summaryrefslogtreecommitdiff
path: root/test/web
diff options
context:
space:
mode:
Diffstat (limited to 'test/web')
-rw-r--r--test/web/activity_pub/activity_pub_controller_test.exs1550
-rw-r--r--test/web/activity_pub/activity_pub_test.exs2136
-rw-r--r--test/web/activity_pub/mrf/activity_expiration_policy_test.exs84
-rw-r--r--test/web/activity_pub/mrf/anti_followbot_policy_test.exs72
-rw-r--r--test/web/activity_pub/mrf/anti_link_spam_policy_test.exs166
-rw-r--r--test/web/activity_pub/mrf/ensure_re_prepended_test.exs92
-rw-r--r--test/web/activity_pub/mrf/hellthread_policy_test.exs92
-rw-r--r--test/web/activity_pub/mrf/keyword_policy_test.exs225
-rw-r--r--test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs51
-rw-r--r--test/web/activity_pub/mrf/mention_policy_test.exs96
-rw-r--r--test/web/activity_pub/mrf/mrf_test.exs84
-rw-r--r--test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs37
-rw-r--r--test/web/activity_pub/mrf/normalize_markup_test.exs42
-rw-r--r--test/web/activity_pub/mrf/object_age_policy_test.exs148
-rw-r--r--test/web/activity_pub/mrf/reject_non_public_test.exs100
-rw-r--r--test/web/activity_pub/mrf/simple_policy_test.exs539
-rw-r--r--test/web/activity_pub/mrf/steal_emoji_policy_test.exs68
-rw-r--r--test/web/activity_pub/mrf/subchain_policy_test.exs33
-rw-r--r--test/web/activity_pub/mrf/tag_policy_test.exs123
-rw-r--r--test/web/activity_pub/mrf/user_allowlist_policy_test.exs31
-rw-r--r--test/web/activity_pub/mrf/vocabulary_policy_test.exs106
-rw-r--r--test/web/activity_pub/object_validators/accept_validation_test.exs56
-rw-r--r--test/web/activity_pub/object_validators/announce_validation_test.exs106
-rw-r--r--test/web/activity_pub/object_validators/attachment_validator_test.exs74
-rw-r--r--test/web/activity_pub/object_validators/block_validation_test.exs39
-rw-r--r--test/web/activity_pub/object_validators/chat_validation_test.exs211
-rw-r--r--test/web/activity_pub/object_validators/delete_validation_test.exs106
-rw-r--r--test/web/activity_pub/object_validators/emoji_react_validation_test.exs53
-rw-r--r--test/web/activity_pub/object_validators/follow_validation_test.exs26
-rw-r--r--test/web/activity_pub/object_validators/like_validation_test.exs113
-rw-r--r--test/web/activity_pub/object_validators/note_validator_test.exs35
-rw-r--r--test/web/activity_pub/object_validators/reject_validation_test.exs56
-rw-r--r--test/web/activity_pub/object_validators/types/date_time_test.exs32
-rw-r--r--test/web/activity_pub/object_validators/types/object_id_test.exs41
-rw-r--r--test/web/activity_pub/object_validators/types/recipients_test.exs27
-rw-r--r--test/web/activity_pub/object_validators/types/safe_text_test.exs30
-rw-r--r--test/web/activity_pub/object_validators/undo_validation_test.exs53
-rw-r--r--test/web/activity_pub/object_validators/update_validation_test.exs44
-rw-r--r--test/web/activity_pub/pipeline_test.exs179
-rw-r--r--test/web/activity_pub/publisher_test.exs365
-rw-r--r--test/web/activity_pub/relay_test.exs128
-rw-r--r--test/web/activity_pub/side_effects_test.exs639
-rw-r--r--test/web/activity_pub/transmogrifier/accept_handling_test.exs91
-rw-r--r--test/web/activity_pub/transmogrifier/announce_handling_test.exs172
-rw-r--r--test/web/activity_pub/transmogrifier/answer_handling_test.exs78
-rw-r--r--test/web/activity_pub/transmogrifier/audio_handling_test.exs83
-rw-r--r--test/web/activity_pub/transmogrifier/block_handling_test.exs63
-rw-r--r--test/web/activity_pub/transmogrifier/chat_message_test.exs171
-rw-r--r--test/web/activity_pub/transmogrifier/delete_handling_test.exs114
-rw-r--r--test/web/activity_pub/transmogrifier/emoji_react_handling_test.exs61
-rw-r--r--test/web/activity_pub/transmogrifier/event_handling_test.exs40
-rw-r--r--test/web/activity_pub/transmogrifier/follow_handling_test.exs208
-rw-r--r--test/web/activity_pub/transmogrifier/like_handling_test.exs78
-rw-r--r--test/web/activity_pub/transmogrifier/question_handling_test.exs125
-rw-r--r--test/web/activity_pub/transmogrifier/reject_handling_test.exs67
-rw-r--r--test/web/activity_pub/transmogrifier/undo_handling_test.exs185
-rw-r--r--test/web/activity_pub/transmogrifier/user_update_handling_test.exs159
-rw-r--r--test/web/activity_pub/transmogrifier_test.exs1379
-rw-r--r--test/web/activity_pub/utils_test.exs548
-rw-r--r--test/web/activity_pub/views/object_view_test.exs84
-rw-r--r--test/web/activity_pub/views/user_view_test.exs180
-rw-r--r--test/web/activity_pub/visibilty_test.exs230
-rw-r--r--test/web/admin_api/controllers/admin_api_controller_test.exs1979
-rw-r--r--test/web/admin_api/controllers/config_controller_test.exs1465
-rw-r--r--test/web/admin_api/controllers/invite_controller_test.exs281
-rw-r--r--test/web/admin_api/controllers/media_proxy_cache_controller_test.exs167
-rw-r--r--test/web/admin_api/controllers/oauth_app_controller_test.exs220
-rw-r--r--test/web/admin_api/controllers/relay_controller_test.exs99
-rw-r--r--test/web/admin_api/controllers/report_controller_test.exs372
-rw-r--r--test/web/admin_api/controllers/status_controller_test.exs202
-rw-r--r--test/web/admin_api/search_test.exs181
-rw-r--r--test/web/admin_api/views/report_view_test.exs146
-rw-r--r--test/web/api_spec/schema_examples_test.exs43
-rw-r--r--test/web/auth/auth_test_controller_test.exs242
-rw-r--r--test/web/auth/authenticator_test.exs42
-rw-r--r--test/web/auth/basic_auth_test.exs46
-rw-r--r--test/web/auth/pleroma_authenticator_test.exs48
-rw-r--r--test/web/auth/totp_authenticator_test.exs51
-rw-r--r--test/web/chat_channel_test.exs37
-rw-r--r--test/web/common_api/common_api_test.exs1140
-rw-r--r--test/web/common_api/common_api_utils_test.exs593
-rw-r--r--test/web/fallback_test.exs80
-rw-r--r--test/web/federator_test.exs173
-rw-r--r--test/web/feed/tag_controller_test.exs197
-rw-r--r--test/web/feed/user_controller_test.exs265
-rw-r--r--test/web/instances/instance_test.exs135
-rw-r--r--test/web/instances/instances_test.exs124
-rw-r--r--test/web/masto_fe_controller_test.exs85
-rw-r--r--test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs529
-rw-r--r--test/web/mastodon_api/controllers/account_controller_test.exs1533
-rw-r--r--test/web/mastodon_api/controllers/app_controller_test.exs60
-rw-r--r--test/web/mastodon_api/controllers/auth_controller_test.exs162
-rw-r--r--test/web/mastodon_api/controllers/conversation_controller_test.exs209
-rw-r--r--test/web/mastodon_api/controllers/custom_emoji_controller_test.exs23
-rw-r--r--test/web/mastodon_api/controllers/domain_block_controller_test.exs79
-rw-r--r--test/web/mastodon_api/controllers/filter_controller_test.exs152
-rw-r--r--test/web/mastodon_api/controllers/follow_request_controller_test.exs74
-rw-r--r--test/web/mastodon_api/controllers/instance_controller_test.exs87
-rw-r--r--test/web/mastodon_api/controllers/list_controller_test.exs158
-rw-r--r--test/web/mastodon_api/controllers/marker_controller_test.exs131
-rw-r--r--test/web/mastodon_api/controllers/media_controller_test.exs146
-rw-r--r--test/web/mastodon_api/controllers/notification_controller_test.exs626
-rw-r--r--test/web/mastodon_api/controllers/poll_controller_test.exs171
-rw-r--r--test/web/mastodon_api/controllers/report_controller_test.exs95
-rw-r--r--test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs139
-rw-r--r--test/web/mastodon_api/controllers/search_controller_test.exs413
-rw-r--r--test/web/mastodon_api/controllers/status_controller_test.exs1704
-rw-r--r--test/web/mastodon_api/controllers/subscription_controller_test.exs199
-rw-r--r--test/web/mastodon_api/controllers/suggestion_controller_test.exs18
-rw-r--r--test/web/mastodon_api/controllers/timeline_controller_test.exs552
-rw-r--r--test/web/mastodon_api/mastodon_api_controller_test.exs34
-rw-r--r--test/web/mastodon_api/mastodon_api_test.exs103
-rw-r--r--test/web/mastodon_api/views/account_view_test.exs572
-rw-r--r--test/web/mastodon_api/views/conversation_view_test.exs44
-rw-r--r--test/web/mastodon_api/views/list_view_test.exs32
-rw-r--r--test/web/mastodon_api/views/marker_view_test.exs29
-rw-r--r--test/web/mastodon_api/views/notification_view_test.exs231
-rw-r--r--test/web/mastodon_api/views/poll_view_test.exs167
-rw-r--r--test/web/mastodon_api/views/scheduled_activity_view_test.exs68
-rw-r--r--test/web/mastodon_api/views/status_view_test.exs664
-rw-r--r--test/web/mastodon_api/views/subscription_view_test.exs23
-rw-r--r--test/web/media_proxy/invalidation_test.exs64
-rw-r--r--test/web/media_proxy/invalidations/http_test.exs39
-rw-r--r--test/web/media_proxy/invalidations/script_test.exs26
-rw-r--r--test/web/media_proxy/media_proxy_controller_test.exs121
-rw-r--r--test/web/media_proxy/media_proxy_test.exs175
-rw-r--r--test/web/metadata/feed_test.exs18
-rw-r--r--test/web/metadata/metadata_test.exs34
-rw-r--r--test/web/metadata/opengraph_test.exs96
-rw-r--r--test/web/metadata/player_view_test.exs33
-rw-r--r--test/web/metadata/rel_me_test.exs21
-rw-r--r--test/web/metadata/restrict_indexing_test.exs21
-rw-r--r--test/web/metadata/twitter_card_test.exs150
-rw-r--r--test/web/metadata/utils_test.exs32
-rw-r--r--test/web/mongooseim/mongoose_im_controller_test.exs81
-rw-r--r--test/web/node_info_test.exs188
-rw-r--r--test/web/oauth/app_test.exs44
-rw-r--r--test/web/oauth/authorization_test.exs77
-rw-r--r--test/web/oauth/ldap_authorization_test.exs135
-rw-r--r--test/web/oauth/mfa_controller_test.exs306
-rw-r--r--test/web/oauth/oauth_controller_test.exs1232
-rw-r--r--test/web/oauth/token/utils_test.exs53
-rw-r--r--test/web/oauth/token_test.exs85
-rw-r--r--test/web/ostatus/ostatus_controller_test.exs338
-rw-r--r--test/web/pleroma_api/controllers/account_controller_test.exs284
-rw-r--r--test/web/pleroma_api/controllers/chat_controller_test.exs390
-rw-r--r--test/web/pleroma_api/controllers/conversation_controller_test.exs136
-rw-r--r--test/web/pleroma_api/controllers/emoji_pack_controller_test.exs861
-rw-r--r--test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs149
-rw-r--r--test/web/pleroma_api/controllers/mascot_controller_test.exs73
-rw-r--r--test/web/pleroma_api/controllers/notification_controller_test.exs68
-rw-r--r--test/web/pleroma_api/controllers/scrobble_controller_test.exs60
-rw-r--r--test/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs260
-rw-r--r--test/web/pleroma_api/views/chat/message_reference_view_test.exs72
-rw-r--r--test/web/pleroma_api/views/chat_view_test.exs49
-rw-r--r--test/web/pleroma_api/views/scrobble_view_test.exs20
-rw-r--r--test/web/plugs/federating_plug_test.exs31
-rw-r--r--test/web/plugs/plug_test.exs91
-rw-r--r--test/web/preload/instance_test.exs48
-rw-r--r--test/web/preload/timeline_test.exs56
-rw-r--r--test/web/preload/user_test.exs33
-rw-r--r--test/web/push/impl_test.exs344
-rw-r--r--test/web/rel_me_test.exs48
-rw-r--r--test/web/rich_media/aws_signed_url_test.exs82
-rw-r--r--test/web/rich_media/helpers_test.exs121
-rw-r--r--test/web/rich_media/parser_test.exs178
-rw-r--r--test/web/rich_media/parsers/twitter_card_test.exs127
-rw-r--r--test/web/static_fe/static_fe_controller_test.exs192
-rw-r--r--test/web/streamer/streamer_test.exs671
-rw-r--r--test/web/twitter_api/password_controller_test.exs81
-rw-r--r--test/web/twitter_api/remote_follow_controller_test.exs350
-rw-r--r--test/web/twitter_api/twitter_api_controller_test.exs138
-rw-r--r--test/web/twitter_api/twitter_api_test.exs432
-rw-r--r--test/web/twitter_api/util_controller_test.exs601
-rw-r--r--test/web/uploader_controller_test.exs43
-rw-r--r--test/web/views/error_view_test.exs36
-rw-r--r--test/web/web_finger/web_finger_controller_test.exs94
-rw-r--r--test/web/web_finger/web_finger_test.exs116
178 files changed, 0 insertions, 39748 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs
deleted file mode 100644
index 0517571f2..000000000
--- a/test/web/activity_pub/activity_pub_controller_test.exs
+++ /dev/null
@@ -1,1550 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
- use Pleroma.Web.ConnCase
- use Oban.Testing, repo: Pleroma.Repo
-
- alias Pleroma.Activity
- alias Pleroma.Config
- alias Pleroma.Delivery
- alias Pleroma.Instances
- alias Pleroma.Object
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- 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.Web.Endpoint
- alias Pleroma.Workers.ReceiverWorker
-
- import Pleroma.Factory
-
- require Pleroma.Constants
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup do: clear_config([:instance, :federating], true)
-
- describe "/relay" do
- setup do: clear_config([:instance, :allow_relay])
-
- test "with the relay active, it returns the relay user", %{conn: conn} do
- res =
- conn
- |> get(activity_pub_path(conn, :relay))
- |> json_response(200)
-
- assert res["id"] =~ "/relay"
- end
-
- test "with the relay disabled, it returns 404", %{conn: conn} do
- Config.put([:instance, :allow_relay], false)
-
- conn
- |> get(activity_pub_path(conn, :relay))
- |> json_response(404)
- end
-
- test "on non-federating instance, it returns 404", %{conn: conn} do
- Config.put([:instance, :federating], false)
- user = insert(:user)
-
- conn
- |> assign(:user, user)
- |> get(activity_pub_path(conn, :relay))
- |> json_response(404)
- end
- end
-
- describe "/internal/fetch" do
- test "it returns the internal fetch user", %{conn: conn} do
- res =
- conn
- |> get(activity_pub_path(conn, :internal_fetch))
- |> json_response(200)
-
- assert res["id"] =~ "/fetch"
- end
-
- test "on non-federating instance, it returns 404", %{conn: conn} do
- Config.put([:instance, :federating], false)
- user = insert(:user)
-
- conn
- |> assign(:user, user)
- |> get(activity_pub_path(conn, :internal_fetch))
- |> json_response(404)
- end
- end
-
- describe "/users/:nickname" do
- test "it returns a json representation of the user with accept application/json", %{
- conn: conn
- } do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/users/#{user.nickname}")
-
- user = User.get_cached_by_id(user.id)
-
- assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
- end
-
- test "it returns a json representation of the user with accept application/activity+json", %{
- conn: conn
- } do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}")
-
- user = User.get_cached_by_id(user.id)
-
- assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
- end
-
- test "it returns a json representation of the user with accept application/ld+json", %{
- conn: conn
- } do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header(
- "accept",
- "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
- )
- |> get("/users/#{user.nickname}")
-
- user = User.get_cached_by_id(user.id)
-
- assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
- end
-
- test "it returns 404 for remote users", %{
- conn: conn
- } do
- user = insert(:user, local: false, nickname: "remoteuser@example.com")
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/users/#{user.nickname}.json")
-
- assert json_response(conn, 404)
- end
-
- test "it returns error when user is not found", %{conn: conn} do
- response =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/users/jimm")
- |> json_response(404)
-
- assert response == "Not found"
- end
-
- test "it requires authentication if instance is NOT federating", %{
- conn: conn
- } do
- user = insert(:user)
-
- conn =
- put_req_header(
- conn,
- "accept",
- "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
- )
-
- ensure_federating_or_authenticated(conn, "/users/#{user.nickname}.json", user)
- end
- end
-
- describe "mastodon compatibility routes" do
- test "it returns a json representation of the object with accept application/json", %{
- conn: conn
- } do
- {:ok, object} =
- %{
- "type" => "Note",
- "content" => "hey",
- "id" => Endpoint.url() <> "/users/raymoo/statuses/999999999",
- "actor" => Endpoint.url() <> "/users/raymoo",
- "to" => [Pleroma.Constants.as_public()]
- }
- |> Object.create()
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/users/raymoo/statuses/999999999")
-
- assert json_response(conn, 200) == ObjectView.render("object.json", %{object: object})
- end
-
- test "it returns a json representation of the activity with accept application/json", %{
- conn: conn
- } do
- {:ok, object} =
- %{
- "type" => "Note",
- "content" => "hey",
- "id" => Endpoint.url() <> "/users/raymoo/statuses/999999999",
- "actor" => Endpoint.url() <> "/users/raymoo",
- "to" => [Pleroma.Constants.as_public()]
- }
- |> Object.create()
-
- {:ok, activity, _} =
- %{
- "id" => object.data["id"] <> "/activity",
- "type" => "Create",
- "object" => object.data["id"],
- "actor" => object.data["actor"],
- "to" => object.data["to"]
- }
- |> ActivityPub.persist(local: true)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/users/raymoo/statuses/999999999/activity")
-
- assert json_response(conn, 200) == ObjectView.render("object.json", %{object: activity})
- end
- end
-
- describe "/objects/:uuid" do
- test "it returns a json representation of the object with accept application/json", %{
- conn: conn
- } do
- note = insert(:note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
- end
-
- test "it returns a json representation of the object with accept application/activity+json",
- %{conn: conn} do
- note = insert(:note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
- end
-
- test "it returns a json representation of the object with accept application/ld+json", %{
- conn: conn
- } do
- note = insert(:note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header(
- "accept",
- "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
- )
- |> get("/objects/#{uuid}")
-
- assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
- end
-
- test "it returns 404 for non-public messages", %{conn: conn} do
- note = insert(:direct_note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn, 404)
- end
-
- test "it returns 404 for tombstone objects", %{conn: conn} do
- tombstone = insert(:tombstone)
- uuid = String.split(tombstone.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn, 404)
- end
-
- test "it caches a response", %{conn: conn} do
- note = insert(:note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn1 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn1, :ok)
- assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
-
- conn2 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn1, :ok) == json_response(conn2, :ok)
- assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
- end
-
- test "cached purged after object deletion", %{conn: conn} do
- note = insert(:note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn1 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert json_response(conn1, :ok)
- assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
-
- Object.delete(note)
-
- conn2 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/objects/#{uuid}")
-
- assert "Not found" == json_response(conn2, :not_found)
- end
-
- test "it requires authentication if instance is NOT federating", %{
- conn: conn
- } do
- user = insert(:user)
- note = insert(:note)
- uuid = String.split(note.data["id"], "/") |> List.last()
-
- conn = put_req_header(conn, "accept", "application/activity+json")
-
- ensure_federating_or_authenticated(conn, "/objects/#{uuid}", user)
- end
- end
-
- describe "/activities/:uuid" do
- test "it returns a json representation of the activity", %{conn: conn} do
- activity = insert(:note_activity)
- uuid = String.split(activity.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/activities/#{uuid}")
-
- assert json_response(conn, 200) == ObjectView.render("object.json", %{object: activity})
- end
-
- test "it returns 404 for non-public activities", %{conn: conn} do
- activity = insert(:direct_note_activity)
- uuid = String.split(activity.data["id"], "/") |> List.last()
-
- conn =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/activities/#{uuid}")
-
- assert json_response(conn, 404)
- end
-
- test "it caches a response", %{conn: conn} do
- activity = insert(:note_activity)
- uuid = String.split(activity.data["id"], "/") |> List.last()
-
- conn1 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/activities/#{uuid}")
-
- assert json_response(conn1, :ok)
- assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
-
- conn2 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/activities/#{uuid}")
-
- assert json_response(conn1, :ok) == json_response(conn2, :ok)
- assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
- end
-
- test "cached purged after activity deletion", %{conn: conn} do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "cofe"})
-
- uuid = String.split(activity.data["id"], "/") |> List.last()
-
- conn1 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/activities/#{uuid}")
-
- assert json_response(conn1, :ok)
- assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
-
- Activity.delete_all_by_object_ap_id(activity.object.data["id"])
-
- conn2 =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/activities/#{uuid}")
-
- assert "Not found" == json_response(conn2, :not_found)
- end
-
- test "it requires authentication if instance is NOT federating", %{
- conn: conn
- } do
- user = insert(:user)
- activity = insert(:note_activity)
- uuid = String.split(activity.data["id"], "/") |> List.last()
-
- conn = put_req_header(conn, "accept", "application/activity+json")
-
- ensure_federating_or_authenticated(conn, "/activities/#{uuid}", user)
- end
- end
-
- describe "/inbox" do
- test "it inserts an incoming activity into the database", %{conn: conn} do
- data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/inbox", data)
-
- assert "ok" == json_response(conn, 200)
-
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- assert Activity.get_by_ap_id(data["id"])
- end
-
- @tag capture_log: true
- test "it inserts an incoming activity into the database" <>
- "even if we can't fetch the user but have it in our db",
- %{conn: conn} do
- user =
- insert(:user,
- ap_id: "https://mastodon.example.org/users/raymoo",
- ap_enabled: true,
- local: false,
- last_refreshed_at: nil
- )
-
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", user.ap_id)
- |> put_in(["object", "attridbutedTo"], user.ap_id)
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/inbox", data)
-
- assert "ok" == json_response(conn, 200)
-
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- assert Activity.get_by_ap_id(data["id"])
- end
-
- test "it clears `unreachable` federation status of the sender", %{conn: conn} do
- data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
-
- sender_url = data["actor"]
- Instances.set_consistently_unreachable(sender_url)
- refute Instances.reachable?(sender_url)
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- assert Instances.reachable?(sender_url)
- end
-
- test "accept follow activity", %{conn: conn} do
- Pleroma.Config.put([:instance, :federating], true)
- relay = Relay.get_actor()
-
- assert {:ok, %Activity{} = activity} = Relay.follow("https://relay.mastodon.host/actor")
-
- followed_relay = Pleroma.User.get_by_ap_id("https://relay.mastodon.host/actor")
- relay = refresh_record(relay)
-
- accept =
- File.read!("test/fixtures/relay/accept-follow.json")
- |> String.replace("{{ap_id}}", relay.ap_id)
- |> String.replace("{{activity_id}}", activity.data["id"])
-
- assert "ok" ==
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/inbox", accept)
- |> json_response(200)
-
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
-
- assert Pleroma.FollowingRelationship.following?(
- relay,
- followed_relay
- )
-
- Mix.shell(Mix.Shell.Process)
-
- on_exit(fn ->
- Mix.shell(Mix.Shell.IO)
- end)
-
- :ok = Mix.Tasks.Pleroma.Relay.run(["list"])
- assert_receive {:mix_shell, :info, ["https://relay.mastodon.host/actor"]}
- end
-
- @tag capture_log: true
- test "without valid signature, " <>
- "it only accepts Create activities and requires enabled federation",
- %{conn: conn} do
- data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
- non_create_data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!()
-
- conn = put_req_header(conn, "content-type", "application/activity+json")
-
- Config.put([:instance, :federating], false)
-
- conn
- |> post("/inbox", data)
- |> json_response(403)
-
- conn
- |> post("/inbox", non_create_data)
- |> json_response(403)
-
- Config.put([:instance, :federating], true)
-
- ret_conn = post(conn, "/inbox", data)
- assert "ok" == json_response(ret_conn, 200)
-
- conn
- |> post("/inbox", non_create_data)
- |> json_response(400)
- end
- end
-
- describe "/users/:nickname/inbox" do
- setup do
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
-
- [data: data]
- end
-
- test "it inserts an incoming activity into the database", %{conn: conn, data: data} do
- user = insert(:user)
- data = Map.put(data, "bcc", [user.ap_id])
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- assert Activity.get_by_ap_id(data["id"])
- end
-
- test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
- user = insert(:user)
-
- data =
- Map.put(data, "to", user.ap_id)
- |> Map.delete("cc")
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- assert Activity.get_by_ap_id(data["id"])
- end
-
- test "it accepts messages with cc as string instead of array", %{conn: conn, data: data} do
- user = insert(:user)
-
- data =
- Map.put(data, "cc", user.ap_id)
- |> Map.delete("to")
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- %Activity{} = activity = Activity.get_by_ap_id(data["id"])
- assert user.ap_id in activity.recipients
- end
-
- test "it accepts messages with bcc as string instead of array", %{conn: conn, data: data} do
- user = insert(:user)
-
- data =
- Map.put(data, "bcc", user.ap_id)
- |> Map.delete("to")
- |> Map.delete("cc")
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- assert Activity.get_by_ap_id(data["id"])
- end
-
- test "it accepts announces with to as string instead of array", %{conn: conn} do
- user = insert(:user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "hey"})
- announcer = insert(:user, local: false)
-
- data = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "actor" => announcer.ap_id,
- "id" => "#{announcer.ap_id}/statuses/19512778738411822/activity",
- "object" => post.data["object"],
- "to" => "https://www.w3.org/ns/activitystreams#Public",
- "cc" => [user.ap_id],
- "type" => "Announce"
- }
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- %Activity{} = activity = Activity.get_by_ap_id(data["id"])
- assert "https://www.w3.org/ns/activitystreams#Public" in activity.recipients
- end
-
- test "it accepts messages from actors that are followed by the user", %{
- conn: conn,
- data: data
- } do
- recipient = insert(:user)
- actor = insert(:user, %{ap_id: "http://mastodon.example.org/users/actor"})
-
- {:ok, recipient} = User.follow(recipient, actor)
-
- object =
- data["object"]
- |> Map.put("attributedTo", actor.ap_id)
-
- data =
- data
- |> Map.put("actor", actor.ap_id)
- |> Map.put("object", object)
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{recipient.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
- assert Activity.get_by_ap_id(data["id"])
- end
-
- test "it rejects reads from other users", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- conn =
- conn
- |> assign(:user, other_user)
- |> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/inbox")
-
- assert json_response(conn, 403)
- end
-
- test "it returns a note activity in a collection", %{conn: conn} do
- note_activity = insert(:direct_note_activity)
- note_object = Object.normalize(note_activity)
- user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/inbox?page=true")
-
- assert response(conn, 200) =~ note_object.data["content"]
- end
-
- test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do
- user = insert(:user)
- data = Map.put(data, "bcc", [user.ap_id])
-
- sender_host = URI.parse(data["actor"]).host
- Instances.set_consistently_unreachable(sender_host)
- refute Instances.reachable?(sender_host)
-
- conn =
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/inbox", data)
-
- assert "ok" == json_response(conn, 200)
- assert Instances.reachable?(sender_host)
- end
-
- test "it removes all follower collections but actor's", %{conn: conn} do
- [actor, recipient] = insert_pair(:user)
-
- data =
- File.read!("test/fixtures/activitypub-client-post-activity.json")
- |> Poison.decode!()
-
- object = Map.put(data["object"], "attributedTo", actor.ap_id)
-
- data =
- data
- |> Map.put("id", Utils.generate_object_id())
- |> Map.put("actor", actor.ap_id)
- |> Map.put("object", object)
- |> Map.put("cc", [
- recipient.follower_address,
- actor.follower_address
- ])
- |> Map.put("to", [
- recipient.ap_id,
- recipient.follower_address,
- "https://www.w3.org/ns/activitystreams#Public"
- ])
-
- conn
- |> assign(:valid_signature, true)
- |> put_req_header("content-type", "application/activity+json")
- |> 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
- assert actor.follower_address in activity.recipients
- assert actor.follower_address in activity.data["cc"]
-
- refute recipient.follower_address in activity.recipients
- refute recipient.follower_address in activity.data["cc"]
- refute recipient.follower_address in activity.data["to"]
- end
-
- test "it requires authentication", %{conn: conn} do
- user = insert(:user)
- conn = put_req_header(conn, "accept", "application/activity+json")
-
- ret_conn = get(conn, "/users/#{user.nickname}/inbox")
- assert json_response(ret_conn, 403)
-
- ret_conn =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/inbox")
-
- assert json_response(ret_conn, 200)
- end
- end
-
- describe "GET /users/:nickname/outbox" do
- test "it paginates correctly", %{conn: conn} do
- user = insert(:user)
- conn = assign(conn, :user, user)
- outbox_endpoint = user.ap_id <> "/outbox"
-
- _posts =
- for i <- 0..25 do
- {:ok, activity} = CommonAPI.post(user, %{status: "post #{i}"})
- activity
- end
-
- result =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get(outbox_endpoint <> "?page=true")
- |> json_response(200)
-
- result_ids = Enum.map(result["orderedItems"], fn x -> x["id"] end)
- assert length(result["orderedItems"]) == 20
- assert length(result_ids) == 20
- assert result["next"]
- assert String.starts_with?(result["next"], outbox_endpoint)
-
- result_next =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get(result["next"])
- |> json_response(200)
-
- result_next_ids = Enum.map(result_next["orderedItems"], fn x -> x["id"] end)
- assert length(result_next["orderedItems"]) == 6
- assert length(result_next_ids) == 6
- refute Enum.find(result_next_ids, fn x -> x in result_ids end)
- refute Enum.find(result_ids, fn x -> x in result_next_ids end)
- assert String.starts_with?(result["id"], outbox_endpoint)
-
- result_next_again =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get(result_next["id"])
- |> json_response(200)
-
- assert result_next == result_next_again
- end
-
- test "it returns 200 even if there're no activities", %{conn: conn} do
- user = insert(:user)
- outbox_endpoint = user.ap_id <> "/outbox"
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("accept", "application/activity+json")
- |> get(outbox_endpoint)
-
- result = json_response(conn, 200)
- assert outbox_endpoint == result["id"]
- end
-
- test "it returns a note activity in a collection", %{conn: conn} do
- note_activity = insert(:note_activity)
- note_object = Object.normalize(note_activity)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/outbox?page=true")
-
- assert response(conn, 200) =~ note_object.data["content"]
- end
-
- test "it returns an announce activity in a collection", %{conn: conn} do
- announce_activity = insert(:announce_activity)
- user = User.get_cached_by_ap_id(announce_activity.data["actor"])
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/outbox?page=true")
-
- assert response(conn, 200) =~ announce_activity.data["object"]
- end
-
- test "it requires authentication if instance is NOT federating", %{
- conn: conn
- } do
- user = insert(:user)
- conn = put_req_header(conn, "accept", "application/activity+json")
-
- ensure_federating_or_authenticated(conn, "/users/#{user.nickname}/outbox", user)
- end
- end
-
- describe "POST /users/:nickname/outbox (C2S)" do
- setup do: clear_config([:instance, :limit])
-
- setup do
- [
- activity: %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Create",
- "object" => %{"type" => "Note", "content" => "AP C2S test"},
- "to" => "https://www.w3.org/ns/activitystreams#Public",
- "cc" => []
- }
- ]
- end
-
- test "it rejects posts from other users / unauthenticated users", %{
- conn: conn,
- activity: activity
- } do
- user = insert(:user)
- other_user = insert(:user)
- conn = put_req_header(conn, "content-type", "application/activity+json")
-
- conn
- |> post("/users/#{user.nickname}/outbox", activity)
- |> json_response(403)
-
- conn
- |> assign(:user, other_user)
- |> post("/users/#{user.nickname}/outbox", activity)
- |> json_response(403)
- end
-
- test "it inserts an incoming create activity into the database", %{
- conn: conn,
- activity: activity
- } do
- user = insert(:user)
-
- result =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", activity)
- |> json_response(201)
-
- assert Activity.get_by_ap_id(result["id"])
- assert result["object"]
- assert %Object{data: object} = Object.normalize(result["object"])
- assert object["content"] == activity["object"]["content"]
- end
-
- test "it rejects anything beyond 'Note' creations", %{conn: conn, activity: activity} do
- user = insert(:user)
-
- activity =
- activity
- |> put_in(["object", "type"], "Benis")
-
- _result =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", activity)
- |> json_response(400)
- end
-
- test "it inserts an incoming sensitive activity into the database", %{
- conn: conn,
- activity: activity
- } do
- user = insert(:user)
- conn = assign(conn, :user, user)
- object = Map.put(activity["object"], "sensitive", true)
- activity = Map.put(activity, "object", object)
-
- response =
- conn
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", activity)
- |> json_response(201)
-
- assert Activity.get_by_ap_id(response["id"])
- assert response["object"]
- assert %Object{data: response_object} = Object.normalize(response["object"])
- assert response_object["sensitive"] == true
- assert response_object["content"] == activity["object"]["content"]
-
- representation =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get(response["id"])
- |> json_response(200)
-
- assert representation["object"]["sensitive"] == true
- end
-
- test "it rejects an incoming activity with bogus type", %{conn: conn, activity: activity} do
- user = insert(:user)
- activity = Map.put(activity, "type", "BadType")
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", activity)
-
- assert json_response(conn, 400)
- end
-
- test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
- note_activity = insert(:note_activity)
- note_object = Object.normalize(note_activity)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- data = %{
- type: "Delete",
- object: %{
- id: note_object.data["id"]
- }
- }
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", data)
-
- result = json_response(conn, 201)
- assert Activity.get_by_ap_id(result["id"])
-
- assert object = Object.get_by_ap_id(note_object.data["id"])
- assert object.data["type"] == "Tombstone"
- end
-
- test "it rejects delete activity of object from other actor", %{conn: conn} do
- note_activity = insert(:note_activity)
- note_object = Object.normalize(note_activity)
- user = insert(:user)
-
- data = %{
- type: "Delete",
- object: %{
- id: note_object.data["id"]
- }
- }
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", data)
-
- assert json_response(conn, 400)
- end
-
- test "it increases like count when receiving a like action", %{conn: conn} do
- note_activity = insert(:note_activity)
- note_object = Object.normalize(note_activity)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- data = %{
- type: "Like",
- object: %{
- id: note_object.data["id"]
- }
- }
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", data)
-
- result = json_response(conn, 201)
- assert Activity.get_by_ap_id(result["id"])
-
- assert object = Object.get_by_ap_id(note_object.data["id"])
- assert object.data["like_count"] == 1
- end
-
- test "it doesn't spreads faulty attributedTo or actor fields", %{
- conn: conn,
- activity: activity
- } do
- reimu = insert(:user, nickname: "reimu")
- cirno = insert(:user, nickname: "cirno")
-
- assert reimu.ap_id
- assert cirno.ap_id
-
- activity =
- activity
- |> put_in(["object", "actor"], reimu.ap_id)
- |> put_in(["object", "attributedTo"], reimu.ap_id)
- |> put_in(["actor"], reimu.ap_id)
- |> put_in(["attributedTo"], reimu.ap_id)
-
- _reimu_outbox =
- conn
- |> assign(:user, cirno)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{reimu.nickname}/outbox", activity)
- |> json_response(403)
-
- cirno_outbox =
- conn
- |> assign(:user, cirno)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{cirno.nickname}/outbox", activity)
- |> json_response(201)
-
- assert cirno_outbox["attributedTo"] == nil
- assert cirno_outbox["actor"] == cirno.ap_id
-
- assert cirno_object = Object.normalize(cirno_outbox["object"])
- assert cirno_object.data["actor"] == cirno.ap_id
- assert cirno_object.data["attributedTo"] == cirno.ap_id
- end
-
- test "Character limitation", %{conn: conn, activity: activity} do
- Pleroma.Config.put([:instance, :limit], 5)
- user = insert(:user)
-
- result =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/activity+json")
- |> post("/users/#{user.nickname}/outbox", activity)
- |> json_response(400)
-
- assert result == "Note is over the character limit"
- end
- end
-
- describe "/relay/followers" do
- test "it returns relay followers", %{conn: conn} do
- relay_actor = Relay.get_actor()
- user = insert(:user)
- User.follow(user, relay_actor)
-
- result =
- conn
- |> get("/relay/followers")
- |> json_response(200)
-
- assert result["first"]["orderedItems"] == [user.ap_id]
- end
-
- test "on non-federating instance, it returns 404", %{conn: conn} do
- Config.put([:instance, :federating], false)
- user = insert(:user)
-
- conn
- |> assign(:user, user)
- |> get("/relay/followers")
- |> json_response(404)
- end
- end
-
- describe "/relay/following" do
- test "it returns relay following", %{conn: conn} do
- result =
- conn
- |> get("/relay/following")
- |> json_response(200)
-
- assert result["first"]["orderedItems"] == []
- end
-
- test "on non-federating instance, it returns 404", %{conn: conn} do
- Config.put([:instance, :federating], false)
- user = insert(:user)
-
- conn
- |> assign(:user, user)
- |> get("/relay/following")
- |> json_response(404)
- end
- end
-
- describe "/users/:nickname/followers" do
- test "it returns the followers in a collection", %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user)
- User.follow(user, user_two)
-
- result =
- conn
- |> assign(:user, user_two)
- |> get("/users/#{user_two.nickname}/followers")
- |> json_response(200)
-
- assert result["first"]["orderedItems"] == [user.ap_id]
- end
-
- test "it returns a uri if the user has 'hide_followers' set", %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user, hide_followers: true)
- User.follow(user, user_two)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user_two.nickname}/followers")
- |> json_response(200)
-
- assert is_binary(result["first"])
- end
-
- test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is from another user",
- %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user, hide_followers: true)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{other_user.nickname}/followers?page=1")
-
- assert result.status == 403
- assert result.resp_body == ""
- end
-
- test "it renders the page, if the user has 'hide_followers' set and the request is authenticated with the same user",
- %{conn: conn} do
- user = insert(:user, hide_followers: true)
- other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/followers?page=1")
- |> json_response(200)
-
- assert result["totalItems"] == 1
- assert result["orderedItems"] == [other_user.ap_id]
- end
-
- test "it works for more than 10 users", %{conn: conn} do
- user = insert(:user)
-
- Enum.each(1..15, fn _ ->
- other_user = insert(:user)
- User.follow(other_user, user)
- end)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/followers")
- |> json_response(200)
-
- assert length(result["first"]["orderedItems"]) == 10
- assert result["first"]["totalItems"] == 15
- assert result["totalItems"] == 15
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/followers?page=2")
- |> json_response(200)
-
- assert length(result["orderedItems"]) == 5
- assert result["totalItems"] == 15
- end
-
- test "does not require authentication", %{conn: conn} do
- user = insert(:user)
-
- conn
- |> get("/users/#{user.nickname}/followers")
- |> json_response(200)
- end
- end
-
- describe "/users/:nickname/following" do
- test "it returns the following in a collection", %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user)
- User.follow(user, user_two)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/following")
- |> json_response(200)
-
- assert result["first"]["orderedItems"] == [user_two.ap_id]
- end
-
- test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user, hide_follows: true)
- User.follow(user, user_two)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user_two.nickname}/following")
- |> json_response(200)
-
- assert is_binary(result["first"])
- end
-
- test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is from another user",
- %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user, hide_follows: true)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user_two.nickname}/following?page=1")
-
- assert result.status == 403
- assert result.resp_body == ""
- end
-
- test "it renders the page, if the user has 'hide_follows' set and the request is authenticated with the same user",
- %{conn: conn} do
- user = insert(:user, hide_follows: true)
- other_user = insert(:user)
- {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/following?page=1")
- |> json_response(200)
-
- assert result["totalItems"] == 1
- assert result["orderedItems"] == [other_user.ap_id]
- end
-
- test "it works for more than 10 users", %{conn: conn} do
- user = insert(:user)
-
- Enum.each(1..15, fn _ ->
- user = User.get_cached_by_id(user.id)
- other_user = insert(:user)
- User.follow(user, other_user)
- end)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/following")
- |> json_response(200)
-
- assert length(result["first"]["orderedItems"]) == 10
- assert result["first"]["totalItems"] == 15
- assert result["totalItems"] == 15
-
- result =
- conn
- |> assign(:user, user)
- |> get("/users/#{user.nickname}/following?page=2")
- |> json_response(200)
-
- assert length(result["orderedItems"]) == 5
- assert result["totalItems"] == 15
- end
-
- test "does not require authentication", %{conn: conn} do
- user = insert(:user)
-
- conn
- |> get("/users/#{user.nickname}/following")
- |> json_response(200)
- end
- end
-
- describe "delivery tracking" do
- test "it tracks a signed object fetch", %{conn: conn} do
- user = insert(:user, local: false)
- activity = insert(:note_activity)
- object = Object.normalize(activity)
-
- object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
-
- conn
- |> put_req_header("accept", "application/activity+json")
- |> assign(:user, user)
- |> get(object_path)
- |> json_response(200)
-
- assert Delivery.get(object.id, user.id)
- end
-
- test "it tracks a signed activity fetch", %{conn: conn} do
- user = insert(:user, local: false)
- activity = insert(:note_activity)
- object = Object.normalize(activity)
-
- activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
-
- conn
- |> put_req_header("accept", "application/activity+json")
- |> assign(:user, user)
- |> get(activity_path)
- |> json_response(200)
-
- assert Delivery.get(object.id, user.id)
- end
-
- test "it tracks a signed object fetch when the json is cached", %{conn: conn} do
- user = insert(:user, local: false)
- other_user = insert(:user, local: false)
- activity = insert(:note_activity)
- object = Object.normalize(activity)
-
- object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
-
- conn
- |> put_req_header("accept", "application/activity+json")
- |> assign(:user, user)
- |> get(object_path)
- |> json_response(200)
-
- build_conn()
- |> put_req_header("accept", "application/activity+json")
- |> assign(:user, other_user)
- |> get(object_path)
- |> json_response(200)
-
- assert Delivery.get(object.id, user.id)
- assert Delivery.get(object.id, other_user.id)
- end
-
- test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do
- user = insert(:user, local: false)
- other_user = insert(:user, local: false)
- activity = insert(:note_activity)
- object = Object.normalize(activity)
-
- activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
-
- conn
- |> put_req_header("accept", "application/activity+json")
- |> assign(:user, user)
- |> get(activity_path)
- |> json_response(200)
-
- build_conn()
- |> put_req_header("accept", "application/activity+json")
- |> assign(:user, other_user)
- |> get(activity_path)
- |> json_response(200)
-
- assert Delivery.get(object.id, user.id)
- assert Delivery.get(object.id, other_user.id)
- end
- end
-
- describe "Additional ActivityPub C2S endpoints" do
- test "GET /api/ap/whoami", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/ap/whoami")
-
- user = User.get_cached_by_id(user.id)
-
- assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
-
- conn
- |> get("/api/ap/whoami")
- |> json_response(403)
- end
-
- setup do: clear_config([:media_proxy])
- setup do: clear_config([Pleroma.Upload])
-
- test "POST /api/ap/upload_media", %{conn: conn} do
- user = insert(:user)
-
- desc = "Description of the image"
-
- image = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- object =
- conn
- |> assign(:user, user)
- |> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
- |> json_response(:created)
-
- assert object["name"] == desc
- assert object["type"] == "Document"
- assert object["actor"] == user.ap_id
- assert [%{"href" => object_href, "mediaType" => object_mediatype}] = object["url"]
- assert is_binary(object_href)
- assert object_mediatype == "image/jpeg"
-
- activity_request = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Create",
- "object" => %{
- "type" => "Note",
- "content" => "AP C2S test, attachment",
- "attachment" => [object]
- },
- "to" => "https://www.w3.org/ns/activitystreams#Public",
- "cc" => []
- }
-
- activity_response =
- conn
- |> assign(:user, user)
- |> post("/users/#{user.nickname}/outbox", activity_request)
- |> json_response(:created)
-
- assert activity_response["id"]
- assert activity_response["object"]
- assert activity_response["actor"] == user.ap_id
-
- assert %Object{data: %{"attachment" => [attachment]}} =
- Object.normalize(activity_response["object"])
-
- assert attachment["type"] == "Document"
- assert attachment["name"] == desc
-
- assert [
- %{
- "href" => ^object_href,
- "type" => "Link",
- "mediaType" => ^object_mediatype
- }
- ] = attachment["url"]
-
- # Fails if unauthenticated
- conn
- |> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
- |> json_response(403)
- end
- end
-end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
deleted file mode 100644
index b579bb0bb..000000000
--- a/test/web/activity_pub/activity_pub_test.exs
+++ /dev/null
@@ -1,2136 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
- use Pleroma.DataCase
- use Oban.Testing, repo: Pleroma.Repo
-
- alias Pleroma.Activity
- alias Pleroma.Builders.ActivityBuilder
- alias Pleroma.Config
- alias Pleroma.Notification
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.Utils
- alias Pleroma.Web.AdminAPI.AccountView
- alias Pleroma.Web.CommonAPI
-
- import ExUnit.CaptureLog
- import Mock
- import Pleroma.Factory
- import Tesla.Mock
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup do: clear_config([:instance, :federating])
-
- describe "streaming out participations" do
- test "it streams them out" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
-
- {:ok, conversation} = Pleroma.Conversation.create_or_bump_for(activity)
-
- participations =
- conversation.participations
- |> Repo.preload(:user)
-
- with_mock Pleroma.Web.Streamer,
- stream: fn _, _ -> nil end do
- ActivityPub.stream_out_participations(conversation.participations)
-
- assert called(Pleroma.Web.Streamer.stream("participation", participations))
- end
- end
-
- test "streams them out on activity creation" do
- user_one = insert(:user)
- user_two = insert(:user)
-
- with_mock Pleroma.Web.Streamer,
- stream: fn _, _ -> nil end do
- {:ok, activity} =
- CommonAPI.post(user_one, %{
- status: "@#{user_two.nickname}",
- visibility: "direct"
- })
-
- conversation =
- activity.data["context"]
- |> Pleroma.Conversation.get_for_ap_id()
- |> Repo.preload(participations: :user)
-
- assert called(Pleroma.Web.Streamer.stream("participation", conversation.participations))
- end
- end
- end
-
- describe "fetching restricted by visibility" do
- test "it restricts by the appropriate visibility" do
- user = insert(:user)
-
- {:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
-
- {:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
-
- {:ok, unlisted_activity} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
-
- {:ok, private_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
-
- activities = ActivityPub.fetch_activities([], %{visibility: "direct", actor_id: user.ap_id})
-
- assert activities == [direct_activity]
-
- activities =
- ActivityPub.fetch_activities([], %{visibility: "unlisted", actor_id: user.ap_id})
-
- assert activities == [unlisted_activity]
-
- activities =
- ActivityPub.fetch_activities([], %{visibility: "private", actor_id: user.ap_id})
-
- assert activities == [private_activity]
-
- activities = ActivityPub.fetch_activities([], %{visibility: "public", actor_id: user.ap_id})
-
- assert activities == [public_activity]
-
- activities =
- ActivityPub.fetch_activities([], %{
- visibility: ~w[private public],
- actor_id: user.ap_id
- })
-
- assert activities == [public_activity, private_activity]
- end
- end
-
- describe "fetching excluded by visibility" do
- test "it excludes by the appropriate visibility" do
- user = insert(:user)
-
- {:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
-
- {:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
-
- {:ok, unlisted_activity} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
-
- {:ok, private_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
-
- activities =
- ActivityPub.fetch_activities([], %{
- exclude_visibilities: "direct",
- actor_id: user.ap_id
- })
-
- assert public_activity in activities
- assert unlisted_activity in activities
- assert private_activity in activities
- refute direct_activity in activities
-
- activities =
- ActivityPub.fetch_activities([], %{
- exclude_visibilities: "unlisted",
- actor_id: user.ap_id
- })
-
- assert public_activity in activities
- refute unlisted_activity in activities
- assert private_activity in activities
- assert direct_activity in activities
-
- activities =
- ActivityPub.fetch_activities([], %{
- exclude_visibilities: "private",
- actor_id: user.ap_id
- })
-
- assert public_activity in activities
- assert unlisted_activity in activities
- refute private_activity in activities
- assert direct_activity in activities
-
- activities =
- ActivityPub.fetch_activities([], %{
- exclude_visibilities: "public",
- actor_id: user.ap_id
- })
-
- refute public_activity in activities
- assert unlisted_activity in activities
- assert private_activity in activities
- assert direct_activity in activities
- end
- end
-
- describe "building a user from his ap id" do
- test "it returns a user" do
- user_id = "http://mastodon.example.org/users/admin"
- {:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
- assert user.ap_id == user_id
- assert user.nickname == "admin@mastodon.example.org"
- assert user.ap_enabled
- assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
- end
-
- test "it returns a user that is invisible" do
- user_id = "http://mastodon.example.org/users/relay"
- {:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
- assert User.invisible?(user)
- end
-
- test "it returns a user that accepts chat messages" do
- user_id = "http://mastodon.example.org/users/admin"
- {:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
-
- assert user.accepts_chat_messages
- end
- end
-
- test "it fetches the appropriate tag-restricted posts" do
- user = insert(:user)
-
- {:ok, status_one} = CommonAPI.post(user, %{status: ". #test"})
- {:ok, status_two} = CommonAPI.post(user, %{status: ". #essais"})
- {:ok, status_three} = CommonAPI.post(user, %{status: ". #test #reject"})
-
- fetch_one = ActivityPub.fetch_activities([], %{type: "Create", tag: "test"})
-
- fetch_two = ActivityPub.fetch_activities([], %{type: "Create", tag: ["test", "essais"]})
-
- fetch_three =
- ActivityPub.fetch_activities([], %{
- type: "Create",
- tag: ["test", "essais"],
- tag_reject: ["reject"]
- })
-
- fetch_four =
- ActivityPub.fetch_activities([], %{
- type: "Create",
- tag: ["test"],
- tag_all: ["test", "reject"]
- })
-
- assert fetch_one == [status_one, status_three]
- assert fetch_two == [status_one, status_two, status_three]
- assert fetch_three == [status_one, status_two]
- assert fetch_four == [status_three]
- end
-
- describe "insertion" do
- test "drops activities beyond a certain limit" do
- limit = Config.get([:instance, :remote_limit])
-
- random_text =
- :crypto.strong_rand_bytes(limit + 1)
- |> Base.encode64()
- |> binary_part(0, limit + 1)
-
- data = %{
- "ok" => true,
- "object" => %{
- "content" => random_text
- }
- }
-
- assert {:error, {:remote_limit_error, _}} = ActivityPub.insert(data)
- end
-
- test "doesn't drop activities with content being null" do
- user = insert(:user)
-
- data = %{
- "actor" => user.ap_id,
- "to" => [],
- "object" => %{
- "actor" => user.ap_id,
- "to" => [],
- "type" => "Note",
- "content" => nil
- }
- }
-
- assert {:ok, _} = ActivityPub.insert(data)
- end
-
- test "returns the activity if one with the same id is already in" do
- activity = insert(:note_activity)
- {:ok, new_activity} = ActivityPub.insert(activity.data)
-
- assert activity.id == new_activity.id
- end
-
- test "inserts a given map into the activity database, giving it an id if it has none." do
- user = insert(:user)
-
- data = %{
- "actor" => user.ap_id,
- "to" => [],
- "object" => %{
- "actor" => user.ap_id,
- "to" => [],
- "type" => "Note",
- "content" => "hey"
- }
- }
-
- {:ok, %Activity{} = activity} = ActivityPub.insert(data)
- assert activity.data["ok"] == data["ok"]
- assert is_binary(activity.data["id"])
-
- given_id = "bla"
-
- data = %{
- "id" => given_id,
- "actor" => user.ap_id,
- "to" => [],
- "context" => "blabla",
- "object" => %{
- "actor" => user.ap_id,
- "to" => [],
- "type" => "Note",
- "content" => "hey"
- }
- }
-
- {:ok, %Activity{} = activity} = ActivityPub.insert(data)
- assert activity.data["ok"] == data["ok"]
- assert activity.data["id"] == given_id
- assert activity.data["context"] == "blabla"
- assert activity.data["context_id"]
- end
-
- test "adds a context when none is there" do
- user = insert(:user)
-
- data = %{
- "actor" => user.ap_id,
- "to" => [],
- "object" => %{
- "actor" => user.ap_id,
- "to" => [],
- "type" => "Note",
- "content" => "hey"
- }
- }
-
- {:ok, %Activity{} = activity} = ActivityPub.insert(data)
- object = Pleroma.Object.normalize(activity)
-
- assert is_binary(activity.data["context"])
- assert is_binary(object.data["context"])
- assert activity.data["context_id"]
- assert object.data["context_id"]
- end
-
- test "adds an id to a given object if it lacks one and is a note and inserts it to the object database" do
- user = insert(:user)
-
- data = %{
- "actor" => user.ap_id,
- "to" => [],
- "object" => %{
- "actor" => user.ap_id,
- "to" => [],
- "type" => "Note",
- "content" => "hey"
- }
- }
-
- {:ok, %Activity{} = activity} = ActivityPub.insert(data)
- assert object = Object.normalize(activity)
- assert is_binary(object.data["id"])
- 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.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 "it reverts create" do
- user = insert(:user)
-
- with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
- assert {:error, :reverted} =
- ActivityPub.create(%{
- to: ["user1", "user2"],
- actor: user,
- context: "",
- object: %{
- "to" => ["user1", "user2"],
- "type" => "Note",
- "content" => "testing"
- }
- })
- end
-
- assert Repo.aggregate(Activity, :count, :id) == 0
- assert Repo.aggregate(Object, :count, :id) == 0
- end
-
- test "removes doubled 'to' recipients" do
- user = insert(:user)
-
- {:ok, activity} =
- ActivityPub.create(%{
- to: ["user1", "user1", "user2"],
- actor: user,
- context: "",
- object: %{
- "to" => ["user1", "user1", "user2"],
- "type" => "Note",
- "content" => "testing"
- }
- })
-
- assert activity.data["to"] == ["user1", "user2"]
- assert activity.actor == user.ap_id
- assert activity.recipients == ["user1", "user2", user.ap_id]
- end
-
- test "increases user note count only for public activities" do
- user = insert(:user)
-
- {:ok, _} =
- CommonAPI.post(User.get_cached_by_id(user.id), %{
- status: "1",
- visibility: "public"
- })
-
- {:ok, _} =
- CommonAPI.post(User.get_cached_by_id(user.id), %{
- status: "2",
- visibility: "unlisted"
- })
-
- {:ok, _} =
- CommonAPI.post(User.get_cached_by_id(user.id), %{
- status: "2",
- visibility: "private"
- })
-
- {:ok, _} =
- CommonAPI.post(User.get_cached_by_id(user.id), %{
- status: "3",
- visibility: "direct"
- })
-
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 2
- end
-
- test "increases replies count" do
- user = insert(:user)
- user2 = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "1", visibility: "public"})
- ap_id = activity.data["id"]
- reply_data = %{status: "1", in_reply_to_status_id: activity.id}
-
- # public
- {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, :visibility, "public"))
- assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
- assert object.data["repliesCount"] == 1
-
- # unlisted
- {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, :visibility, "unlisted"))
- assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
- assert object.data["repliesCount"] == 2
-
- # private
- {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, :visibility, "private"))
- assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
- assert object.data["repliesCount"] == 2
-
- # direct
- {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, :visibility, "direct"))
- assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
- assert object.data["repliesCount"] == 2
- end
- end
-
- describe "fetch activities for recipients" do
- test "retrieve the activities for certain recipients" do
- {:ok, activity_one} = ActivityBuilder.insert(%{"to" => ["someone"]})
- {:ok, activity_two} = ActivityBuilder.insert(%{"to" => ["someone_else"]})
- {:ok, _activity_three} = ActivityBuilder.insert(%{"to" => ["noone"]})
-
- activities = ActivityPub.fetch_activities(["someone", "someone_else"])
- assert length(activities) == 2
- assert activities == [activity_one, activity_two]
- end
- end
-
- describe "fetch activities in context" do
- test "retrieves activities that have a given context" do
- {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
- {:ok, activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
- {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
- {:ok, _activity_four} = ActivityBuilder.insert(%{"type" => "Announce", "context" => "2hu"})
- activity_five = insert(:note_activity)
- user = insert(:user)
-
- {:ok, _user_relationship} = User.block(user, %{ap_id: activity_five.data["actor"]})
-
- activities = ActivityPub.fetch_activities_for_context("2hu", %{blocking_user: user})
- assert activities == [activity_two, activity]
- end
-
- test "doesn't return activities with filtered words" do
- user = insert(:user)
- user_two = insert(:user)
- insert(:filter, user: user, phrase: "test", hide: true)
-
- {:ok, %{id: id1, data: %{"context" => context}}} = CommonAPI.post(user, %{status: "1"})
-
- {:ok, %{id: id2}} = CommonAPI.post(user_two, %{status: "2", in_reply_to_status_id: id1})
-
- {:ok, %{id: id3} = user_activity} =
- CommonAPI.post(user, %{status: "3 test?", in_reply_to_status_id: id2})
-
- {:ok, %{id: id4} = filtered_activity} =
- CommonAPI.post(user_two, %{status: "4 test!", in_reply_to_status_id: id3})
-
- {:ok, _} = CommonAPI.post(user, %{status: "5", in_reply_to_status_id: id4})
-
- activities =
- context
- |> ActivityPub.fetch_activities_for_context(%{user: user})
- |> Enum.map(& &1.id)
-
- assert length(activities) == 4
- assert user_activity.id in activities
- refute filtered_activity.id in activities
- end
- end
-
- test "doesn't return blocked activities" do
- activity_one = insert(:note_activity)
- activity_two = insert(:note_activity)
- activity_three = insert(:note_activity)
- user = insert(:user)
- booster = insert(:user)
- {:ok, _user_relationship} = User.block(user, %{ap_id: activity_one.data["actor"]})
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- refute Enum.member?(activities, activity_one)
-
- {:ok, _user_block} = User.unblock(user, %{ap_id: activity_one.data["actor"]})
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- assert Enum.member?(activities, activity_one)
-
- {:ok, _user_relationship} = User.block(user, %{ap_id: activity_three.data["actor"]})
- {:ok, %{data: %{"object" => id}}} = CommonAPI.repeat(activity_three.id, booster)
- %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
- activity_three = Activity.get_by_id(activity_three.id)
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- refute Enum.member?(activities, activity_three)
- refute Enum.member?(activities, boost_activity)
- assert Enum.member?(activities, activity_one)
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: nil, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- assert Enum.member?(activities, boost_activity)
- assert Enum.member?(activities, activity_one)
- end
-
- test "doesn't return transitive interactions concerning blocked users" do
- blocker = insert(:user)
- blockee = insert(:user)
- friend = insert(:user)
-
- {:ok, _user_relationship} = User.block(blocker, blockee)
-
- {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey!"})
-
- {:ok, activity_two} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
-
- {:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
-
- {:ok, activity_four} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: blocker})
-
- assert Enum.member?(activities, activity_one)
- refute Enum.member?(activities, activity_two)
- refute Enum.member?(activities, activity_three)
- refute Enum.member?(activities, activity_four)
- end
-
- test "doesn't return announce activities with blocked users in 'to'" do
- blocker = insert(:user)
- blockee = insert(:user)
- friend = insert(:user)
-
- {:ok, _user_relationship} = User.block(blocker, blockee)
-
- {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey!"})
-
- {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
-
- {:ok, activity_three} = CommonAPI.repeat(activity_two.id, friend)
-
- activities =
- ActivityPub.fetch_activities([], %{blocking_user: blocker})
- |> Enum.map(fn act -> act.id end)
-
- assert Enum.member?(activities, activity_one.id)
- refute Enum.member?(activities, activity_two.id)
- refute Enum.member?(activities, activity_three.id)
- end
-
- test "doesn't return announce activities with blocked users in 'cc'" do
- blocker = insert(:user)
- blockee = insert(:user)
- friend = insert(:user)
-
- {:ok, _user_relationship} = User.block(blocker, blockee)
-
- {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey!"})
-
- {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
-
- assert object = Pleroma.Object.normalize(activity_two)
-
- data = %{
- "actor" => friend.ap_id,
- "object" => object.data["id"],
- "context" => object.data["context"],
- "type" => "Announce",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [blockee.ap_id]
- }
-
- assert {:ok, activity_three} = ActivityPub.insert(data)
-
- activities =
- ActivityPub.fetch_activities([], %{blocking_user: blocker})
- |> Enum.map(fn act -> act.id end)
-
- assert Enum.member?(activities, activity_one.id)
- refute Enum.member?(activities, activity_two.id)
- refute Enum.member?(activities, activity_three.id)
- end
-
- test "doesn't return activities from blocked domains" do
- domain = "dogwhistle.zone"
- domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
- note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
- activity = insert(:note_activity, %{note: note})
- user = insert(:user)
- {:ok, user} = User.block_domain(user, domain)
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
-
- refute activity in activities
-
- followed_user = insert(:user)
- CommonAPI.follow(user, followed_user)
- {:ok, repeat_activity} = CommonAPI.repeat(activity.id, followed_user)
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
-
- refute repeat_activity in activities
- end
-
- test "does return activities from followed users on blocked domains" do
- domain = "meanies.social"
- domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
- blocker = insert(:user)
-
- {:ok, blocker} = User.follow(blocker, domain_user)
- {:ok, blocker} = User.block_domain(blocker, domain)
-
- assert User.following?(blocker, domain_user)
- assert User.blocks_domain?(blocker, domain_user)
- refute User.blocks?(blocker, domain_user)
-
- note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
- activity = insert(:note_activity, %{note: note})
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: blocker, skip_preload: true})
-
- assert activity in activities
-
- # And check that if the guy we DO follow boosts someone else from their domain,
- # that should be hidden
- another_user = insert(:user, %{ap_id: "https://#{domain}/@meanie2"})
- bad_note = insert(:note, %{data: %{"actor" => another_user.ap_id}})
- bad_activity = insert(:note_activity, %{note: bad_note})
- {:ok, repeat_activity} = CommonAPI.repeat(bad_activity.id, domain_user)
-
- activities = ActivityPub.fetch_activities([], %{blocking_user: blocker, skip_preload: true})
-
- refute repeat_activity in activities
- end
-
- test "doesn't return muted activities" do
- activity_one = insert(:note_activity)
- activity_two = insert(:note_activity)
- activity_three = insert(:note_activity)
- user = insert(:user)
- booster = insert(:user)
-
- activity_one_actor = User.get_by_ap_id(activity_one.data["actor"])
- {:ok, _user_relationships} = User.mute(user, activity_one_actor)
-
- activities = ActivityPub.fetch_activities([], %{muting_user: user, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- refute Enum.member?(activities, activity_one)
-
- # Calling with 'with_muted' will deliver muted activities, too.
- activities =
- ActivityPub.fetch_activities([], %{
- muting_user: user,
- with_muted: true,
- skip_preload: true
- })
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- assert Enum.member?(activities, activity_one)
-
- {:ok, _user_mute} = User.unmute(user, activity_one_actor)
-
- activities = ActivityPub.fetch_activities([], %{muting_user: user, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- assert Enum.member?(activities, activity_one)
-
- activity_three_actor = User.get_by_ap_id(activity_three.data["actor"])
- {:ok, _user_relationships} = User.mute(user, activity_three_actor)
- {:ok, %{data: %{"object" => id}}} = CommonAPI.repeat(activity_three.id, booster)
- %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
- activity_three = Activity.get_by_id(activity_three.id)
-
- activities = ActivityPub.fetch_activities([], %{muting_user: user, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- refute Enum.member?(activities, activity_three)
- refute Enum.member?(activities, boost_activity)
- assert Enum.member?(activities, activity_one)
-
- activities = ActivityPub.fetch_activities([], %{muting_user: nil, skip_preload: true})
-
- assert Enum.member?(activities, activity_two)
- assert Enum.member?(activities, activity_three)
- assert Enum.member?(activities, boost_activity)
- assert Enum.member?(activities, activity_one)
- end
-
- test "doesn't return thread muted activities" do
- user = insert(:user)
- _activity_one = insert(:note_activity)
- note_two = insert(:note, data: %{"context" => "suya.."})
- activity_two = insert(:note_activity, note: note_two)
-
- {:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
-
- assert [_activity_one] = ActivityPub.fetch_activities([], %{muting_user: user})
- end
-
- test "returns thread muted activities when with_muted is set" do
- user = insert(:user)
- _activity_one = insert(:note_activity)
- note_two = insert(:note, data: %{"context" => "suya.."})
- activity_two = insert(:note_activity, note: note_two)
-
- {:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
-
- assert [_activity_two, _activity_one] =
- ActivityPub.fetch_activities([], %{muting_user: user, with_muted: true})
- end
-
- test "does include announces on request" do
- activity_three = insert(:note_activity)
- user = insert(:user)
- booster = insert(:user)
-
- {:ok, user} = User.follow(user, booster)
-
- {:ok, announce} = CommonAPI.repeat(activity_three.id, booster)
-
- [announce_activity] = ActivityPub.fetch_activities([user.ap_id | User.following(user)])
-
- assert announce_activity.id == announce.id
- end
-
- test "excludes reblogs on request" do
- user = insert(:user)
- {:ok, expected_activity} = ActivityBuilder.insert(%{"type" => "Create"}, %{:user => user})
- {:ok, _} = ActivityBuilder.insert(%{"type" => "Announce"}, %{:user => user})
-
- [activity] = ActivityPub.fetch_user_activities(user, nil, %{exclude_reblogs: true})
-
- assert activity == expected_activity
- end
-
- describe "irreversible filters" do
- setup do
- user = insert(:user)
- user_two = insert(:user)
-
- insert(:filter, user: user_two, phrase: "cofe", hide: true)
- insert(:filter, user: user_two, phrase: "ok boomer", hide: true)
- insert(:filter, user: user_two, phrase: "test", hide: false)
-
- params = %{
- type: ["Create", "Announce"],
- user: user_two
- }
-
- {:ok, %{user: user, user_two: user_two, params: params}}
- end
-
- test "it returns statuses if they don't contain exact filter words", %{
- user: user,
- params: params
- } do
- {:ok, _} = CommonAPI.post(user, %{status: "hey"})
- {:ok, _} = CommonAPI.post(user, %{status: "got cofefe?"})
- {:ok, _} = CommonAPI.post(user, %{status: "I am not a boomer"})
- {:ok, _} = CommonAPI.post(user, %{status: "ok boomers"})
- {:ok, _} = CommonAPI.post(user, %{status: "ccofee is not a word"})
- {:ok, _} = CommonAPI.post(user, %{status: "this is a test"})
-
- activities = ActivityPub.fetch_activities([], params)
-
- assert Enum.count(activities) == 6
- end
-
- test "it does not filter user's own statuses", %{user_two: user_two, params: params} do
- {:ok, _} = CommonAPI.post(user_two, %{status: "Give me some cofe!"})
- {:ok, _} = CommonAPI.post(user_two, %{status: "ok boomer"})
-
- activities = ActivityPub.fetch_activities([], params)
-
- assert Enum.count(activities) == 2
- end
-
- test "it excludes statuses with filter words", %{user: user, params: params} do
- {:ok, _} = CommonAPI.post(user, %{status: "Give me some cofe!"})
- {:ok, _} = CommonAPI.post(user, %{status: "ok boomer"})
- {:ok, _} = CommonAPI.post(user, %{status: "is it a cOfE?"})
- {:ok, _} = CommonAPI.post(user, %{status: "cofe is all I need"})
- {:ok, _} = CommonAPI.post(user, %{status: "— ok BOOMER\n"})
-
- activities = ActivityPub.fetch_activities([], params)
-
- assert Enum.empty?(activities)
- end
-
- test "it returns all statuses if user does not have any filters" do
- another_user = insert(:user)
- {:ok, _} = CommonAPI.post(another_user, %{status: "got cofe?"})
- {:ok, _} = CommonAPI.post(another_user, %{status: "test!"})
-
- activities =
- ActivityPub.fetch_activities([], %{
- type: ["Create", "Announce"],
- user: another_user
- })
-
- assert Enum.count(activities) == 2
- end
- end
-
- describe "public fetch activities" do
- test "doesn't retrieve unlisted activities" do
- user = insert(:user)
-
- {:ok, _unlisted_activity} = CommonAPI.post(user, %{status: "yeah", visibility: "unlisted"})
-
- {:ok, listed_activity} = CommonAPI.post(user, %{status: "yeah"})
-
- [activity] = ActivityPub.fetch_public_activities()
-
- assert activity == listed_activity
- end
-
- test "retrieves public activities" do
- _activities = ActivityPub.fetch_public_activities()
-
- %{public: public} = ActivityBuilder.public_and_non_public()
-
- activities = ActivityPub.fetch_public_activities()
- assert length(activities) == 1
- assert Enum.at(activities, 0) == public
- end
-
- test "retrieves a maximum of 20 activities" do
- ActivityBuilder.insert_list(10)
- expected_activities = ActivityBuilder.insert_list(20)
-
- activities = ActivityPub.fetch_public_activities()
-
- assert collect_ids(activities) == collect_ids(expected_activities)
- assert length(activities) == 20
- end
-
- test "retrieves ids starting from a since_id" do
- activities = ActivityBuilder.insert_list(30)
- expected_activities = ActivityBuilder.insert_list(10)
- since_id = List.last(activities).id
-
- activities = ActivityPub.fetch_public_activities(%{since_id: since_id})
-
- assert collect_ids(activities) == collect_ids(expected_activities)
- assert length(activities) == 10
- end
-
- test "retrieves ids up to max_id" do
- ActivityBuilder.insert_list(10)
- expected_activities = ActivityBuilder.insert_list(20)
-
- %{id: max_id} =
- 10
- |> ActivityBuilder.insert_list()
- |> List.first()
-
- activities = ActivityPub.fetch_public_activities(%{max_id: max_id})
-
- assert length(activities) == 20
- assert collect_ids(activities) == collect_ids(expected_activities)
- end
-
- test "paginates via offset/limit" do
- _first_part_activities = ActivityBuilder.insert_list(10)
- second_part_activities = ActivityBuilder.insert_list(10)
-
- later_activities = ActivityBuilder.insert_list(10)
-
- activities = ActivityPub.fetch_public_activities(%{page: "2", page_size: "20"}, :offset)
-
- assert length(activities) == 20
-
- assert collect_ids(activities) ==
- collect_ids(second_part_activities) ++ collect_ids(later_activities)
- end
-
- test "doesn't return reblogs for users for whom reblogs have been muted" do
- activity = insert(:note_activity)
- user = insert(:user)
- booster = insert(:user)
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
-
- {:ok, activity} = CommonAPI.repeat(activity.id, booster)
-
- activities = ActivityPub.fetch_activities([], %{muting_user: user})
-
- refute Enum.any?(activities, fn %{id: id} -> id == activity.id end)
- end
-
- test "returns reblogs for users for whom reblogs have not been muted" do
- activity = insert(:note_activity)
- user = insert(:user)
- booster = insert(:user)
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
- {:ok, _reblog_mute} = CommonAPI.show_reblogs(user, booster)
-
- {:ok, activity} = CommonAPI.repeat(activity.id, booster)
-
- activities = ActivityPub.fetch_activities([], %{muting_user: user})
-
- assert Enum.any?(activities, fn %{id: id} -> id == activity.id end)
- end
- end
-
- describe "uploading files" do
- setup do
- test_file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- %{test_file: test_file}
- end
-
- test "sets a description if given", %{test_file: file} do
- {:ok, %Object{} = object} = ActivityPub.upload(file, description: "a cool file")
- assert object.data["name"] == "a cool file"
- end
-
- test "it sets the default description depending on the configuration", %{test_file: file} do
- clear_config([Pleroma.Upload, :default_description])
-
- Pleroma.Config.put([Pleroma.Upload, :default_description], nil)
- {:ok, %Object{} = object} = ActivityPub.upload(file)
- assert object.data["name"] == ""
-
- Pleroma.Config.put([Pleroma.Upload, :default_description], :filename)
- {:ok, %Object{} = object} = ActivityPub.upload(file)
- assert object.data["name"] == "an_image.jpg"
-
- Pleroma.Config.put([Pleroma.Upload, :default_description], "unnamed attachment")
- {:ok, %Object{} = object} = ActivityPub.upload(file)
- assert object.data["name"] == "unnamed attachment"
- end
-
- test "copies the file to the configured folder", %{test_file: file} do
- clear_config([Pleroma.Upload, :default_description], :filename)
- {:ok, %Object{} = object} = ActivityPub.upload(file)
- assert object.data["name"] == "an_image.jpg"
- end
-
- test "works with base64 encoded images" do
- file = %{
- img: data_uri()
- }
-
- {:ok, %Object{}} = ActivityPub.upload(file)
- end
- end
-
- describe "fetch the latest Follow" do
- test "fetches the latest Follow activity" do
- %Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity)
- follower = Repo.get_by(User, ap_id: activity.data["actor"])
- followed = Repo.get_by(User, ap_id: activity.data["object"])
-
- assert activity == Utils.fetch_latest_follow(follower, followed)
- end
- end
-
- describe "unfollowing" do
- test "it reverts unfollow activity" do
- follower = insert(:user)
- followed = insert(:user)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
-
- with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
- assert {:error, :reverted} = ActivityPub.unfollow(follower, followed)
- end
-
- activity = Activity.get_by_id(follow_activity.id)
- assert activity.data["type"] == "Follow"
- assert activity.data["actor"] == follower.ap_id
-
- assert activity.data["object"] == followed.ap_id
- end
-
- test "creates an undo activity for the last follow" do
- follower = insert(:user)
- followed = insert(:user)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
- {:ok, activity} = ActivityPub.unfollow(follower, followed)
-
- assert activity.data["type"] == "Undo"
- assert activity.data["actor"] == follower.ap_id
-
- embedded_object = activity.data["object"]
- assert is_map(embedded_object)
- assert embedded_object["type"] == "Follow"
- assert embedded_object["object"] == followed.ap_id
- assert embedded_object["id"] == follow_activity.data["id"]
- end
-
- test "creates an undo activity for a pending follow request" do
- follower = insert(:user)
- followed = insert(:user, %{locked: true})
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
- {:ok, activity} = ActivityPub.unfollow(follower, followed)
-
- assert activity.data["type"] == "Undo"
- assert activity.data["actor"] == follower.ap_id
-
- embedded_object = activity.data["object"]
- assert is_map(embedded_object)
- assert embedded_object["type"] == "Follow"
- assert embedded_object["object"] == followed.ap_id
- assert embedded_object["id"] == follow_activity.data["id"]
- end
- end
-
- describe "timeline post-processing" do
- test "it filters broken threads" do
- user1 = insert(:user)
- user2 = insert(:user)
- user3 = insert(:user)
-
- {:ok, user1} = User.follow(user1, user3)
- assert User.following?(user1, user3)
-
- {:ok, user2} = User.follow(user2, user3)
- assert User.following?(user2, user3)
-
- {:ok, user3} = User.follow(user3, user2)
- assert User.following?(user3, user2)
-
- {:ok, public_activity} = CommonAPI.post(user3, %{status: "hi 1"})
-
- {:ok, private_activity_1} = CommonAPI.post(user3, %{status: "hi 2", visibility: "private"})
-
- {:ok, private_activity_2} =
- CommonAPI.post(user2, %{
- status: "hi 3",
- visibility: "private",
- in_reply_to_status_id: private_activity_1.id
- })
-
- {:ok, private_activity_3} =
- CommonAPI.post(user3, %{
- status: "hi 4",
- visibility: "private",
- in_reply_to_status_id: private_activity_2.id
- })
-
- activities =
- ActivityPub.fetch_activities([user1.ap_id | User.following(user1)])
- |> Enum.map(fn a -> a.id end)
-
- private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"])
-
- assert [public_activity.id, private_activity_1.id, private_activity_3.id] == activities
-
- assert length(activities) == 3
-
- activities =
- ActivityPub.fetch_activities([user1.ap_id | User.following(user1)], %{user: user1})
- |> Enum.map(fn a -> a.id end)
-
- assert [public_activity.id, private_activity_1.id] == activities
- assert length(activities) == 2
- end
- end
-
- describe "flag/1" do
- setup do
- reporter = insert(:user)
- target_account = insert(:user)
- content = "foobar"
- {:ok, activity} = CommonAPI.post(target_account, %{status: content})
- context = Utils.generate_context_id()
-
- reporter_ap_id = reporter.ap_id
- target_ap_id = target_account.ap_id
- activity_ap_id = activity.data["id"]
-
- activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id)
-
- {:ok,
- %{
- reporter: reporter,
- context: context,
- target_account: target_account,
- reported_activity: activity,
- content: content,
- activity_ap_id: activity_ap_id,
- activity_with_object: activity_with_object,
- reporter_ap_id: reporter_ap_id,
- target_ap_id: target_ap_id
- }}
- end
-
- test "it can create a Flag activity",
- %{
- reporter: reporter,
- context: context,
- target_account: target_account,
- reported_activity: reported_activity,
- content: content,
- activity_ap_id: activity_ap_id,
- activity_with_object: activity_with_object,
- reporter_ap_id: reporter_ap_id,
- target_ap_id: target_ap_id
- } do
- assert {:ok, activity} =
- ActivityPub.flag(%{
- actor: reporter,
- context: context,
- account: target_account,
- statuses: [reported_activity],
- content: content
- })
-
- note_obj = %{
- "type" => "Note",
- "id" => activity_ap_id,
- "content" => content,
- "published" => activity_with_object.object.data["published"],
- "actor" =>
- AccountView.render("show.json", %{user: target_account, skip_visibility_check: true})
- }
-
- assert %Activity{
- actor: ^reporter_ap_id,
- data: %{
- "type" => "Flag",
- "content" => ^content,
- "context" => ^context,
- "object" => [^target_ap_id, ^note_obj]
- }
- } = activity
- end
-
- test_with_mock "strips status data from Flag, before federating it",
- %{
- reporter: reporter,
- context: context,
- target_account: target_account,
- reported_activity: reported_activity,
- content: content
- },
- Utils,
- [:passthrough],
- [] do
- {:ok, activity} =
- ActivityPub.flag(%{
- actor: reporter,
- context: context,
- account: target_account,
- statuses: [reported_activity],
- content: content
- })
-
- new_data =
- put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]])
-
- assert_called(Utils.maybe_federate(%{activity | data: new_data}))
- end
- end
-
- test "fetch_activities/2 returns activities addressed to a list " do
- user = insert(:user)
- member = insert(:user)
- {:ok, list} = Pleroma.List.create("foo", user)
- {:ok, list} = Pleroma.List.follow(list, member)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
-
- activity = Repo.preload(activity, :bookmark)
- activity = %Activity{activity | thread_muted?: !!activity.thread_muted?}
-
- assert ActivityPub.fetch_activities([], %{user: user}) == [activity]
- end
-
- def data_uri do
- File.read!("test/fixtures/avatar_data_uri")
- end
-
- describe "fetch_activities_bounded" do
- test "fetches private posts for followed users" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "thought I looked cute might delete later :3",
- visibility: "private"
- })
-
- [result] = ActivityPub.fetch_activities_bounded([user.follower_address], [])
- assert result.id == activity.id
- end
-
- test "fetches only public posts for other users" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe", visibility: "public"})
-
- {:ok, _private_activity} =
- CommonAPI.post(user, %{
- status: "why is tenshi eating a corndog so cute?",
- visibility: "private"
- })
-
- [result] = ActivityPub.fetch_activities_bounded([], [user.follower_address])
- assert result.id == activity.id
- end
- end
-
- describe "fetch_follow_information_for_user" do
- test "syncronizes following/followers counters" do
- user =
- insert(:user,
- local: false,
- follower_address: "http://localhost:4001/users/fuser2/followers",
- following_address: "http://localhost:4001/users/fuser2/following"
- )
-
- {:ok, info} = ActivityPub.fetch_follow_information_for_user(user)
- assert info.follower_count == 527
- assert info.following_count == 267
- end
-
- test "detects hidden followers" do
- mock(fn env ->
- case env.url do
- "http://localhost:4001/users/masto_closed/followers?page=1" ->
- %Tesla.Env{status: 403, body: ""}
-
- _ ->
- apply(HttpRequestMock, :request, [env])
- end
- end)
-
- user =
- insert(:user,
- local: false,
- follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following"
- )
-
- {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
- assert follow_info.hide_followers == true
- assert follow_info.hide_follows == false
- end
-
- test "detects hidden follows" do
- mock(fn env ->
- case env.url do
- "http://localhost:4001/users/masto_closed/following?page=1" ->
- %Tesla.Env{status: 403, body: ""}
-
- _ ->
- apply(HttpRequestMock, :request, [env])
- end
- end)
-
- user =
- insert(:user,
- local: false,
- follower_address: "http://localhost:4001/users/masto_closed/followers",
- following_address: "http://localhost:4001/users/masto_closed/following"
- )
-
- {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
- assert follow_info.hide_followers == false
- assert follow_info.hide_follows == true
- end
-
- test "detects hidden follows/followers for friendica" do
- user =
- insert(:user,
- local: false,
- follower_address: "http://localhost:8080/followers/fuser3",
- following_address: "http://localhost:8080/following/fuser3"
- )
-
- {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
- assert follow_info.hide_followers == true
- assert follow_info.follower_count == 296
- assert follow_info.following_count == 32
- assert follow_info.hide_follows == true
- end
-
- test "doesn't crash when follower and following counters are hidden" do
- mock(fn env ->
- case env.url do
- "http://localhost:4001/users/masto_hidden_counters/following" ->
- json(%{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "id" => "http://localhost:4001/users/masto_hidden_counters/followers"
- })
-
- "http://localhost:4001/users/masto_hidden_counters/following?page=1" ->
- %Tesla.Env{status: 403, body: ""}
-
- "http://localhost:4001/users/masto_hidden_counters/followers" ->
- json(%{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "id" => "http://localhost:4001/users/masto_hidden_counters/following"
- })
-
- "http://localhost:4001/users/masto_hidden_counters/followers?page=1" ->
- %Tesla.Env{status: 403, body: ""}
- end
- end)
-
- user =
- insert(:user,
- local: false,
- follower_address: "http://localhost:4001/users/masto_hidden_counters/followers",
- following_address: "http://localhost:4001/users/masto_hidden_counters/following"
- )
-
- {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
-
- assert follow_info.hide_followers == true
- assert follow_info.follower_count == 0
- assert follow_info.hide_follows == true
- assert follow_info.following_count == 0
- end
- end
-
- describe "fetch_favourites/3" do
- test "returns a favourite activities sorted by adds to favorite" do
- user = insert(:user)
- other_user = insert(:user)
- user1 = insert(:user)
- user2 = insert(:user)
- {:ok, a1} = CommonAPI.post(user1, %{status: "bla"})
- {:ok, _a2} = CommonAPI.post(user2, %{status: "traps are happy"})
- {:ok, a3} = CommonAPI.post(user2, %{status: "Trees Are "})
- {:ok, a4} = CommonAPI.post(user2, %{status: "Agent Smith "})
- {:ok, a5} = CommonAPI.post(user1, %{status: "Red or Blue "})
-
- {:ok, _} = CommonAPI.favorite(user, a4.id)
- {:ok, _} = CommonAPI.favorite(other_user, a3.id)
- {:ok, _} = CommonAPI.favorite(user, a3.id)
- {:ok, _} = CommonAPI.favorite(other_user, a5.id)
- {:ok, _} = CommonAPI.favorite(user, a5.id)
- {:ok, _} = CommonAPI.favorite(other_user, a4.id)
- {:ok, _} = CommonAPI.favorite(user, a1.id)
- {:ok, _} = CommonAPI.favorite(other_user, a1.id)
- result = ActivityPub.fetch_favourites(user)
-
- assert Enum.map(result, & &1.id) == [a1.id, a5.id, a3.id, a4.id]
-
- result = ActivityPub.fetch_favourites(user, %{limit: 2})
- assert Enum.map(result, & &1.id) == [a1.id, a5.id]
- end
- end
-
- describe "Move activity" do
- test "create" do
- %{ap_id: old_ap_id} = old_user = insert(:user)
- %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
- follower = insert(:user)
- follower_move_opted_out = insert(:user, allow_following_move: false)
-
- User.follow(follower, old_user)
- User.follow(follower_move_opted_out, old_user)
-
- assert User.following?(follower, old_user)
- assert User.following?(follower_move_opted_out, old_user)
-
- assert {:ok, activity} = ActivityPub.move(old_user, new_user)
-
- assert %Activity{
- actor: ^old_ap_id,
- data: %{
- "actor" => ^old_ap_id,
- "object" => ^old_ap_id,
- "target" => ^new_ap_id,
- "type" => "Move"
- },
- local: true
- } = activity
-
- params = %{
- "op" => "move_following",
- "origin_id" => old_user.id,
- "target_id" => new_user.id
- }
-
- assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
-
- Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
-
- refute User.following?(follower, old_user)
- assert User.following?(follower, new_user)
-
- assert User.following?(follower_move_opted_out, old_user)
- refute User.following?(follower_move_opted_out, new_user)
-
- activity = %Activity{activity | object: nil}
-
- assert [%Notification{activity: ^activity}] = Notification.for_user(follower)
-
- assert [%Notification{activity: ^activity}] = Notification.for_user(follower_move_opted_out)
- end
-
- test "old user must be in the new user's `also_known_as` list" do
- old_user = insert(:user)
- new_user = insert(:user)
-
- assert {:error, "Target account must have the origin in `alsoKnownAs`"} =
- ActivityPub.move(old_user, new_user)
- end
- end
-
- test "doesn't retrieve replies activities with exclude_replies" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "yeah"})
-
- {:ok, _reply} = CommonAPI.post(user, %{status: "yeah", in_reply_to_status_id: activity.id})
-
- [result] = ActivityPub.fetch_public_activities(%{exclude_replies: true})
-
- assert result.id == activity.id
-
- assert length(ActivityPub.fetch_public_activities()) == 2
- end
-
- describe "replies filtering with public messages" do
- setup :public_messages
-
- test "public timeline", %{users: %{u1: user}} do
- activities_ids =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:local_only, false)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:reply_filtering_user, user)
- |> ActivityPub.fetch_public_activities()
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 16
- end
-
- test "public timeline with reply_visibility `following`", %{
- users: %{u1: user},
- u1: u1,
- u2: u2,
- u3: u3,
- u4: u4,
- activities: activities
- } do
- activities_ids =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:local_only, false)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:reply_visibility, "following")
- |> Map.put(:reply_filtering_user, user)
- |> ActivityPub.fetch_public_activities()
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 14
-
- visible_ids =
- Map.values(u1) ++ Map.values(u2) ++ Map.values(u4) ++ Map.values(activities) ++ [u3[:r1]]
-
- assert Enum.all?(visible_ids, &(&1 in activities_ids))
- end
-
- test "public timeline with reply_visibility `self`", %{
- users: %{u1: user},
- u1: u1,
- u2: u2,
- u3: u3,
- u4: u4,
- activities: activities
- } do
- activities_ids =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:local_only, false)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:reply_visibility, "self")
- |> Map.put(:reply_filtering_user, user)
- |> ActivityPub.fetch_public_activities()
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 10
- visible_ids = Map.values(u1) ++ [u2[:r1], u3[:r1], u4[:r1]] ++ Map.values(activities)
- assert Enum.all?(visible_ids, &(&1 in activities_ids))
- end
-
- test "home timeline", %{
- users: %{u1: user},
- activities: activities,
- u1: u1,
- u2: u2,
- u3: u3,
- u4: u4
- } do
- params =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> Map.put(:reply_filtering_user, user)
-
- activities_ids =
- ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 13
-
- visible_ids =
- Map.values(u1) ++
- Map.values(u3) ++
- [
- activities[:a1],
- activities[:a2],
- activities[:a4],
- u2[:r1],
- u2[:r3],
- u4[:r1],
- u4[:r2]
- ]
-
- assert Enum.all?(visible_ids, &(&1 in activities_ids))
- end
-
- test "home timeline with reply_visibility `following`", %{
- users: %{u1: user},
- activities: activities,
- u1: u1,
- u2: u2,
- u3: u3,
- u4: u4
- } do
- params =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> Map.put(:reply_visibility, "following")
- |> Map.put(:reply_filtering_user, user)
-
- activities_ids =
- ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 11
-
- visible_ids =
- Map.values(u1) ++
- [
- activities[:a1],
- activities[:a2],
- activities[:a4],
- u2[:r1],
- u2[:r3],
- u3[:r1],
- u4[:r1],
- u4[:r2]
- ]
-
- assert Enum.all?(visible_ids, &(&1 in activities_ids))
- end
-
- test "home timeline with reply_visibility `self`", %{
- users: %{u1: user},
- activities: activities,
- u1: u1,
- u2: u2,
- u3: u3,
- u4: u4
- } do
- params =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> Map.put(:reply_visibility, "self")
- |> Map.put(:reply_filtering_user, user)
-
- activities_ids =
- ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 9
-
- visible_ids =
- Map.values(u1) ++
- [
- activities[:a1],
- activities[:a2],
- activities[:a4],
- u2[:r1],
- u3[:r1],
- u4[:r1]
- ]
-
- assert Enum.all?(visible_ids, &(&1 in activities_ids))
- end
-
- test "filtering out announces where the user is the actor of the announced message" do
- user = insert(:user)
- other_user = insert(:user)
- third_user = insert(:user)
- User.follow(user, other_user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "yo"})
- {:ok, other_post} = CommonAPI.post(third_user, %{status: "yo"})
- {:ok, _announce} = CommonAPI.repeat(post.id, other_user)
- {:ok, _announce} = CommonAPI.repeat(post.id, third_user)
- {:ok, announce} = CommonAPI.repeat(other_post.id, other_user)
-
- params = %{
- type: ["Announce"]
- }
-
- results =
- [user.ap_id | User.following(user)]
- |> ActivityPub.fetch_activities(params)
-
- assert length(results) == 3
-
- params = %{
- type: ["Announce"],
- announce_filtering_user: user
- }
-
- [result] =
- [user.ap_id | User.following(user)]
- |> ActivityPub.fetch_activities(params)
-
- assert result.id == announce.id
- end
- end
-
- describe "replies filtering with private messages" do
- setup :private_messages
-
- test "public timeline", %{users: %{u1: user}} do
- activities_ids =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:local_only, false)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> ActivityPub.fetch_public_activities()
- |> Enum.map(& &1.id)
-
- assert activities_ids == []
- end
-
- test "public timeline with default reply_visibility `following`", %{users: %{u1: user}} do
- activities_ids =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:local_only, false)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:reply_visibility, "following")
- |> Map.put(:reply_filtering_user, user)
- |> Map.put(:user, user)
- |> ActivityPub.fetch_public_activities()
- |> Enum.map(& &1.id)
-
- assert activities_ids == []
- end
-
- test "public timeline with default reply_visibility `self`", %{users: %{u1: user}} do
- activities_ids =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:local_only, false)
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:reply_visibility, "self")
- |> Map.put(:reply_filtering_user, user)
- |> Map.put(:user, user)
- |> ActivityPub.fetch_public_activities()
- |> Enum.map(& &1.id)
-
- assert activities_ids == []
-
- activities_ids =
- %{}
- |> Map.put(:reply_visibility, "self")
- |> Map.put(:reply_filtering_user, nil)
- |> ActivityPub.fetch_public_activities()
-
- assert activities_ids == []
- end
-
- test "home timeline", %{users: %{u1: user}} do
- params =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
-
- activities_ids =
- ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 12
- end
-
- test "home timeline with default reply_visibility `following`", %{users: %{u1: user}} do
- params =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> Map.put(:reply_visibility, "following")
- |> Map.put(:reply_filtering_user, user)
-
- activities_ids =
- ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 12
- end
-
- test "home timeline with default reply_visibility `self`", %{
- users: %{u1: user},
- activities: activities,
- u1: u1,
- u2: u2,
- u3: u3,
- u4: u4
- } do
- params =
- %{}
- |> Map.put(:type, ["Create", "Announce"])
- |> Map.put(:blocking_user, user)
- |> Map.put(:muting_user, user)
- |> Map.put(:user, user)
- |> Map.put(:reply_visibility, "self")
- |> Map.put(:reply_filtering_user, user)
-
- activities_ids =
- ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
- |> Enum.map(& &1.id)
-
- assert length(activities_ids) == 10
-
- visible_ids =
- Map.values(u1) ++ Map.values(u4) ++ [u2[:r1], u3[:r1]] ++ Map.values(activities)
-
- assert Enum.all?(visible_ids, &(&1 in activities_ids))
- end
- end
-
- defp public_messages(_) do
- [u1, u2, u3, u4] = insert_list(4, :user)
- {:ok, u1} = User.follow(u1, u2)
- {:ok, u2} = User.follow(u2, u1)
- {:ok, u1} = User.follow(u1, u4)
- {:ok, u4} = User.follow(u4, u1)
-
- {:ok, u2} = User.follow(u2, u3)
- {:ok, u3} = User.follow(u3, u2)
-
- {:ok, a1} = CommonAPI.post(u1, %{status: "Status"})
-
- {:ok, r1_1} =
- CommonAPI.post(u2, %{
- status: "@#{u1.nickname} reply from u2 to u1",
- in_reply_to_status_id: a1.id
- })
-
- {:ok, r1_2} =
- CommonAPI.post(u3, %{
- status: "@#{u1.nickname} reply from u3 to u1",
- in_reply_to_status_id: a1.id
- })
-
- {:ok, r1_3} =
- CommonAPI.post(u4, %{
- status: "@#{u1.nickname} reply from u4 to u1",
- in_reply_to_status_id: a1.id
- })
-
- {:ok, a2} = CommonAPI.post(u2, %{status: "Status"})
-
- {:ok, r2_1} =
- CommonAPI.post(u1, %{
- status: "@#{u2.nickname} reply from u1 to u2",
- in_reply_to_status_id: a2.id
- })
-
- {:ok, r2_2} =
- CommonAPI.post(u3, %{
- status: "@#{u2.nickname} reply from u3 to u2",
- in_reply_to_status_id: a2.id
- })
-
- {:ok, r2_3} =
- CommonAPI.post(u4, %{
- status: "@#{u2.nickname} reply from u4 to u2",
- in_reply_to_status_id: a2.id
- })
-
- {:ok, a3} = CommonAPI.post(u3, %{status: "Status"})
-
- {:ok, r3_1} =
- CommonAPI.post(u1, %{
- status: "@#{u3.nickname} reply from u1 to u3",
- in_reply_to_status_id: a3.id
- })
-
- {:ok, r3_2} =
- CommonAPI.post(u2, %{
- status: "@#{u3.nickname} reply from u2 to u3",
- in_reply_to_status_id: a3.id
- })
-
- {:ok, r3_3} =
- CommonAPI.post(u4, %{
- status: "@#{u3.nickname} reply from u4 to u3",
- in_reply_to_status_id: a3.id
- })
-
- {:ok, a4} = CommonAPI.post(u4, %{status: "Status"})
-
- {:ok, r4_1} =
- CommonAPI.post(u1, %{
- status: "@#{u4.nickname} reply from u1 to u4",
- in_reply_to_status_id: a4.id
- })
-
- {:ok, r4_2} =
- CommonAPI.post(u2, %{
- status: "@#{u4.nickname} reply from u2 to u4",
- in_reply_to_status_id: a4.id
- })
-
- {:ok, r4_3} =
- CommonAPI.post(u3, %{
- status: "@#{u4.nickname} reply from u3 to u4",
- in_reply_to_status_id: a4.id
- })
-
- {:ok,
- users: %{u1: u1, u2: u2, u3: u3, u4: u4},
- activities: %{a1: a1.id, a2: a2.id, a3: a3.id, a4: a4.id},
- u1: %{r1: r1_1.id, r2: r1_2.id, r3: r1_3.id},
- u2: %{r1: r2_1.id, r2: r2_2.id, r3: r2_3.id},
- u3: %{r1: r3_1.id, r2: r3_2.id, r3: r3_3.id},
- u4: %{r1: r4_1.id, r2: r4_2.id, r3: r4_3.id}}
- end
-
- defp private_messages(_) do
- [u1, u2, u3, u4] = insert_list(4, :user)
- {:ok, u1} = User.follow(u1, u2)
- {:ok, u2} = User.follow(u2, u1)
- {:ok, u1} = User.follow(u1, u3)
- {:ok, u3} = User.follow(u3, u1)
- {:ok, u1} = User.follow(u1, u4)
- {:ok, u4} = User.follow(u4, u1)
-
- {:ok, u2} = User.follow(u2, u3)
- {:ok, u3} = User.follow(u3, u2)
-
- {:ok, a1} = CommonAPI.post(u1, %{status: "Status", visibility: "private"})
-
- {:ok, r1_1} =
- CommonAPI.post(u2, %{
- status: "@#{u1.nickname} reply from u2 to u1",
- in_reply_to_status_id: a1.id,
- visibility: "private"
- })
-
- {:ok, r1_2} =
- CommonAPI.post(u3, %{
- status: "@#{u1.nickname} reply from u3 to u1",
- in_reply_to_status_id: a1.id,
- visibility: "private"
- })
-
- {:ok, r1_3} =
- CommonAPI.post(u4, %{
- status: "@#{u1.nickname} reply from u4 to u1",
- in_reply_to_status_id: a1.id,
- visibility: "private"
- })
-
- {:ok, a2} = CommonAPI.post(u2, %{status: "Status", visibility: "private"})
-
- {:ok, r2_1} =
- CommonAPI.post(u1, %{
- status: "@#{u2.nickname} reply from u1 to u2",
- in_reply_to_status_id: a2.id,
- visibility: "private"
- })
-
- {:ok, r2_2} =
- CommonAPI.post(u3, %{
- status: "@#{u2.nickname} reply from u3 to u2",
- in_reply_to_status_id: a2.id,
- visibility: "private"
- })
-
- {:ok, a3} = CommonAPI.post(u3, %{status: "Status", visibility: "private"})
-
- {:ok, r3_1} =
- CommonAPI.post(u1, %{
- status: "@#{u3.nickname} reply from u1 to u3",
- in_reply_to_status_id: a3.id,
- visibility: "private"
- })
-
- {:ok, r3_2} =
- CommonAPI.post(u2, %{
- status: "@#{u3.nickname} reply from u2 to u3",
- in_reply_to_status_id: a3.id,
- visibility: "private"
- })
-
- {:ok, a4} = CommonAPI.post(u4, %{status: "Status", visibility: "private"})
-
- {:ok, r4_1} =
- CommonAPI.post(u1, %{
- status: "@#{u4.nickname} reply from u1 to u4",
- in_reply_to_status_id: a4.id,
- visibility: "private"
- })
-
- {:ok,
- users: %{u1: u1, u2: u2, u3: u3, u4: u4},
- activities: %{a1: a1.id, a2: a2.id, a3: a3.id, a4: a4.id},
- u1: %{r1: r1_1.id, r2: r1_2.id, r3: r1_3.id},
- u2: %{r1: r2_1.id, r2: r2_2.id},
- u3: %{r1: r3_1.id, r2: r3_2.id},
- u4: %{r1: r4_1.id}}
- end
-
- describe "maybe_update_follow_information/1" do
- setup do
- clear_config([:instance, :external_user_synchronization], true)
-
- user = %{
- local: false,
- ap_id: "https://gensokyo.2hu/users/raymoo",
- following_address: "https://gensokyo.2hu/users/following",
- follower_address: "https://gensokyo.2hu/users/followers",
- type: "Person"
- }
-
- %{user: user}
- end
-
- test "logs an error when it can't fetch the info", %{user: user} do
- assert capture_log(fn ->
- ActivityPub.maybe_update_follow_information(user)
- end) =~ "Follower/Following counter update for #{user.ap_id} failed"
- end
-
- test "just returns the input if the user type is Application", %{
- user: user
- } do
- user =
- user
- |> Map.put(:type, "Application")
-
- refute capture_log(fn ->
- assert ^user = ActivityPub.maybe_update_follow_information(user)
- end) =~ "Follower/Following counter update for #{user.ap_id} failed"
- end
-
- test "it just returns the input if the user has no following/follower addresses", %{
- user: user
- } do
- user =
- user
- |> Map.put(:following_address, nil)
- |> Map.put(:follower_address, nil)
-
- refute capture_log(fn ->
- assert ^user = ActivityPub.maybe_update_follow_information(user)
- end) =~ "Follower/Following counter update for #{user.ap_id} failed"
- end
- end
-
- describe "global activity expiration" do
- setup do: clear_config([:mrf, :policies])
-
- test "creates an activity expiration for local Create activities" do
- Pleroma.Config.put(
- [:mrf, :policies],
- Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
- )
-
- {:ok, %{id: id_create}} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
- {:ok, _follow} = ActivityBuilder.insert(%{"type" => "Follow", "context" => "3hu"})
-
- assert [%{activity_id: ^id_create}] = Pleroma.ActivityExpiration |> Repo.all()
- end
- end
-
- describe "handling of clashing nicknames" do
- test "renames an existing user with a clashing nickname and a different ap id" do
- orig_user =
- insert(
- :user,
- local: false,
- nickname: "admin@mastodon.example.org",
- ap_id: "http://mastodon.example.org/users/harinezumigari"
- )
-
- %{
- nickname: orig_user.nickname,
- ap_id: orig_user.ap_id <> "part_2"
- }
- |> ActivityPub.maybe_handle_clashing_nickname()
-
- user = User.get_by_id(orig_user.id)
-
- assert user.nickname == "#{orig_user.id}.admin@mastodon.example.org"
- end
-
- test "does nothing with a clashing nickname and the same ap id" do
- orig_user =
- insert(
- :user,
- local: false,
- nickname: "admin@mastodon.example.org",
- ap_id: "http://mastodon.example.org/users/harinezumigari"
- )
-
- %{
- nickname: orig_user.nickname,
- ap_id: orig_user.ap_id
- }
- |> ActivityPub.maybe_handle_clashing_nickname()
-
- user = User.get_by_id(orig_user.id)
-
- assert user.nickname == orig_user.nickname
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs b/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
deleted file mode 100644
index f25cf8b12..000000000
--- a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
+++ /dev/null
@@ -1,84 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
- use ExUnit.Case, async: true
- alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
-
- @id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
- @local_actor Pleroma.Web.Endpoint.url() <> "/users/cofe"
-
- test "adds `expires_at` property" do
- assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
- ActivityExpirationPolicy.filter(%{
- "id" => @id,
- "actor" => @local_actor,
- "type" => "Create",
- "object" => %{"type" => "Note"}
- })
-
- assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
- end
-
- test "keeps existing `expires_at` if it less than the config setting" do
- expires_at = NaiveDateTime.utc_now() |> Timex.shift(days: 1)
-
- assert {:ok, %{"type" => "Create", "expires_at" => ^expires_at}} =
- ActivityExpirationPolicy.filter(%{
- "id" => @id,
- "actor" => @local_actor,
- "type" => "Create",
- "expires_at" => expires_at,
- "object" => %{"type" => "Note"}
- })
- end
-
- test "overwrites existing `expires_at` if it greater than the config setting" do
- too_distant_future = NaiveDateTime.utc_now() |> Timex.shift(years: 2)
-
- assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
- ActivityExpirationPolicy.filter(%{
- "id" => @id,
- "actor" => @local_actor,
- "type" => "Create",
- "expires_at" => too_distant_future,
- "object" => %{"type" => "Note"}
- })
-
- assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
- end
-
- test "ignores remote activities" do
- assert {:ok, activity} =
- ActivityExpirationPolicy.filter(%{
- "id" => "https://example.com/123",
- "actor" => "https://example.com/users/cofe",
- "type" => "Create",
- "object" => %{"type" => "Note"}
- })
-
- refute Map.has_key?(activity, "expires_at")
- end
-
- test "ignores non-Create/Note activities" do
- assert {:ok, activity} =
- ActivityExpirationPolicy.filter(%{
- "id" => "https://example.com/123",
- "actor" => "https://example.com/users/cofe",
- "type" => "Follow"
- })
-
- refute Map.has_key?(activity, "expires_at")
-
- assert {:ok, activity} =
- ActivityExpirationPolicy.filter(%{
- "id" => "https://example.com/123",
- "actor" => "https://example.com/users/cofe",
- "type" => "Create",
- "object" => %{"type" => "Cofe"}
- })
-
- refute Map.has_key?(activity, "expires_at")
- end
-end
diff --git a/test/web/activity_pub/mrf/anti_followbot_policy_test.exs b/test/web/activity_pub/mrf/anti_followbot_policy_test.exs
deleted file mode 100644
index 3c795f5ac..000000000
--- a/test/web/activity_pub/mrf/anti_followbot_policy_test.exs
+++ /dev/null
@@ -1,72 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicyTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy
-
- describe "blocking based on attributes" do
- test "matches followbots by nickname" do
- actor = insert(:user, %{nickname: "followbot@example.com"})
- target = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Follow",
- "actor" => actor.ap_id,
- "object" => target.ap_id,
- "id" => "https://example.com/activities/1234"
- }
-
- assert {:reject, "[AntiFollowbotPolicy]" <> _} = AntiFollowbotPolicy.filter(message)
- end
-
- test "matches followbots by display name" do
- actor = insert(:user, %{name: "Federation Bot"})
- target = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Follow",
- "actor" => actor.ap_id,
- "object" => target.ap_id,
- "id" => "https://example.com/activities/1234"
- }
-
- assert {:reject, "[AntiFollowbotPolicy]" <> _} = AntiFollowbotPolicy.filter(message)
- end
- end
-
- test "it allows non-followbots" do
- actor = insert(:user)
- target = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Follow",
- "actor" => actor.ap_id,
- "object" => target.ap_id,
- "id" => "https://example.com/activities/1234"
- }
-
- {:ok, _} = AntiFollowbotPolicy.filter(message)
- end
-
- test "it gracefully handles nil display names" do
- actor = insert(:user, %{name: nil})
- target = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Follow",
- "actor" => actor.ap_id,
- "object" => target.ap_id,
- "id" => "https://example.com/activities/1234"
- }
-
- {:ok, _} = AntiFollowbotPolicy.filter(message)
- end
-end
diff --git a/test/web/activity_pub/mrf/anti_link_spam_policy_test.exs b/test/web/activity_pub/mrf/anti_link_spam_policy_test.exs
deleted file mode 100644
index 6867c9853..000000000
--- a/test/web/activity_pub/mrf/anti_link_spam_policy_test.exs
+++ /dev/null
@@ -1,166 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- import ExUnit.CaptureLog
-
- alias Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy
-
- @linkless_message %{
- "type" => "Create",
- "object" => %{
- "content" => "hi world!"
- }
- }
-
- @linkful_message %{
- "type" => "Create",
- "object" => %{
- "content" => "<a href='https://example.com'>hi world!</a>"
- }
- }
-
- @response_message %{
- "type" => "Create",
- "object" => %{
- "name" => "yes",
- "type" => "Answer"
- }
- }
-
- describe "with new user" do
- test "it allows posts without links" do
- user = insert(:user, local: false)
-
- assert user.note_count == 0
-
- message =
- @linkless_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
-
- test "it disallows posts with links" do
- user = insert(:user, local: false)
-
- assert user.note_count == 0
-
- message =
- @linkful_message
- |> Map.put("actor", user.ap_id)
-
- {:reject, _} = AntiLinkSpamPolicy.filter(message)
- end
-
- test "it allows posts with links for local users" do
- user = insert(:user)
-
- assert user.note_count == 0
-
- message =
- @linkful_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
- end
-
- describe "with old user" do
- test "it allows posts without links" do
- user = insert(:user, note_count: 1)
-
- assert user.note_count == 1
-
- message =
- @linkless_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
-
- test "it allows posts with links" do
- user = insert(:user, note_count: 1)
-
- assert user.note_count == 1
-
- message =
- @linkful_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
- end
-
- describe "with followed new user" do
- test "it allows posts without links" do
- user = insert(:user, follower_count: 1)
-
- assert user.follower_count == 1
-
- message =
- @linkless_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
-
- test "it allows posts with links" do
- user = insert(:user, follower_count: 1)
-
- assert user.follower_count == 1
-
- message =
- @linkful_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
- end
-
- describe "with unknown actors" do
- setup do
- Tesla.Mock.mock(fn
- %{method: :get, url: "http://invalid.actor"} ->
- %Tesla.Env{status: 500, body: ""}
- end)
-
- :ok
- end
-
- test "it rejects posts without links" do
- message =
- @linkless_message
- |> Map.put("actor", "http://invalid.actor")
-
- assert capture_log(fn ->
- {:reject, _} = AntiLinkSpamPolicy.filter(message)
- end) =~ "[error] Could not decode user at fetch http://invalid.actor"
- end
-
- test "it rejects posts with links" do
- message =
- @linkful_message
- |> Map.put("actor", "http://invalid.actor")
-
- assert capture_log(fn ->
- {:reject, _} = AntiLinkSpamPolicy.filter(message)
- end) =~ "[error] Could not decode user at fetch http://invalid.actor"
- end
- end
-
- describe "with contentless-objects" do
- test "it does not reject them or error out" do
- user = insert(:user, note_count: 1)
-
- message =
- @response_message
- |> Map.put("actor", user.ap_id)
-
- {:ok, _message} = AntiLinkSpamPolicy.filter(message)
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/web/activity_pub/mrf/ensure_re_prepended_test.exs
deleted file mode 100644
index 9a283f27d..000000000
--- a/test/web/activity_pub/mrf/ensure_re_prepended_test.exs
+++ /dev/null
@@ -1,92 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended
-
- describe "rewrites summary" do
- test "it adds `re:` to summary object when child summary and parent summary equal" do
- message = %{
- "type" => "Create",
- "object" => %{
- "summary" => "object-summary",
- "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
- }
- }
-
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res["object"]["summary"] == "re: object-summary"
- end
-
- test "it adds `re:` to summary object when child summary containts re-subject of parent summary " do
- message = %{
- "type" => "Create",
- "object" => %{
- "summary" => "object-summary",
- "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "re: object-summary"}}}
- }
- }
-
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res["object"]["summary"] == "re: object-summary"
- end
- end
-
- describe "skip filter" do
- test "it skip if type isn't 'Create'" do
- message = %{
- "type" => "Annotation",
- "object" => %{"summary" => "object-summary"}
- }
-
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res == message
- end
-
- test "it skip if summary is empty" do
- message = %{
- "type" => "Create",
- "object" => %{
- "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "summary"}}}
- }
- }
-
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res == message
- end
-
- test "it skip if inReplyTo is empty" do
- message = %{"type" => "Create", "object" => %{"summary" => "summary"}}
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res == message
- end
-
- test "it skip if parent and child summary isn't equal" do
- message = %{
- "type" => "Create",
- "object" => %{
- "summary" => "object-summary",
- "inReplyTo" => %Activity{object: %Object{data: %{"summary" => "summary"}}}
- }
- }
-
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res == message
- end
-
- test "it skips if the object is only a reference" do
- message = %{
- "type" => "Create",
- "object" => "somereference"
- }
-
- assert {:ok, res} = EnsureRePrepended.filter(message)
- assert res == message
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/hellthread_policy_test.exs b/test/web/activity_pub/mrf/hellthread_policy_test.exs
deleted file mode 100644
index 26f5bcdaa..000000000
--- a/test/web/activity_pub/mrf/hellthread_policy_test.exs
+++ /dev/null
@@ -1,92 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- import Pleroma.Web.ActivityPub.MRF.HellthreadPolicy
-
- alias Pleroma.Web.CommonAPI
-
- setup do
- user = insert(:user)
-
- message = %{
- "actor" => user.ap_id,
- "cc" => [user.follower_address],
- "type" => "Create",
- "to" => [
- "https://www.w3.org/ns/activitystreams#Public",
- "https://instance.tld/users/user1",
- "https://instance.tld/users/user2",
- "https://instance.tld/users/user3"
- ],
- "object" => %{
- "type" => "Note"
- }
- }
-
- [user: user, message: message]
- end
-
- setup do: clear_config(:mrf_hellthread)
-
- test "doesn't die on chat messages" do
- Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0})
-
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post_chat_message(user, other_user, "moin")
-
- assert {:ok, _} = filter(activity.data)
- end
-
- describe "reject" do
- test "rejects the message if the recipient count is above reject_threshold", %{
- message: message
- } do
- Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 2})
-
- assert {:reject, "[HellthreadPolicy] 3 recipients is over the limit of 2"} ==
- filter(message)
- end
-
- test "does not reject the message if the recipient count is below reject_threshold", %{
- message: message
- } do
- Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 3})
-
- assert {:ok, ^message} = filter(message)
- end
- end
-
- describe "delist" do
- test "delists the message if the recipient count is above delist_threshold", %{
- user: user,
- message: message
- } do
- Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0})
-
- {:ok, message} = filter(message)
- assert user.follower_address in message["to"]
- assert "https://www.w3.org/ns/activitystreams#Public" in message["cc"]
- end
-
- test "does not delist the message if the recipient count is below delist_threshold", %{
- message: message
- } do
- Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 4, reject_threshold: 0})
-
- assert {:ok, ^message} = filter(message)
- end
- end
-
- test "excludes follower collection and public URI from threshold count", %{message: message} do
- Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 3})
-
- assert {:ok, ^message} = filter(message)
- end
-end
diff --git a/test/web/activity_pub/mrf/keyword_policy_test.exs b/test/web/activity_pub/mrf/keyword_policy_test.exs
deleted file mode 100644
index b3d0f3d90..000000000
--- a/test/web/activity_pub/mrf/keyword_policy_test.exs
+++ /dev/null
@@ -1,225 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.MRF.KeywordPolicy
-
- setup do: clear_config(:mrf_keyword)
-
- setup do
- Pleroma.Config.put([:mrf_keyword], %{reject: [], federated_timeline_removal: [], replace: []})
- end
-
- describe "rejecting based on keywords" do
- test "rejects if string matches in content" do
- Pleroma.Config.put([:mrf_keyword, :reject], ["pun"])
-
- message = %{
- "type" => "Create",
- "object" => %{
- "content" => "just a daily reminder that compLAINer is a good pun",
- "summary" => ""
- }
- }
-
- assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
- KeywordPolicy.filter(message)
- end
-
- test "rejects if string matches in summary" do
- Pleroma.Config.put([:mrf_keyword, :reject], ["pun"])
-
- message = %{
- "type" => "Create",
- "object" => %{
- "summary" => "just a daily reminder that compLAINer is a good pun",
- "content" => ""
- }
- }
-
- assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
- KeywordPolicy.filter(message)
- end
-
- test "rejects if regex matches in content" do
- Pleroma.Config.put([:mrf_keyword, :reject], [~r/comp[lL][aA][iI][nN]er/])
-
- assert true ==
- Enum.all?(["complainer", "compLainer", "compLAiNer", "compLAINer"], fn content ->
- message = %{
- "type" => "Create",
- "object" => %{
- "content" => "just a daily reminder that #{content} is a good pun",
- "summary" => ""
- }
- }
-
- {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
- KeywordPolicy.filter(message)
- end)
- end
-
- test "rejects if regex matches in summary" do
- Pleroma.Config.put([:mrf_keyword, :reject], [~r/comp[lL][aA][iI][nN]er/])
-
- assert true ==
- Enum.all?(["complainer", "compLainer", "compLAiNer", "compLAINer"], fn content ->
- message = %{
- "type" => "Create",
- "object" => %{
- "summary" => "just a daily reminder that #{content} is a good pun",
- "content" => ""
- }
- }
-
- {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
- KeywordPolicy.filter(message)
- end)
- end
- end
-
- describe "delisting from ftl based on keywords" do
- test "delists if string matches in content" do
- Pleroma.Config.put([:mrf_keyword, :federated_timeline_removal], ["pun"])
-
- message = %{
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "type" => "Create",
- "object" => %{
- "content" => "just a daily reminder that compLAINer is a good pun",
- "summary" => ""
- }
- }
-
- {:ok, result} = KeywordPolicy.filter(message)
- assert ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"]
- refute ["https://www.w3.org/ns/activitystreams#Public"] == result["to"]
- end
-
- test "delists if string matches in summary" do
- Pleroma.Config.put([:mrf_keyword, :federated_timeline_removal], ["pun"])
-
- message = %{
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "type" => "Create",
- "object" => %{
- "summary" => "just a daily reminder that compLAINer is a good pun",
- "content" => ""
- }
- }
-
- {:ok, result} = KeywordPolicy.filter(message)
- assert ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"]
- refute ["https://www.w3.org/ns/activitystreams#Public"] == result["to"]
- end
-
- test "delists if regex matches in content" do
- Pleroma.Config.put([:mrf_keyword, :federated_timeline_removal], [~r/comp[lL][aA][iI][nN]er/])
-
- assert true ==
- Enum.all?(["complainer", "compLainer", "compLAiNer", "compLAINer"], fn content ->
- message = %{
- "type" => "Create",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => %{
- "content" => "just a daily reminder that #{content} is a good pun",
- "summary" => ""
- }
- }
-
- {:ok, result} = KeywordPolicy.filter(message)
-
- ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"] and
- not (["https://www.w3.org/ns/activitystreams#Public"] == result["to"])
- end)
- end
-
- test "delists if regex matches in summary" do
- Pleroma.Config.put([:mrf_keyword, :federated_timeline_removal], [~r/comp[lL][aA][iI][nN]er/])
-
- assert true ==
- Enum.all?(["complainer", "compLainer", "compLAiNer", "compLAINer"], fn content ->
- message = %{
- "type" => "Create",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => %{
- "summary" => "just a daily reminder that #{content} is a good pun",
- "content" => ""
- }
- }
-
- {:ok, result} = KeywordPolicy.filter(message)
-
- ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"] and
- not (["https://www.w3.org/ns/activitystreams#Public"] == result["to"])
- end)
- end
- end
-
- describe "replacing keywords" do
- test "replaces keyword if string matches in content" do
- Pleroma.Config.put([:mrf_keyword, :replace], [{"opensource", "free software"}])
-
- message = %{
- "type" => "Create",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => %{"content" => "ZFS is opensource", "summary" => ""}
- }
-
- {:ok, %{"object" => %{"content" => result}}} = KeywordPolicy.filter(message)
- assert result == "ZFS is free software"
- end
-
- test "replaces keyword if string matches in summary" do
- Pleroma.Config.put([:mrf_keyword, :replace], [{"opensource", "free software"}])
-
- message = %{
- "type" => "Create",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => %{"summary" => "ZFS is opensource", "content" => ""}
- }
-
- {:ok, %{"object" => %{"summary" => result}}} = KeywordPolicy.filter(message)
- assert result == "ZFS is free software"
- end
-
- test "replaces keyword if regex matches in content" do
- Pleroma.Config.put([:mrf_keyword, :replace], [
- {~r/open(-|\s)?source\s?(software)?/, "free software"}
- ])
-
- assert true ==
- Enum.all?(["opensource", "open-source", "open source"], fn content ->
- message = %{
- "type" => "Create",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => %{"content" => "ZFS is #{content}", "summary" => ""}
- }
-
- {:ok, %{"object" => %{"content" => result}}} = KeywordPolicy.filter(message)
- result == "ZFS is free software"
- end)
- end
-
- test "replaces keyword if regex matches in summary" do
- Pleroma.Config.put([:mrf_keyword, :replace], [
- {~r/open(-|\s)?source\s?(software)?/, "free software"}
- ])
-
- assert true ==
- Enum.all?(["opensource", "open-source", "open source"], fn content ->
- message = %{
- "type" => "Create",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => %{"summary" => "ZFS is #{content}", "content" => ""}
- }
-
- {:ok, %{"object" => %{"summary" => result}}} = KeywordPolicy.filter(message)
- result == "ZFS is free software"
- end)
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
deleted file mode 100644
index 313d59a66..000000000
--- a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
+++ /dev/null
@@ -1,51 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
- use Pleroma.DataCase
-
- alias Pleroma.HTTP
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
-
- import Mock
-
- @message %{
- "type" => "Create",
- "object" => %{
- "type" => "Note",
- "content" => "content",
- "attachment" => [
- %{"url" => [%{"href" => "http://example.com/image.jpg"}]}
- ]
- }
- }
-
- 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
-
- test "it does nothing when no attachments are present" do
- object =
- @message["object"]
- |> Map.delete("attachment")
-
- message =
- @message
- |> Map.put("object", object)
-
- with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
- MediaProxyWarmingPolicy.filter(message)
- refute called(HTTP.get(:_, :_, :_))
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/mention_policy_test.exs b/test/web/activity_pub/mrf/mention_policy_test.exs
deleted file mode 100644
index 220309cc9..000000000
--- a/test/web/activity_pub/mrf/mention_policy_test.exs
+++ /dev/null
@@ -1,96 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.MRF.MentionPolicy
-
- setup do: clear_config(:mrf_mention)
-
- test "pass filter if allow list is empty" do
- Pleroma.Config.delete([:mrf_mention])
-
- message = %{
- "type" => "Create",
- "to" => ["https://example.com/ok"],
- "cc" => ["https://example.com/blocked"]
- }
-
- assert MentionPolicy.filter(message) == {:ok, message}
- end
-
- describe "allow" do
- test "empty" do
- Pleroma.Config.put([:mrf_mention], %{actors: ["https://example.com/blocked"]})
-
- message = %{
- "type" => "Create"
- }
-
- assert MentionPolicy.filter(message) == {:ok, message}
- end
-
- test "to" do
- Pleroma.Config.put([:mrf_mention], %{actors: ["https://example.com/blocked"]})
-
- message = %{
- "type" => "Create",
- "to" => ["https://example.com/ok"]
- }
-
- assert MentionPolicy.filter(message) == {:ok, message}
- end
-
- test "cc" do
- Pleroma.Config.put([:mrf_mention], %{actors: ["https://example.com/blocked"]})
-
- message = %{
- "type" => "Create",
- "cc" => ["https://example.com/ok"]
- }
-
- assert MentionPolicy.filter(message) == {:ok, message}
- end
-
- test "both" do
- Pleroma.Config.put([:mrf_mention], %{actors: ["https://example.com/blocked"]})
-
- message = %{
- "type" => "Create",
- "to" => ["https://example.com/ok"],
- "cc" => ["https://example.com/ok2"]
- }
-
- assert MentionPolicy.filter(message) == {:ok, message}
- end
- end
-
- describe "deny" do
- test "to" do
- Pleroma.Config.put([:mrf_mention], %{actors: ["https://example.com/blocked"]})
-
- message = %{
- "type" => "Create",
- "to" => ["https://example.com/blocked"]
- }
-
- assert MentionPolicy.filter(message) ==
- {:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"}
- end
-
- test "cc" do
- Pleroma.Config.put([:mrf_mention], %{actors: ["https://example.com/blocked"]})
-
- message = %{
- "type" => "Create",
- "to" => ["https://example.com/ok"],
- "cc" => ["https://example.com/blocked"]
- }
-
- assert MentionPolicy.filter(message) ==
- {:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"}
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/mrf_test.exs b/test/web/activity_pub/mrf/mrf_test.exs
deleted file mode 100644
index a63b25423..000000000
--- a/test/web/activity_pub/mrf/mrf_test.exs
+++ /dev/null
@@ -1,84 +0,0 @@
-defmodule Pleroma.Web.ActivityPub.MRFTest do
- use ExUnit.Case, async: true
- use Pleroma.Tests.Helpers
- alias Pleroma.Web.ActivityPub.MRF
-
- test "subdomains_regex/1" do
- assert MRF.subdomains_regex(["unsafe.tld", "*.unsafe.tld"]) == [
- ~r/^unsafe.tld$/i,
- ~r/^(.*\.)*unsafe.tld$/i
- ]
- end
-
- describe "subdomain_match/2" do
- test "common domains" do
- regexes = MRF.subdomains_regex(["unsafe.tld", "unsafe2.tld"])
-
- assert regexes == [~r/^unsafe.tld$/i, ~r/^unsafe2.tld$/i]
-
- assert MRF.subdomain_match?(regexes, "unsafe.tld")
- assert MRF.subdomain_match?(regexes, "unsafe2.tld")
-
- refute MRF.subdomain_match?(regexes, "example.com")
- end
-
- test "wildcard domains with one subdomain" do
- regexes = MRF.subdomains_regex(["*.unsafe.tld"])
-
- assert regexes == [~r/^(.*\.)*unsafe.tld$/i]
-
- assert MRF.subdomain_match?(regexes, "unsafe.tld")
- assert MRF.subdomain_match?(regexes, "sub.unsafe.tld")
- refute MRF.subdomain_match?(regexes, "anotherunsafe.tld")
- refute MRF.subdomain_match?(regexes, "unsafe.tldanother")
- end
-
- test "wildcard domains with two subdomains" do
- regexes = MRF.subdomains_regex(["*.unsafe.tld"])
-
- assert regexes == [~r/^(.*\.)*unsafe.tld$/i]
-
- assert MRF.subdomain_match?(regexes, "unsafe.tld")
- assert MRF.subdomain_match?(regexes, "sub.sub.unsafe.tld")
- refute MRF.subdomain_match?(regexes, "sub.anotherunsafe.tld")
- refute MRF.subdomain_match?(regexes, "sub.unsafe.tldanother")
- end
-
- test "matches are case-insensitive" do
- regexes = MRF.subdomains_regex(["UnSafe.TLD", "UnSAFE2.Tld"])
-
- assert regexes == [~r/^UnSafe.TLD$/i, ~r/^UnSAFE2.Tld$/i]
-
- assert MRF.subdomain_match?(regexes, "UNSAFE.TLD")
- assert MRF.subdomain_match?(regexes, "UNSAFE2.TLD")
- assert MRF.subdomain_match?(regexes, "unsafe.tld")
- assert MRF.subdomain_match?(regexes, "unsafe2.tld")
-
- refute MRF.subdomain_match?(regexes, "EXAMPLE.COM")
- refute MRF.subdomain_match?(regexes, "example.com")
- end
- end
-
- describe "describe/0" do
- test "it works as expected with noop policy" do
- expected = %{
- mrf_policies: ["NoOpPolicy"],
- exclusions: false
- }
-
- {:ok, ^expected} = MRF.describe()
- end
-
- test "it works as expected with mock policy" do
- clear_config([:mrf, :policies], [MRFModuleMock])
-
- expected = %{
- mrf_policies: ["MRFModuleMock"],
- mrf_module_mock: "some config data",
- exclusions: false
- }
-
- {:ok, ^expected} = MRF.describe()
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs b/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs
deleted file mode 100644
index 64ea61dd4..000000000
--- a/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs
+++ /dev/null
@@ -1,37 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
- use Pleroma.DataCase
- alias Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy
-
- test "it clears content object" do
- message = %{
- "type" => "Create",
- "object" => %{"content" => ".", "attachment" => "image"}
- }
-
- assert {:ok, res} = NoPlaceholderTextPolicy.filter(message)
- assert res["object"]["content"] == ""
-
- message = put_in(message, ["object", "content"], "<p>.</p>")
- assert {:ok, res} = NoPlaceholderTextPolicy.filter(message)
- assert res["object"]["content"] == ""
- end
-
- @messages [
- %{
- "type" => "Create",
- "object" => %{"content" => "test", "attachment" => "image"}
- },
- %{"type" => "Create", "object" => %{"content" => "."}},
- %{"type" => "Create", "object" => %{"content" => "<p>.</p>"}}
- ]
- test "it skips filter" do
- Enum.each(@messages, fn message ->
- assert {:ok, res} = NoPlaceholderTextPolicy.filter(message)
- assert res == message
- end)
- end
-end
diff --git a/test/web/activity_pub/mrf/normalize_markup_test.exs b/test/web/activity_pub/mrf/normalize_markup_test.exs
deleted file mode 100644
index 9b39c45bd..000000000
--- a/test/web/activity_pub/mrf/normalize_markup_test.exs
+++ /dev/null
@@ -1,42 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
- use Pleroma.DataCase
- alias Pleroma.Web.ActivityPub.MRF.NormalizeMarkup
-
- @html_sample """
- <b>this is in bold</b>
- <p>this is a paragraph</p>
- this is a linebreak<br />
- this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
- this is a link with not allowed "rel" attribute: <a href="http://example.com/" rel="tag noallowed">example.com</a>
- this is an image: <img src="http://example.com/image.jpg"><br />
- <script>alert('hacked')</script>
- """
-
- test "it filter html tags" do
- expected = """
- <b>this is in bold</b>
- <p>this is a paragraph</p>
- this is a linebreak<br/>
- this is a link with allowed &quot;rel&quot; attribute: <a href="http://example.com/" rel="tag">example.com</a>
- this is a link with not allowed &quot;rel&quot; attribute: <a href="http://example.com/">example.com</a>
- this is an image: <img src="http://example.com/image.jpg"/><br/>
- alert(&#39;hacked&#39;)
- """
-
- message = %{"type" => "Create", "object" => %{"content" => @html_sample}}
-
- assert {:ok, res} = NormalizeMarkup.filter(message)
- assert res["object"]["content"] == expected
- end
-
- test "it skips filter if type isn't `Create`" do
- message = %{"type" => "Note", "object" => %{}}
-
- assert {:ok, res} = NormalizeMarkup.filter(message)
- assert res == message
- end
-end
diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs
deleted file mode 100644
index cf6acc9a2..000000000
--- a/test/web/activity_pub/mrf/object_age_policy_test.exs
+++ /dev/null
@@ -1,148 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
- use Pleroma.DataCase
- alias Pleroma.Config
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy
- alias Pleroma.Web.ActivityPub.Visibility
-
- setup do:
- clear_config(:mrf_object_age,
- threshold: 172_800,
- actions: [:delist, :strip_followers]
- )
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- defp get_old_message do
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
- end
-
- defp get_new_message do
- old_message = get_old_message()
-
- new_object =
- old_message
- |> Map.get("object")
- |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
-
- old_message
- |> Map.put("object", new_object)
- end
-
- describe "with reject action" do
- test "works with objects with empty to or cc fields" do
- Config.put([:mrf_object_age, :actions], [:reject])
-
- data =
- get_old_message()
- |> Map.put("cc", nil)
- |> Map.put("to", nil)
-
- assert match?({:reject, _}, ObjectAgePolicy.filter(data))
- end
-
- test "it rejects an old post" do
- Config.put([:mrf_object_age, :actions], [:reject])
-
- data = get_old_message()
-
- assert match?({:reject, _}, ObjectAgePolicy.filter(data))
- end
-
- test "it allows a new post" do
- Config.put([:mrf_object_age, :actions], [:reject])
-
- data = get_new_message()
-
- assert match?({:ok, _}, ObjectAgePolicy.filter(data))
- end
- end
-
- describe "with delist action" do
- test "works with objects with empty to or cc fields" do
- Config.put([:mrf_object_age, :actions], [:delist])
-
- data =
- get_old_message()
- |> Map.put("cc", nil)
- |> Map.put("to", nil)
-
- {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
-
- {:ok, data} = ObjectAgePolicy.filter(data)
-
- assert Visibility.get_visibility(%{data: data}) == "unlisted"
- end
-
- test "it delists an old post" do
- Config.put([:mrf_object_age, :actions], [:delist])
-
- data = get_old_message()
-
- {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
-
- {:ok, data} = ObjectAgePolicy.filter(data)
-
- assert Visibility.get_visibility(%{data: data}) == "unlisted"
- end
-
- test "it allows a new post" do
- Config.put([:mrf_object_age, :actions], [:delist])
-
- data = get_new_message()
-
- {:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"])
-
- assert match?({:ok, ^data}, ObjectAgePolicy.filter(data))
- end
- end
-
- describe "with strip_followers action" do
- test "works with objects with empty to or cc fields" do
- Config.put([:mrf_object_age, :actions], [:strip_followers])
-
- data =
- get_old_message()
- |> Map.put("cc", nil)
- |> Map.put("to", nil)
-
- {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
-
- {:ok, data} = ObjectAgePolicy.filter(data)
-
- refute user.follower_address in data["to"]
- refute user.follower_address in data["cc"]
- end
-
- test "it strips followers collections from an old post" do
- Config.put([:mrf_object_age, :actions], [:strip_followers])
-
- data = get_old_message()
-
- {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
-
- {:ok, data} = ObjectAgePolicy.filter(data)
-
- refute user.follower_address in data["to"]
- refute user.follower_address in data["cc"]
- end
-
- test "it allows a new post" do
- Config.put([:mrf_object_age, :actions], [:strip_followers])
-
- data = get_new_message()
-
- {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
-
- assert match?({:ok, ^data}, ObjectAgePolicy.filter(data))
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/reject_non_public_test.exs b/test/web/activity_pub/mrf/reject_non_public_test.exs
deleted file mode 100644
index 58b46b9a2..000000000
--- a/test/web/activity_pub/mrf/reject_non_public_test.exs
+++ /dev/null
@@ -1,100 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.Web.ActivityPub.MRF.RejectNonPublic
-
- setup do: clear_config([:mrf_rejectnonpublic])
-
- describe "public message" do
- test "it's allowed when address is public" do
- actor = insert(:user, follower_address: "test-address")
-
- message = %{
- "actor" => actor.ap_id,
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "type" => "Create"
- }
-
- assert {:ok, message} = RejectNonPublic.filter(message)
- end
-
- test "it's allowed when cc address contain public address" do
- actor = insert(:user, follower_address: "test-address")
-
- message = %{
- "actor" => actor.ap_id,
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "type" => "Create"
- }
-
- assert {:ok, message} = RejectNonPublic.filter(message)
- end
- end
-
- describe "followers message" do
- test "it's allowed when addrer of message in the follower addresses of user and it enabled in config" do
- actor = insert(:user, follower_address: "test-address")
-
- message = %{
- "actor" => actor.ap_id,
- "to" => ["test-address"],
- "cc" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "type" => "Create"
- }
-
- Pleroma.Config.put([:mrf_rejectnonpublic, :allow_followersonly], true)
- assert {:ok, message} = RejectNonPublic.filter(message)
- end
-
- test "it's rejected when addrer of message in the follower addresses of user and it disabled in config" do
- actor = insert(:user, follower_address: "test-address")
-
- message = %{
- "actor" => actor.ap_id,
- "to" => ["test-address"],
- "cc" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "type" => "Create"
- }
-
- Pleroma.Config.put([:mrf_rejectnonpublic, :allow_followersonly], false)
- assert {:reject, _} = RejectNonPublic.filter(message)
- end
- end
-
- describe "direct message" do
- test "it's allows when direct messages are allow" do
- actor = insert(:user)
-
- message = %{
- "actor" => actor.ap_id,
- "to" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "cc" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "type" => "Create"
- }
-
- Pleroma.Config.put([:mrf_rejectnonpublic, :allow_direct], true)
- assert {:ok, message} = RejectNonPublic.filter(message)
- end
-
- test "it's reject when direct messages aren't allow" do
- actor = insert(:user)
-
- message = %{
- "actor" => actor.ap_id,
- "to" => ["https://www.w3.org/ns/activitystreams#Publid~~~"],
- "cc" => ["https://www.w3.org/ns/activitystreams#Publid"],
- "type" => "Create"
- }
-
- Pleroma.Config.put([:mrf_rejectnonpublic, :allow_direct], false)
- assert {:reject, _} = RejectNonPublic.filter(message)
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs
deleted file mode 100644
index d7dde62c4..000000000
--- a/test/web/activity_pub/mrf/simple_policy_test.exs
+++ /dev/null
@@ -1,539 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Config
- alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
- alias Pleroma.Web.CommonAPI
-
- setup do:
- clear_config(:mrf_simple,
- media_removal: [],
- media_nsfw: [],
- federated_timeline_removal: [],
- report_removal: [],
- reject: [],
- followers_only: [],
- accept: [],
- avatar_removal: [],
- banner_removal: [],
- reject_deletes: []
- )
-
- describe "when :media_removal" do
- test "is empty" do
- Config.put([:mrf_simple, :media_removal], [])
- media_message = build_media_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(media_message) == {:ok, media_message}
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "has a matching host" do
- Config.put([:mrf_simple, :media_removal], ["remote.instance"])
- media_message = build_media_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(media_message) ==
- {:ok,
- media_message
- |> Map.put("object", Map.delete(media_message["object"], "attachment"))}
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "match with wildcard domain" do
- Config.put([:mrf_simple, :media_removal], ["*.remote.instance"])
- media_message = build_media_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(media_message) ==
- {:ok,
- media_message
- |> Map.put("object", Map.delete(media_message["object"], "attachment"))}
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
- end
-
- describe "when :media_nsfw" do
- test "is empty" do
- Config.put([:mrf_simple, :media_nsfw], [])
- media_message = build_media_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(media_message) == {:ok, media_message}
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "has a matching host" do
- Config.put([:mrf_simple, :media_nsfw], ["remote.instance"])
- media_message = build_media_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(media_message) ==
- {:ok,
- media_message
- |> put_in(["object", "tag"], ["foo", "nsfw"])
- |> put_in(["object", "sensitive"], true)}
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "match with wildcard domain" do
- Config.put([:mrf_simple, :media_nsfw], ["*.remote.instance"])
- media_message = build_media_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(media_message) ==
- {:ok,
- media_message
- |> put_in(["object", "tag"], ["foo", "nsfw"])
- |> put_in(["object", "sensitive"], true)}
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
- end
-
- defp build_media_message do
- %{
- "actor" => "https://remote.instance/users/bob",
- "type" => "Create",
- "object" => %{
- "attachment" => [%{}],
- "tag" => ["foo"],
- "sensitive" => false
- }
- }
- end
-
- describe "when :report_removal" do
- test "is empty" do
- Config.put([:mrf_simple, :report_removal], [])
- report_message = build_report_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(report_message) == {:ok, report_message}
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "has a matching host" do
- Config.put([:mrf_simple, :report_removal], ["remote.instance"])
- report_message = build_report_message()
- local_message = build_local_message()
-
- assert {:reject, _} = SimplePolicy.filter(report_message)
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "match with wildcard domain" do
- Config.put([:mrf_simple, :report_removal], ["*.remote.instance"])
- report_message = build_report_message()
- local_message = build_local_message()
-
- assert {:reject, _} = SimplePolicy.filter(report_message)
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
- end
-
- defp build_report_message do
- %{
- "actor" => "https://remote.instance/users/bob",
- "type" => "Flag"
- }
- end
-
- describe "when :federated_timeline_removal" do
- test "is empty" do
- Config.put([:mrf_simple, :federated_timeline_removal], [])
- {_, ftl_message} = build_ftl_actor_and_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "has a matching host" do
- {actor, ftl_message} = build_ftl_actor_and_message()
-
- ftl_message_actor_host =
- ftl_message
- |> Map.fetch!("actor")
- |> URI.parse()
- |> Map.fetch!(:host)
-
- Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host])
- local_message = build_local_message()
-
- assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
- assert actor.follower_address in ftl_message["to"]
- refute actor.follower_address in ftl_message["cc"]
- refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
- assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "match with wildcard domain" do
- {actor, ftl_message} = build_ftl_actor_and_message()
-
- ftl_message_actor_host =
- ftl_message
- |> Map.fetch!("actor")
- |> URI.parse()
- |> Map.fetch!(:host)
-
- Config.put([:mrf_simple, :federated_timeline_removal], ["*." <> ftl_message_actor_host])
- local_message = build_local_message()
-
- assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
- assert actor.follower_address in ftl_message["to"]
- refute actor.follower_address in ftl_message["cc"]
- refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
- assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "has a matching host but only as:Public in to" do
- {_actor, ftl_message} = build_ftl_actor_and_message()
-
- ftl_message_actor_host =
- ftl_message
- |> Map.fetch!("actor")
- |> URI.parse()
- |> Map.fetch!(:host)
-
- ftl_message = Map.put(ftl_message, "cc", [])
-
- Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host])
-
- assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
- refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
- assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
- end
- end
-
- defp build_ftl_actor_and_message do
- actor = insert(:user)
-
- {actor,
- %{
- "actor" => actor.ap_id,
- "to" => ["https://www.w3.org/ns/activitystreams#Public", "http://foo.bar/baz"],
- "cc" => [actor.follower_address, "http://foo.bar/qux"]
- }}
- end
-
- describe "when :reject" do
- test "is empty" do
- Config.put([:mrf_simple, :reject], [])
-
- remote_message = build_remote_message()
-
- assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
- end
-
- test "activity has a matching host" do
- Config.put([:mrf_simple, :reject], ["remote.instance"])
-
- remote_message = build_remote_message()
-
- assert {:reject, _} = SimplePolicy.filter(remote_message)
- end
-
- test "activity matches with wildcard domain" do
- Config.put([:mrf_simple, :reject], ["*.remote.instance"])
-
- remote_message = build_remote_message()
-
- assert {:reject, _} = SimplePolicy.filter(remote_message)
- end
-
- test "actor has a matching host" do
- Config.put([:mrf_simple, :reject], ["remote.instance"])
-
- remote_user = build_remote_user()
-
- assert {:reject, _} = SimplePolicy.filter(remote_user)
- end
- end
-
- describe "when :followers_only" do
- test "is empty" do
- Config.put([:mrf_simple, :followers_only], [])
- {_, ftl_message} = build_ftl_actor_and_message()
- local_message = build_local_message()
-
- assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- end
-
- test "has a matching host" do
- actor = insert(:user)
- following_user = insert(:user)
- non_following_user = insert(:user)
-
- {:ok, _, _, _} = CommonAPI.follow(following_user, actor)
-
- activity = %{
- "actor" => actor.ap_id,
- "to" => [
- "https://www.w3.org/ns/activitystreams#Public",
- following_user.ap_id,
- non_following_user.ap_id
- ],
- "cc" => [actor.follower_address, "http://foo.bar/qux"]
- }
-
- dm_activity = %{
- "actor" => actor.ap_id,
- "to" => [
- following_user.ap_id,
- non_following_user.ap_id
- ],
- "cc" => []
- }
-
- actor_domain =
- activity
- |> Map.fetch!("actor")
- |> URI.parse()
- |> Map.fetch!(:host)
-
- Config.put([:mrf_simple, :followers_only], [actor_domain])
-
- assert {:ok, new_activity} = SimplePolicy.filter(activity)
- assert actor.follower_address in new_activity["cc"]
- assert following_user.ap_id in new_activity["to"]
- refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["to"]
- refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["cc"]
- refute non_following_user.ap_id in new_activity["to"]
- refute non_following_user.ap_id in new_activity["cc"]
-
- assert {:ok, new_dm_activity} = SimplePolicy.filter(dm_activity)
- assert new_dm_activity["to"] == [following_user.ap_id]
- assert new_dm_activity["cc"] == []
- end
- end
-
- describe "when :accept" do
- test "is empty" do
- Config.put([:mrf_simple, :accept], [])
-
- local_message = build_local_message()
- remote_message = build_remote_message()
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
- end
-
- test "is not empty but activity doesn't have a matching host" do
- Config.put([:mrf_simple, :accept], ["non.matching.remote"])
-
- local_message = build_local_message()
- remote_message = build_remote_message()
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- assert {:reject, _} = SimplePolicy.filter(remote_message)
- end
-
- test "activity has a matching host" do
- Config.put([:mrf_simple, :accept], ["remote.instance"])
-
- local_message = build_local_message()
- remote_message = build_remote_message()
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
- end
-
- test "activity matches with wildcard domain" do
- Config.put([:mrf_simple, :accept], ["*.remote.instance"])
-
- local_message = build_local_message()
- remote_message = build_remote_message()
-
- assert SimplePolicy.filter(local_message) == {:ok, local_message}
- assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
- end
-
- test "actor has a matching host" do
- Config.put([:mrf_simple, :accept], ["remote.instance"])
-
- remote_user = build_remote_user()
-
- assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
- end
- end
-
- describe "when :avatar_removal" do
- test "is empty" do
- Config.put([:mrf_simple, :avatar_removal], [])
-
- remote_user = build_remote_user()
-
- assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
- end
-
- test "is not empty but it doesn't have a matching host" do
- Config.put([:mrf_simple, :avatar_removal], ["non.matching.remote"])
-
- remote_user = build_remote_user()
-
- assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
- end
-
- test "has a matching host" do
- Config.put([:mrf_simple, :avatar_removal], ["remote.instance"])
-
- remote_user = build_remote_user()
- {:ok, filtered} = SimplePolicy.filter(remote_user)
-
- refute filtered["icon"]
- end
-
- test "match with wildcard domain" do
- Config.put([:mrf_simple, :avatar_removal], ["*.remote.instance"])
-
- remote_user = build_remote_user()
- {:ok, filtered} = SimplePolicy.filter(remote_user)
-
- refute filtered["icon"]
- end
- end
-
- describe "when :banner_removal" do
- test "is empty" do
- Config.put([:mrf_simple, :banner_removal], [])
-
- remote_user = build_remote_user()
-
- assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
- end
-
- test "is not empty but it doesn't have a matching host" do
- Config.put([:mrf_simple, :banner_removal], ["non.matching.remote"])
-
- remote_user = build_remote_user()
-
- assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
- end
-
- test "has a matching host" do
- Config.put([:mrf_simple, :banner_removal], ["remote.instance"])
-
- remote_user = build_remote_user()
- {:ok, filtered} = SimplePolicy.filter(remote_user)
-
- refute filtered["image"]
- end
-
- test "match with wildcard domain" do
- Config.put([:mrf_simple, :banner_removal], ["*.remote.instance"])
-
- remote_user = build_remote_user()
- {:ok, filtered} = SimplePolicy.filter(remote_user)
-
- refute filtered["image"]
- end
- end
-
- describe "when :reject_deletes is empty" do
- setup do: Config.put([:mrf_simple, :reject_deletes], [])
-
- test "it accepts deletions even from rejected servers" do
- Config.put([:mrf_simple, :reject], ["remote.instance"])
-
- deletion_message = build_remote_deletion_message()
-
- assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
- end
-
- test "it accepts deletions even from non-whitelisted servers" do
- Config.put([:mrf_simple, :accept], ["non.matching.remote"])
-
- deletion_message = build_remote_deletion_message()
-
- assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
- end
- end
-
- describe "when :reject_deletes is not empty but it doesn't have a matching host" do
- setup do: Config.put([:mrf_simple, :reject_deletes], ["non.matching.remote"])
-
- test "it accepts deletions even from rejected servers" do
- Config.put([:mrf_simple, :reject], ["remote.instance"])
-
- deletion_message = build_remote_deletion_message()
-
- assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
- end
-
- test "it accepts deletions even from non-whitelisted servers" do
- Config.put([:mrf_simple, :accept], ["non.matching.remote"])
-
- deletion_message = build_remote_deletion_message()
-
- assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
- end
- end
-
- describe "when :reject_deletes has a matching host" do
- setup do: Config.put([:mrf_simple, :reject_deletes], ["remote.instance"])
-
- test "it rejects the deletion" do
- deletion_message = build_remote_deletion_message()
-
- assert {:reject, _} = SimplePolicy.filter(deletion_message)
- end
- end
-
- describe "when :reject_deletes match with wildcard domain" do
- setup do: Config.put([:mrf_simple, :reject_deletes], ["*.remote.instance"])
-
- test "it rejects the deletion" do
- deletion_message = build_remote_deletion_message()
-
- assert {:reject, _} = SimplePolicy.filter(deletion_message)
- end
- end
-
- defp build_local_message do
- %{
- "actor" => "#{Pleroma.Web.base_url()}/users/alice",
- "to" => [],
- "cc" => []
- }
- end
-
- defp build_remote_message do
- %{"actor" => "https://remote.instance/users/bob"}
- end
-
- defp build_remote_user do
- %{
- "id" => "https://remote.instance/users/bob",
- "icon" => %{
- "url" => "http://example.com/image.jpg",
- "type" => "Image"
- },
- "image" => %{
- "url" => "http://example.com/image.jpg",
- "type" => "Image"
- },
- "type" => "Person"
- }
- end
-
- defp build_remote_deletion_message do
- %{
- "type" => "Delete",
- "actor" => "https://remote.instance/users/bob"
- }
- end
-end
diff --git a/test/web/activity_pub/mrf/steal_emoji_policy_test.exs b/test/web/activity_pub/mrf/steal_emoji_policy_test.exs
deleted file mode 100644
index 3f8222736..000000000
--- a/test/web/activity_pub/mrf/steal_emoji_policy_test.exs
+++ /dev/null
@@ -1,68 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
- use Pleroma.DataCase
-
- alias Pleroma.Config
- alias Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup do
- emoji_path = Path.join(Config.get([:instance, :static_dir]), "emoji/stolen")
- File.rm_rf!(emoji_path)
- File.mkdir!(emoji_path)
-
- Pleroma.Emoji.reload()
-
- on_exit(fn ->
- File.rm_rf!(emoji_path)
- end)
-
- :ok
- end
-
- test "does nothing by default" do
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- refute "firedfox" in installed_emoji
-
- message = %{
- "type" => "Create",
- "object" => %{
- "emoji" => [{"firedfox", "https://example.org/emoji/firedfox.png"}],
- "actor" => "https://example.org/users/admin"
- }
- }
-
- assert {:ok, message} == StealEmojiPolicy.filter(message)
-
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- refute "firedfox" in installed_emoji
- end
-
- test "Steals emoji on unknown shortcode from allowed remote host" do
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- refute "firedfox" in installed_emoji
-
- message = %{
- "type" => "Create",
- "object" => %{
- "emoji" => [{"firedfox", "https://example.org/emoji/firedfox.png"}],
- "actor" => "https://example.org/users/admin"
- }
- }
-
- clear_config([:mrf_steal_emoji, :hosts], ["example.org"])
- clear_config([:mrf_steal_emoji, :size_limit], 284_468)
-
- assert {:ok, message} == StealEmojiPolicy.filter(message)
-
- installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
- assert "firedfox" in installed_emoji
- end
-end
diff --git a/test/web/activity_pub/mrf/subchain_policy_test.exs b/test/web/activity_pub/mrf/subchain_policy_test.exs
deleted file mode 100644
index fff66cb7e..000000000
--- a/test/web/activity_pub/mrf/subchain_policy_test.exs
+++ /dev/null
@@ -1,33 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicyTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.MRF.DropPolicy
- alias Pleroma.Web.ActivityPub.MRF.SubchainPolicy
-
- @message %{
- "actor" => "https://banned.com",
- "type" => "Create",
- "object" => %{"content" => "hi"}
- }
- setup do: clear_config([:mrf_subchain, :match_actor])
-
- test "it matches and processes subchains when the actor matches a configured target" do
- Pleroma.Config.put([:mrf_subchain, :match_actor], %{
- ~r/^https:\/\/banned.com/s => [DropPolicy]
- })
-
- {:reject, _} = SubchainPolicy.filter(@message)
- end
-
- test "it doesn't match and process subchains when the actor doesn't match a configured target" do
- Pleroma.Config.put([:mrf_subchain, :match_actor], %{
- ~r/^https:\/\/borked.com/s => [DropPolicy]
- })
-
- {:ok, _message} = SubchainPolicy.filter(@message)
- end
-end
diff --git a/test/web/activity_pub/mrf/tag_policy_test.exs b/test/web/activity_pub/mrf/tag_policy_test.exs
deleted file mode 100644
index 6ff71d640..000000000
--- a/test/web/activity_pub/mrf/tag_policy_test.exs
+++ /dev/null
@@ -1,123 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.Web.ActivityPub.MRF.TagPolicy
- @public "https://www.w3.org/ns/activitystreams#Public"
-
- describe "mrf_tag:disable-any-subscription" do
- test "rejects message" do
- actor = insert(:user, tags: ["mrf_tag:disable-any-subscription"])
- message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => actor.ap_id}
- assert {:reject, _} = TagPolicy.filter(message)
- end
- end
-
- describe "mrf_tag:disable-remote-subscription" do
- test "rejects non-local follow requests" do
- actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"])
- follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: false)
- message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id}
- assert {:reject, _} = TagPolicy.filter(message)
- end
-
- test "allows non-local follow requests" do
- actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"])
- follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: true)
- message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id}
- assert {:ok, message} = TagPolicy.filter(message)
- end
- end
-
- describe "mrf_tag:sandbox" do
- test "removes from public timelines" do
- actor = insert(:user, tags: ["mrf_tag:sandbox"])
-
- message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{},
- "to" => [@public, "f"],
- "cc" => [@public, "d"]
- }
-
- except_message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d"]},
- "to" => ["f", actor.follower_address],
- "cc" => ["d"]
- }
-
- assert TagPolicy.filter(message) == {:ok, except_message}
- end
- end
-
- describe "mrf_tag:force-unlisted" do
- test "removes from the federated timeline" do
- actor = insert(:user, tags: ["mrf_tag:force-unlisted"])
-
- message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{},
- "to" => [@public, "f"],
- "cc" => [actor.follower_address, "d"]
- }
-
- except_message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d", @public]},
- "to" => ["f", actor.follower_address],
- "cc" => ["d", @public]
- }
-
- assert TagPolicy.filter(message) == {:ok, except_message}
- end
- end
-
- describe "mrf_tag:media-strip" do
- test "removes attachments" do
- actor = insert(:user, tags: ["mrf_tag:media-strip"])
-
- message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{"attachment" => ["file1"]}
- }
-
- except_message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{}
- }
-
- assert TagPolicy.filter(message) == {:ok, except_message}
- end
- end
-
- describe "mrf_tag:media-force-nsfw" do
- test "Mark as sensitive on presence of attachments" do
- actor = insert(:user, tags: ["mrf_tag:media-force-nsfw"])
-
- message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{"tag" => ["test"], "attachment" => ["file1"]}
- }
-
- except_message = %{
- "actor" => actor.ap_id,
- "type" => "Create",
- "object" => %{"tag" => ["test", "nsfw"], "attachment" => ["file1"], "sensitive" => true}
- }
-
- assert TagPolicy.filter(message) == {:ok, except_message}
- end
- end
-end
diff --git a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs
deleted file mode 100644
index 8e1ad5bc8..000000000
--- a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs
+++ /dev/null
@@ -1,31 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy
-
- setup do: clear_config(:mrf_user_allowlist)
-
- test "pass filter if allow list is empty" do
- actor = insert(:user)
- message = %{"actor" => actor.ap_id}
- assert UserAllowListPolicy.filter(message) == {:ok, message}
- end
-
- test "pass filter if allow list isn't empty and user in allow list" do
- actor = insert(:user)
- Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => [actor.ap_id, "test-ap-id"]})
- message = %{"actor" => actor.ap_id}
- assert UserAllowListPolicy.filter(message) == {:ok, message}
- end
-
- test "rejected if allow list isn't empty and user not in allow list" do
- actor = insert(:user)
- Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => ["test-ap-id"]})
- message = %{"actor" => actor.ap_id}
- assert {:reject, _} = UserAllowListPolicy.filter(message)
- end
-end
diff --git a/test/web/activity_pub/mrf/vocabulary_policy_test.exs b/test/web/activity_pub/mrf/vocabulary_policy_test.exs
deleted file mode 100644
index 2bceb67ee..000000000
--- a/test/web/activity_pub/mrf/vocabulary_policy_test.exs
+++ /dev/null
@@ -1,106 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.MRF.VocabularyPolicy
-
- describe "accept" do
- setup do: clear_config([:mrf_vocabulary, :accept])
-
- test "it accepts based on parent activity type" do
- Pleroma.Config.put([:mrf_vocabulary, :accept], ["Like"])
-
- message = %{
- "type" => "Like",
- "object" => "whatever"
- }
-
- {:ok, ^message} = VocabularyPolicy.filter(message)
- end
-
- test "it accepts based on child object type" do
- Pleroma.Config.put([:mrf_vocabulary, :accept], ["Create", "Note"])
-
- message = %{
- "type" => "Create",
- "object" => %{
- "type" => "Note",
- "content" => "whatever"
- }
- }
-
- {:ok, ^message} = VocabularyPolicy.filter(message)
- end
-
- test "it does not accept disallowed child objects" do
- Pleroma.Config.put([:mrf_vocabulary, :accept], ["Create", "Note"])
-
- message = %{
- "type" => "Create",
- "object" => %{
- "type" => "Article",
- "content" => "whatever"
- }
- }
-
- {:reject, _} = VocabularyPolicy.filter(message)
- end
-
- test "it does not accept disallowed parent types" do
- Pleroma.Config.put([:mrf_vocabulary, :accept], ["Announce", "Note"])
-
- message = %{
- "type" => "Create",
- "object" => %{
- "type" => "Note",
- "content" => "whatever"
- }
- }
-
- {:reject, _} = VocabularyPolicy.filter(message)
- end
- end
-
- describe "reject" do
- setup do: clear_config([:mrf_vocabulary, :reject])
-
- test "it rejects based on parent activity type" do
- Pleroma.Config.put([:mrf_vocabulary, :reject], ["Like"])
-
- message = %{
- "type" => "Like",
- "object" => "whatever"
- }
-
- {:reject, _} = VocabularyPolicy.filter(message)
- end
-
- test "it rejects based on child object type" do
- Pleroma.Config.put([:mrf_vocabulary, :reject], ["Note"])
-
- message = %{
- "type" => "Create",
- "object" => %{
- "type" => "Note",
- "content" => "whatever"
- }
- }
-
- {:reject, _} = VocabularyPolicy.filter(message)
- end
-
- test "it passes through objects that aren't disallowed" do
- Pleroma.Config.put([:mrf_vocabulary, :reject], ["Like"])
-
- message = %{
- "type" => "Announce",
- "object" => "whatever"
- }
-
- {:ok, ^message} = VocabularyPolicy.filter(message)
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/accept_validation_test.exs b/test/web/activity_pub/object_validators/accept_validation_test.exs
deleted file mode 100644
index d6111ba41..000000000
--- a/test/web/activity_pub/object_validators/accept_validation_test.exs
+++ /dev/null
@@ -1,56 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.ActivityPub.Pipeline
-
- import Pleroma.Factory
-
- setup do
- follower = insert(:user)
- followed = insert(:user, local: false)
-
- {:ok, follow_data, _} = Builder.follow(follower, followed)
- {:ok, follow_activity, _} = Pipeline.common_pipeline(follow_data, local: true)
-
- {:ok, accept_data, _} = Builder.accept(followed, follow_activity)
-
- %{accept_data: accept_data, followed: followed}
- end
-
- test "it validates a basic 'accept'", %{accept_data: accept_data} do
- assert {:ok, _, _} = ObjectValidator.validate(accept_data, [])
- end
-
- test "it fails when the actor doesn't exist", %{accept_data: accept_data} do
- accept_data =
- accept_data
- |> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
-
- assert {:error, _} = ObjectValidator.validate(accept_data, [])
- end
-
- test "it fails when the accepted activity doesn't exist", %{accept_data: accept_data} do
- accept_data =
- accept_data
- |> Map.put("object", "https://gensokyo.2hu/users/raymoo/follows/1")
-
- assert {:error, _} = ObjectValidator.validate(accept_data, [])
- end
-
- test "for an accepted follow, it only validates if the actor of the accept is the followed actor",
- %{accept_data: accept_data} do
- stranger = insert(:user)
-
- accept_data =
- accept_data
- |> Map.put("actor", stranger.ap_id)
-
- assert {:error, _} = ObjectValidator.validate(accept_data, [])
- end
-end
diff --git a/test/web/activity_pub/object_validators/announce_validation_test.exs b/test/web/activity_pub/object_validators/announce_validation_test.exs
deleted file mode 100644
index 623342f76..000000000
--- a/test/web/activity_pub/object_validators/announce_validation_test.exs
+++ /dev/null
@@ -1,106 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnouncValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "announces" do
- setup do
- user = insert(:user)
- announcer = insert(:user)
- {:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
-
- object = Object.normalize(post_activity, false)
- {:ok, valid_announce, []} = Builder.announce(announcer, object)
-
- %{
- valid_announce: valid_announce,
- user: user,
- post_activity: post_activity,
- announcer: announcer
- }
- end
-
- test "returns ok for a valid announce", %{valid_announce: valid_announce} do
- assert {:ok, _object, _meta} = ObjectValidator.validate(valid_announce, [])
- end
-
- test "returns an error if the object can't be found", %{valid_announce: valid_announce} do
- without_object =
- valid_announce
- |> Map.delete("object")
-
- {:error, cng} = ObjectValidator.validate(without_object, [])
-
- assert {:object, {"can't be blank", [validation: :required]}} in cng.errors
-
- nonexisting_object =
- valid_announce
- |> Map.put("object", "https://gensokyo.2hu/objects/99999999")
-
- {:error, cng} = ObjectValidator.validate(nonexisting_object, [])
-
- assert {:object, {"can't find object", []}} in cng.errors
- end
-
- test "returns an error if we don't have the actor", %{valid_announce: valid_announce} do
- nonexisting_actor =
- valid_announce
- |> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
-
- {:error, cng} = ObjectValidator.validate(nonexisting_actor, [])
-
- assert {:actor, {"can't find user", []}} in cng.errors
- end
-
- test "returns an error if the actor already announced the object", %{
- valid_announce: valid_announce,
- announcer: announcer,
- post_activity: post_activity
- } do
- _announce = CommonAPI.repeat(post_activity.id, announcer)
-
- {:error, cng} = ObjectValidator.validate(valid_announce, [])
-
- assert {:actor, {"already announced this object", []}} in cng.errors
- assert {:object, {"already announced by this actor", []}} in cng.errors
- end
-
- test "returns an error if the actor can't announce the object", %{
- announcer: announcer,
- user: user
- } do
- {:ok, post_activity} =
- CommonAPI.post(user, %{status: "a secret post", visibility: "private"})
-
- object = Object.normalize(post_activity, false)
-
- # Another user can't announce it
- {:ok, announce, []} = Builder.announce(announcer, object, public: false)
-
- {:error, cng} = ObjectValidator.validate(announce, [])
-
- assert {:actor, {"can not announce this object", []}} in cng.errors
-
- # The actor of the object can announce it
- {:ok, announce, []} = Builder.announce(user, object, public: false)
-
- assert {:ok, _, _} = ObjectValidator.validate(announce, [])
-
- # The actor of the object can not announce it publicly
- {:ok, announce, []} = Builder.announce(user, object, public: true)
-
- {:error, cng} = ObjectValidator.validate(announce, [])
-
- assert {:actor, {"can not announce this object publicly", []}} in cng.errors
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/attachment_validator_test.exs b/test/web/activity_pub/object_validators/attachment_validator_test.exs
deleted file mode 100644
index 558bb3131..000000000
--- a/test/web/activity_pub/object_validators/attachment_validator_test.exs
+++ /dev/null
@@ -1,74 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
-
- import Pleroma.Factory
-
- describe "attachments" do
- test "works with honkerific attachments" do
- attachment = %{
- "mediaType" => "",
- "name" => "",
- "summary" => "298p3RG7j27tfsZ9RQ.jpg",
- "type" => "Document",
- "url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
- }
-
- assert {:ok, attachment} =
- AttachmentValidator.cast_and_validate(attachment)
- |> Ecto.Changeset.apply_action(:insert)
-
- assert attachment.mediaType == "application/octet-stream"
- end
-
- test "it turns mastodon attachments into our attachments" do
- attachment = %{
- "url" =>
- "http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
- "type" => "Document",
- "name" => nil,
- "mediaType" => "image/jpeg"
- }
-
- {:ok, attachment} =
- AttachmentValidator.cast_and_validate(attachment)
- |> Ecto.Changeset.apply_action(:insert)
-
- assert [
- %{
- href:
- "http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
- type: "Link",
- mediaType: "image/jpeg"
- }
- ] = attachment.url
-
- assert attachment.mediaType == "image/jpeg"
- end
-
- test "it handles our own uploads" do
- user = insert(:user)
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
-
- {:ok, attachment} =
- attachment.data
- |> AttachmentValidator.cast_and_validate()
- |> Ecto.Changeset.apply_action(:insert)
-
- assert attachment.mediaType == "image/jpeg"
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/block_validation_test.exs b/test/web/activity_pub/object_validators/block_validation_test.exs
deleted file mode 100644
index c08d4b2e8..000000000
--- a/test/web/activity_pub/object_validators/block_validation_test.exs
+++ /dev/null
@@ -1,39 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.BlockValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
-
- import Pleroma.Factory
-
- describe "blocks" do
- setup do
- user = insert(:user, local: false)
- blocked = insert(:user)
-
- {:ok, valid_block, []} = Builder.block(user, blocked)
-
- %{user: user, valid_block: valid_block}
- end
-
- test "validates a basic object", %{
- valid_block: valid_block
- } do
- assert {:ok, _block, []} = ObjectValidator.validate(valid_block, [])
- end
-
- test "returns an error if we don't know the blocked user", %{
- valid_block: valid_block
- } do
- block =
- valid_block
- |> Map.put("object", "https://gensokyo.2hu/users/raymoo")
-
- assert {:error, _cng} = ObjectValidator.validate(block, [])
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/chat_validation_test.exs b/test/web/activity_pub/object_validators/chat_validation_test.exs
deleted file mode 100644
index 50bf03515..000000000
--- a/test/web/activity_pub/object_validators/chat_validation_test.exs
+++ /dev/null
@@ -1,211 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
- use Pleroma.DataCase
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "chat message create activities" do
- test "it is invalid if the object already exists" do
- user = insert(:user)
- recipient = insert(:user)
- {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
- object = Object.normalize(activity, false)
-
- {:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
-
- {:error, cng} = ObjectValidator.validate(create_data, [])
-
- assert {:object, {"The object to create already exists", []}} in cng.errors
- end
-
- test "it is invalid if the object data has a different `to` or `actor` field" do
- user = insert(:user)
- recipient = insert(:user)
- {:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey")
-
- {:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id])
-
- {:error, cng} = ObjectValidator.validate(create_data, [])
-
- assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors
- assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors
- end
- end
-
- describe "chat messages" do
- setup do
- clear_config([:instance, :remote_limit])
- user = insert(:user)
- recipient = insert(:user, local: false)
-
- {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:")
-
- %{user: user, recipient: recipient, valid_chat_message: valid_chat_message}
- end
-
- test "let's through some basic html", %{user: user, recipient: recipient} do
- {:ok, valid_chat_message, _} =
- Builder.chat_message(
- user,
- recipient.ap_id,
- "hey <a href='https://example.org'>example</a> <script>alert('uguu')</script>"
- )
-
- assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
-
- assert object["content"] ==
- "hey <a href=\"https://example.org\">example</a> alert(&#39;uguu&#39;)"
- end
-
- test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do
- assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
-
- assert Map.put(valid_chat_message, "attachment", nil) == object
- end
-
- test "validates for a basic object with an attachment", %{
- valid_chat_message: valid_chat_message,
- user: user
- } do
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
-
- valid_chat_message =
- valid_chat_message
- |> Map.put("attachment", attachment.data)
-
- assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
-
- assert object["attachment"]
- end
-
- test "validates for a basic object with an attachment in an array", %{
- valid_chat_message: valid_chat_message,
- user: user
- } do
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
-
- valid_chat_message =
- valid_chat_message
- |> Map.put("attachment", [attachment.data])
-
- assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
-
- assert object["attachment"]
- end
-
- test "validates for a basic object with an attachment but without content", %{
- valid_chat_message: valid_chat_message,
- user: user
- } do
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
-
- valid_chat_message =
- valid_chat_message
- |> Map.put("attachment", attachment.data)
- |> Map.delete("content")
-
- assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
-
- assert object["attachment"]
- end
-
- test "does not validate if the message has no content", %{
- valid_chat_message: valid_chat_message
- } do
- contentless =
- valid_chat_message
- |> Map.delete("content")
-
- refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, []))
- end
-
- test "does not validate if the message is longer than the remote_limit", %{
- valid_chat_message: valid_chat_message
- } do
- Pleroma.Config.put([:instance, :remote_limit], 2)
- refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
- end
-
- test "does not validate if the recipient is blocking the actor", %{
- valid_chat_message: valid_chat_message,
- user: user,
- recipient: recipient
- } do
- Pleroma.User.block(recipient, user)
- refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
- end
-
- test "does not validate if the recipient is not accepting chat messages", %{
- valid_chat_message: valid_chat_message,
- recipient: recipient
- } do
- recipient
- |> Ecto.Changeset.change(%{accepts_chat_messages: false})
- |> Pleroma.Repo.update!()
-
- refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
- end
-
- test "does not validate if the actor or the recipient is not in our system", %{
- valid_chat_message: valid_chat_message
- } do
- chat_message =
- valid_chat_message
- |> Map.put("actor", "https://raymoo.com/raymoo")
-
- {:error, _} = ObjectValidator.validate(chat_message, [])
-
- chat_message =
- valid_chat_message
- |> Map.put("to", ["https://raymoo.com/raymoo"])
-
- {:error, _} = ObjectValidator.validate(chat_message, [])
- end
-
- test "does not validate for a message with multiple recipients", %{
- valid_chat_message: valid_chat_message,
- user: user,
- recipient: recipient
- } do
- chat_message =
- valid_chat_message
- |> Map.put("to", [user.ap_id, recipient.ap_id])
-
- assert {:error, _} = ObjectValidator.validate(chat_message, [])
- end
-
- test "does not validate if it doesn't concern local users" do
- user = insert(:user, local: false)
- recipient = insert(:user, local: false)
-
- {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey")
- assert {:error, _} = ObjectValidator.validate(valid_chat_message, [])
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/delete_validation_test.exs b/test/web/activity_pub/object_validators/delete_validation_test.exs
deleted file mode 100644
index 02683b899..000000000
--- a/test/web/activity_pub/object_validators/delete_validation_test.exs
+++ /dev/null
@@ -1,106 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "deletes" do
- setup do
- user = insert(:user)
- {:ok, post_activity} = CommonAPI.post(user, %{status: "cancel me daddy"})
-
- {:ok, valid_post_delete, _} = Builder.delete(user, post_activity.data["object"])
- {:ok, valid_user_delete, _} = Builder.delete(user, user.ap_id)
-
- %{user: user, valid_post_delete: valid_post_delete, valid_user_delete: valid_user_delete}
- end
-
- test "it is valid for a post deletion", %{valid_post_delete: valid_post_delete} do
- {:ok, valid_post_delete, _} = ObjectValidator.validate(valid_post_delete, [])
-
- assert valid_post_delete["deleted_activity_id"]
- end
-
- test "it is invalid if the object isn't in a list of certain types", %{
- valid_post_delete: valid_post_delete
- } do
- object = Object.get_by_ap_id(valid_post_delete["object"])
-
- data =
- object.data
- |> Map.put("type", "Like")
-
- {:ok, _object} =
- object
- |> Ecto.Changeset.change(%{data: data})
- |> Object.update_and_set_cache()
-
- {:error, cng} = ObjectValidator.validate(valid_post_delete, [])
- assert {:object, {"object not in allowed types", []}} in cng.errors
- end
-
- test "it is valid for a user deletion", %{valid_user_delete: valid_user_delete} do
- assert match?({:ok, _, _}, ObjectValidator.validate(valid_user_delete, []))
- end
-
- test "it's invalid if the id is missing", %{valid_post_delete: valid_post_delete} do
- no_id =
- valid_post_delete
- |> Map.delete("id")
-
- {:error, cng} = ObjectValidator.validate(no_id, [])
-
- assert {:id, {"can't be blank", [validation: :required]}} in cng.errors
- end
-
- test "it's invalid if the object doesn't exist", %{valid_post_delete: valid_post_delete} do
- missing_object =
- valid_post_delete
- |> Map.put("object", "http://does.not/exist")
-
- {:error, cng} = ObjectValidator.validate(missing_object, [])
-
- assert {:object, {"can't find object", []}} in cng.errors
- end
-
- test "it's invalid if the actor of the object and the actor of delete are from different domains",
- %{valid_post_delete: valid_post_delete} do
- valid_user = insert(:user)
-
- valid_other_actor =
- valid_post_delete
- |> Map.put("actor", valid_user.ap_id)
-
- assert match?({:ok, _, _}, ObjectValidator.validate(valid_other_actor, []))
-
- invalid_other_actor =
- valid_post_delete
- |> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
-
- {:error, cng} = ObjectValidator.validate(invalid_other_actor, [])
-
- assert {:actor, {"is not allowed to modify object", []}} in cng.errors
- end
-
- test "it's valid if the actor of the object is a local superuser",
- %{valid_post_delete: valid_post_delete} do
- user =
- insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo")
-
- valid_other_actor =
- valid_post_delete
- |> Map.put("actor", user.ap_id)
-
- {:ok, _, meta} = ObjectValidator.validate(valid_other_actor, [])
- assert meta[:do_not_federate]
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/emoji_react_validation_test.exs b/test/web/activity_pub/object_validators/emoji_react_validation_test.exs
deleted file mode 100644
index 582e6d785..000000000
--- a/test/web/activity_pub/object_validators/emoji_react_validation_test.exs
+++ /dev/null
@@ -1,53 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "EmojiReacts" do
- setup do
- user = insert(:user)
- {:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
-
- object = Pleroma.Object.get_by_ap_id(post_activity.data["object"])
-
- {:ok, valid_emoji_react, []} = Builder.emoji_react(user, object, "👌")
-
- %{user: user, post_activity: post_activity, valid_emoji_react: valid_emoji_react}
- end
-
- test "it validates a valid EmojiReact", %{valid_emoji_react: valid_emoji_react} do
- assert {:ok, _, _} = ObjectValidator.validate(valid_emoji_react, [])
- end
-
- test "it is not valid without a 'content' field", %{valid_emoji_react: valid_emoji_react} do
- without_content =
- valid_emoji_react
- |> Map.delete("content")
-
- {:error, cng} = ObjectValidator.validate(without_content, [])
-
- refute cng.valid?
- assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
- end
-
- test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
- without_emoji_content =
- valid_emoji_react
- |> Map.put("content", "x")
-
- {:error, cng} = ObjectValidator.validate(without_emoji_content, [])
-
- refute cng.valid?
-
- assert {:content, {"must be a single character emoji", []}} in cng.errors
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/follow_validation_test.exs b/test/web/activity_pub/object_validators/follow_validation_test.exs
deleted file mode 100644
index 6e1378be2..000000000
--- a/test/web/activity_pub/object_validators/follow_validation_test.exs
+++ /dev/null
@@ -1,26 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
-
- import Pleroma.Factory
-
- describe "Follows" do
- setup do
- follower = insert(:user)
- followed = insert(:user)
-
- {:ok, valid_follow, []} = Builder.follow(follower, followed)
- %{follower: follower, followed: followed, valid_follow: valid_follow}
- end
-
- test "validates a basic follow object", %{valid_follow: valid_follow} do
- assert {:ok, _follow, []} = ObjectValidator.validate(valid_follow, [])
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/like_validation_test.exs b/test/web/activity_pub/object_validators/like_validation_test.exs
deleted file mode 100644
index 2c033b7e2..000000000
--- a/test/web/activity_pub/object_validators/like_validation_test.exs
+++ /dev/null
@@ -1,113 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
- alias Pleroma.Web.ActivityPub.Utils
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "likes" do
- setup do
- user = insert(:user)
- {:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
-
- valid_like = %{
- "to" => [user.ap_id],
- "cc" => [],
- "type" => "Like",
- "id" => Utils.generate_activity_id(),
- "object" => post_activity.data["object"],
- "actor" => user.ap_id,
- "context" => "a context"
- }
-
- %{valid_like: valid_like, user: user, post_activity: post_activity}
- end
-
- test "returns ok when called in the ObjectValidator", %{valid_like: valid_like} do
- {:ok, object, _meta} = ObjectValidator.validate(valid_like, [])
-
- assert "id" in Map.keys(object)
- end
-
- test "is valid for a valid object", %{valid_like: valid_like} do
- assert LikeValidator.cast_and_validate(valid_like).valid?
- end
-
- test "sets the 'to' field to the object actor if no recipients are given", %{
- valid_like: valid_like,
- user: user
- } do
- without_recipients =
- valid_like
- |> Map.delete("to")
-
- {:ok, object, _meta} = ObjectValidator.validate(without_recipients, [])
-
- assert object["to"] == [user.ap_id]
- end
-
- test "sets the context field to the context of the object if no context is given", %{
- valid_like: valid_like,
- post_activity: post_activity
- } do
- without_context =
- valid_like
- |> Map.delete("context")
-
- {:ok, object, _meta} = ObjectValidator.validate(without_context, [])
-
- assert object["context"] == post_activity.data["context"]
- end
-
- test "it errors when the actor is missing or not known", %{valid_like: valid_like} do
- without_actor = Map.delete(valid_like, "actor")
-
- refute LikeValidator.cast_and_validate(without_actor).valid?
-
- with_invalid_actor = Map.put(valid_like, "actor", "invalidactor")
-
- refute LikeValidator.cast_and_validate(with_invalid_actor).valid?
- end
-
- test "it errors when the object is missing or not known", %{valid_like: valid_like} do
- without_object = Map.delete(valid_like, "object")
-
- refute LikeValidator.cast_and_validate(without_object).valid?
-
- with_invalid_object = Map.put(valid_like, "object", "invalidobject")
-
- refute LikeValidator.cast_and_validate(with_invalid_object).valid?
- end
-
- test "it errors when the actor has already like the object", %{
- valid_like: valid_like,
- user: user,
- post_activity: post_activity
- } do
- _like = CommonAPI.favorite(user, post_activity.id)
-
- refute LikeValidator.cast_and_validate(valid_like).valid?
- end
-
- test "it works when actor or object are wrapped in maps", %{valid_like: valid_like} do
- wrapped_like =
- valid_like
- |> Map.put("actor", %{"id" => valid_like["actor"]})
- |> Map.put("object", %{"id" => valid_like["object"]})
-
- validated = LikeValidator.cast_and_validate(wrapped_like)
-
- assert validated.valid?
-
- assert {:actor, valid_like["actor"]} in validated.changes
- assert {:object, valid_like["object"]} in validated.changes
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/note_validator_test.exs b/test/web/activity_pub/object_validators/note_validator_test.exs
deleted file mode 100644
index 30c481ffb..000000000
--- a/test/web/activity_pub/object_validators/note_validator_test.exs
+++ /dev/null
@@ -1,35 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidatorTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator
- alias Pleroma.Web.ActivityPub.Utils
-
- import Pleroma.Factory
-
- describe "Notes" do
- setup do
- user = insert(:user)
-
- note = %{
- "id" => Utils.generate_activity_id(),
- "type" => "Note",
- "actor" => user.ap_id,
- "to" => [user.follower_address],
- "cc" => [],
- "content" => "Hellow this is content.",
- "context" => "xxx",
- "summary" => "a post"
- }
-
- %{user: user, note: note}
- end
-
- test "a basic note validates", %{note: note} do
- %{valid?: true} = NoteValidator.cast_and_validate(note)
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/reject_validation_test.exs b/test/web/activity_pub/object_validators/reject_validation_test.exs
deleted file mode 100644
index 370bb6e5c..000000000
--- a/test/web/activity_pub/object_validators/reject_validation_test.exs
+++ /dev/null
@@ -1,56 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.RejectValidationTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.ActivityPub.Pipeline
-
- import Pleroma.Factory
-
- setup do
- follower = insert(:user)
- followed = insert(:user, local: false)
-
- {:ok, follow_data, _} = Builder.follow(follower, followed)
- {:ok, follow_activity, _} = Pipeline.common_pipeline(follow_data, local: true)
-
- {:ok, reject_data, _} = Builder.reject(followed, follow_activity)
-
- %{reject_data: reject_data, followed: followed}
- end
-
- test "it validates a basic 'reject'", %{reject_data: reject_data} do
- assert {:ok, _, _} = ObjectValidator.validate(reject_data, [])
- end
-
- test "it fails when the actor doesn't exist", %{reject_data: reject_data} do
- reject_data =
- reject_data
- |> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
-
- assert {:error, _} = ObjectValidator.validate(reject_data, [])
- end
-
- test "it fails when the rejected activity doesn't exist", %{reject_data: reject_data} do
- reject_data =
- reject_data
- |> Map.put("object", "https://gensokyo.2hu/users/raymoo/follows/1")
-
- assert {:error, _} = ObjectValidator.validate(reject_data, [])
- end
-
- test "for an rejected follow, it only validates if the actor of the reject is the followed actor",
- %{reject_data: reject_data} do
- stranger = insert(:user)
-
- reject_data =
- reject_data
- |> Map.put("actor", stranger.ap_id)
-
- assert {:error, _} = ObjectValidator.validate(reject_data, [])
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/date_time_test.exs b/test/web/activity_pub/object_validators/types/date_time_test.exs
deleted file mode 100644
index 43be8e936..000000000
--- a/test/web/activity_pub/object_validators/types/date_time_test.exs
+++ /dev/null
@@ -1,32 +0,0 @@
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTimeTest do
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime
- use Pleroma.DataCase
-
- test "it validates an xsd:Datetime" do
- valid_strings = [
- "2004-04-12T13:20:00",
- "2004-04-12T13:20:15.5",
- "2004-04-12T13:20:00-05:00",
- "2004-04-12T13:20:00Z"
- ]
-
- invalid_strings = [
- "2004-04-12T13:00",
- "2004-04-1213:20:00",
- "99-04-12T13:00",
- "2004-04-12"
- ]
-
- assert {:ok, "2004-04-01T12:00:00Z"} == DateTime.cast("2004-04-01T12:00:00Z")
-
- Enum.each(valid_strings, fn date_time ->
- result = DateTime.cast(date_time)
- assert {:ok, _} = result
- end)
-
- Enum.each(invalid_strings, fn date_time ->
- result = DateTime.cast(date_time)
- assert :error == result
- end)
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/object_id_test.exs b/test/web/activity_pub/object_validators/types/object_id_test.exs
deleted file mode 100644
index e0ab76379..000000000
--- a/test/web/activity_pub/object_validators/types/object_id_test.exs
+++ /dev/null
@@ -1,41 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ObjectValidators.Types.ObjectIDTest do
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
- use Pleroma.DataCase
-
- @uris [
- "http://lain.com/users/lain",
- "http://lain.com",
- "https://lain.com/object/1"
- ]
-
- @non_uris [
- "https://",
- "rin",
- 1,
- :x,
- %{"1" => 2}
- ]
-
- test "it accepts http uris" do
- Enum.each(@uris, fn uri ->
- assert {:ok, uri} == ObjectID.cast(uri)
- end)
- end
-
- test "it accepts an object with a nested uri id" do
- Enum.each(@uris, fn uri ->
- assert {:ok, uri} == ObjectID.cast(%{"id" => uri})
- end)
- end
-
- test "it rejects non-uri strings" do
- Enum.each(@non_uris, fn non_uri ->
- assert :error == ObjectID.cast(non_uri)
- assert :error == ObjectID.cast(%{"id" => non_uri})
- end)
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/recipients_test.exs b/test/web/activity_pub/object_validators/types/recipients_test.exs
deleted file mode 100644
index 053916bdd..000000000
--- a/test/web/activity_pub/object_validators/types/recipients_test.exs
+++ /dev/null
@@ -1,27 +0,0 @@
-defmodule Pleroma.Web.ObjectValidators.Types.RecipientsTest do
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients
- use Pleroma.DataCase
-
- test "it asserts that all elements of the list are object ids" do
- list = ["https://lain.com/users/lain", "invalid"]
-
- assert :error == Recipients.cast(list)
- end
-
- test "it works with a list" do
- list = ["https://lain.com/users/lain"]
- assert {:ok, list} == Recipients.cast(list)
- end
-
- test "it works with a list with whole objects" do
- list = ["https://lain.com/users/lain", %{"id" => "https://gensokyo.2hu/users/raymoo"}]
- resulting_list = ["https://gensokyo.2hu/users/raymoo", "https://lain.com/users/lain"]
- assert {:ok, resulting_list} == Recipients.cast(list)
- end
-
- test "it turns a single string into a list" do
- recipient = "https://lain.com/users/lain"
-
- assert {:ok, [recipient]} == Recipients.cast(recipient)
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/safe_text_test.exs b/test/web/activity_pub/object_validators/types/safe_text_test.exs
deleted file mode 100644
index 9c08606f6..000000000
--- a/test/web/activity_pub/object_validators/types/safe_text_test.exs
+++ /dev/null
@@ -1,30 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.SafeTextTest do
- use Pleroma.DataCase
-
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText
-
- test "it lets normal text go through" do
- text = "hey how are you"
- assert {:ok, text} == SafeText.cast(text)
- end
-
- test "it removes html tags from text" do
- text = "hey look xss <script>alert('foo')</script>"
- assert {:ok, "hey look xss alert(&#39;foo&#39;)"} == SafeText.cast(text)
- end
-
- test "it keeps basic html tags" do
- text = "hey <a href='http://gensokyo.2hu'>look</a> xss <script>alert('foo')</script>"
-
- assert {:ok, "hey <a href=\"http://gensokyo.2hu\">look</a> xss alert(&#39;foo&#39;)"} ==
- SafeText.cast(text)
- end
-
- test "errors for non-text" do
- assert :error == SafeText.cast(1)
- end
-end
diff --git a/test/web/activity_pub/object_validators/undo_validation_test.exs b/test/web/activity_pub/object_validators/undo_validation_test.exs
deleted file mode 100644
index 75bbcc4b6..000000000
--- a/test/web/activity_pub/object_validators/undo_validation_test.exs
+++ /dev/null
@@ -1,53 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "Undos" do
- setup do
- user = insert(:user)
- {:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
- {:ok, like} = CommonAPI.favorite(user, post_activity.id)
- {:ok, valid_like_undo, []} = Builder.undo(user, like)
-
- %{user: user, like: like, valid_like_undo: valid_like_undo}
- end
-
- test "it validates a basic like undo", %{valid_like_undo: valid_like_undo} do
- assert {:ok, _, _} = ObjectValidator.validate(valid_like_undo, [])
- end
-
- test "it does not validate if the actor of the undo is not the actor of the object", %{
- valid_like_undo: valid_like_undo
- } do
- other_user = insert(:user, ap_id: "https://gensokyo.2hu/users/raymoo")
-
- bad_actor =
- valid_like_undo
- |> Map.put("actor", other_user.ap_id)
-
- {:error, cng} = ObjectValidator.validate(bad_actor, [])
-
- assert {:actor, {"not the same as object actor", []}} in cng.errors
- end
-
- test "it does not validate if the object is missing", %{valid_like_undo: valid_like_undo} do
- missing_object =
- valid_like_undo
- |> Map.put("object", "https://gensokyo.2hu/objects/1")
-
- {:error, cng} = ObjectValidator.validate(missing_object, [])
-
- assert {:object, {"can't find object", []}} in cng.errors
- assert length(cng.errors) == 1
- end
- end
-end
diff --git a/test/web/activity_pub/object_validators/update_validation_test.exs b/test/web/activity_pub/object_validators/update_validation_test.exs
deleted file mode 100644
index 5e80cf731..000000000
--- a/test/web/activity_pub/object_validators/update_validation_test.exs
+++ /dev/null
@@ -1,44 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.ObjectValidator
-
- import Pleroma.Factory
-
- describe "updates" do
- setup do
- user = insert(:user)
-
- object = %{
- "id" => user.ap_id,
- "name" => "A new name",
- "summary" => "A new bio"
- }
-
- {:ok, valid_update, []} = Builder.update(user, object)
-
- %{user: user, valid_update: valid_update}
- end
-
- test "validates a basic object", %{valid_update: valid_update} do
- assert {:ok, _update, []} = ObjectValidator.validate(valid_update, [])
- end
-
- test "returns an error if the object can't be updated by the actor", %{
- valid_update: valid_update
- } do
- other_user = insert(:user)
-
- update =
- valid_update
- |> Map.put("actor", other_user.ap_id)
-
- assert {:error, _cng} = ObjectValidator.validate(update, [])
- end
- end
-end
diff --git a/test/web/activity_pub/pipeline_test.exs b/test/web/activity_pub/pipeline_test.exs
deleted file mode 100644
index 210a06563..000000000
--- a/test/web/activity_pub/pipeline_test.exs
+++ /dev/null
@@ -1,179 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.PipelineTest do
- use Pleroma.DataCase
-
- import Mock
- import Pleroma.Factory
-
- describe "common_pipeline/2" do
- setup do
- clear_config([:instance, :federating], true)
- :ok
- end
-
- test "when given an `object_data` in meta, Federation will receive a the original activity with the `object` field set to this embedded object" do
- activity = insert(:note_activity)
- object = %{"id" => "1", "type" => "Love"}
- meta = [local: true, object_data: object]
-
- activity_with_object = %{activity | data: Map.put(activity.data, "object", object)}
-
- with_mocks([
- {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
- {
- Pleroma.Web.ActivityPub.MRF,
- [],
- [pipeline_filter: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.ActivityPub,
- [],
- [persist: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.SideEffects,
- [],
- [
- handle: fn o, m -> {:ok, o, m} end,
- handle_after_transaction: fn m -> m end
- ]
- },
- {
- Pleroma.Web.Federator,
- [],
- [publish: fn _o -> :ok end]
- }
- ]) do
- assert {:ok, ^activity, ^meta} =
- Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
-
- assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
- refute called(Pleroma.Web.Federator.publish(activity))
- assert_called(Pleroma.Web.Federator.publish(activity_with_object))
- end
- end
-
- test "it goes through validation, filtering, persisting, side effects and federation for local activities" do
- activity = insert(:note_activity)
- meta = [local: true]
-
- with_mocks([
- {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
- {
- Pleroma.Web.ActivityPub.MRF,
- [],
- [pipeline_filter: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.ActivityPub,
- [],
- [persist: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.SideEffects,
- [],
- [
- handle: fn o, m -> {:ok, o, m} end,
- handle_after_transaction: fn m -> m end
- ]
- },
- {
- Pleroma.Web.Federator,
- [],
- [publish: fn _o -> :ok end]
- }
- ]) do
- assert {:ok, ^activity, ^meta} =
- Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
-
- assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
- assert_called(Pleroma.Web.Federator.publish(activity))
- end
- end
-
- test "it goes through validation, filtering, persisting, side effects without federation for remote activities" do
- activity = insert(:note_activity)
- meta = [local: false]
-
- with_mocks([
- {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
- {
- Pleroma.Web.ActivityPub.MRF,
- [],
- [pipeline_filter: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.ActivityPub,
- [],
- [persist: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.SideEffects,
- [],
- [handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
- },
- {
- Pleroma.Web.Federator,
- [],
- []
- }
- ]) do
- assert {:ok, ^activity, ^meta} =
- Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
-
- assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
- end
- end
-
- test "it goes through validation, filtering, persisting, side effects without federation for local activities if federation is deactivated" do
- clear_config([:instance, :federating], false)
-
- activity = insert(:note_activity)
- meta = [local: true]
-
- with_mocks([
- {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
- {
- Pleroma.Web.ActivityPub.MRF,
- [],
- [pipeline_filter: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.ActivityPub,
- [],
- [persist: fn o, m -> {:ok, o, m} end]
- },
- {
- Pleroma.Web.ActivityPub.SideEffects,
- [],
- [handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
- },
- {
- Pleroma.Web.Federator,
- [],
- []
- }
- ]) do
- assert {:ok, ^activity, ^meta} =
- Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
-
- assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
- assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
- end
- end
- end
-end
diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs
deleted file mode 100644
index b9388b966..000000000
--- a/test/web/activity_pub/publisher_test.exs
+++ /dev/null
@@ -1,365 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.PublisherTest do
- 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"
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup_all do: clear_config([:instance, :federating], true)
-
- describe "gather_webfinger_links/1" do
- test "it returns links" do
- user = insert(:user)
-
- expected_links = [
- %{"href" => user.ap_id, "rel" => "self", "type" => "application/activity+json"},
- %{
- "href" => user.ap_id,
- "rel" => "self",
- "type" => "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
- },
- %{
- "rel" => "http://ostatus.org/schema/1.0/subscribe",
- "template" => "#{Pleroma.Web.base_url()}/ostatus_subscribe?acct={uri}"
- }
- ]
-
- assert expected_links == Publisher.gather_webfinger_links(user)
- end
- end
-
- describe "determine_inbox/2" do
- test "it returns sharedInbox for messages involving as:Public in to" do
- user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
-
- activity = %Activity{
- data: %{"to" => [@as_public], "cc" => [user.follower_address]}
- }
-
- assert Publisher.determine_inbox(activity, user) == "http://example.com/inbox"
- end
-
- test "it returns sharedInbox for messages involving as:Public in cc" do
- user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
-
- activity = %Activity{
- data: %{"cc" => [@as_public], "to" => [user.follower_address]}
- }
-
- assert Publisher.determine_inbox(activity, user) == "http://example.com/inbox"
- end
-
- test "it returns sharedInbox for messages involving multiple recipients in to" do
- user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
- user_two = insert(:user)
- user_three = insert(:user)
-
- activity = %Activity{
- data: %{"cc" => [], "to" => [user.ap_id, user_two.ap_id, user_three.ap_id]}
- }
-
- assert Publisher.determine_inbox(activity, user) == "http://example.com/inbox"
- end
-
- test "it returns sharedInbox for messages involving multiple recipients in cc" do
- user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
- user_two = insert(:user)
- user_three = insert(:user)
-
- activity = %Activity{
- data: %{"to" => [], "cc" => [user.ap_id, user_two.ap_id, user_three.ap_id]}
- }
-
- assert Publisher.determine_inbox(activity, user) == "http://example.com/inbox"
- end
-
- test "it returns sharedInbox for messages involving multiple recipients in total" do
- user =
- insert(:user, %{
- shared_inbox: "http://example.com/inbox",
- inbox: "http://example.com/personal-inbox"
- })
-
- user_two = insert(:user)
-
- activity = %Activity{
- data: %{"to" => [user_two.ap_id], "cc" => [user.ap_id]}
- }
-
- assert Publisher.determine_inbox(activity, user) == "http://example.com/inbox"
- end
-
- test "it returns inbox for messages involving single recipients in total" do
- user =
- insert(:user, %{
- shared_inbox: "http://example.com/inbox",
- inbox: "http://example.com/personal-inbox"
- })
-
- activity = %Activity{
- data: %{"to" => [user.ap_id], "cc" => []}
- }
-
- assert Publisher.determine_inbox(activity, user) == "http://example.com/personal-inbox"
- end
- end
-
- describe "publish_one/1" do
- test "publish to url with with different ports" do
- inbox80 = "http://42.site/users/nick1/inbox"
- inbox42 = "http://42.site:42/users/nick1/inbox"
-
- mock(fn
- %{method: :post, url: "http://42.site:42/users/nick1/inbox"} ->
- {:ok, %Tesla.Env{status: 200, body: "port 42"}}
-
- %{method: :post, url: "http://42.site/users/nick1/inbox"} ->
- {:ok, %Tesla.Env{status: 200, body: "port 80"}}
- end)
-
- actor = insert(:user)
-
- assert {:ok, %{body: "port 42"}} =
- Publisher.publish_one(%{
- inbox: inbox42,
- json: "{}",
- actor: actor,
- id: 1,
- unreachable_since: true
- })
-
- assert {:ok, %{body: "port 80"}} =
- Publisher.publish_one(%{
- inbox: inbox80,
- json: "{}",
- actor: actor,
- id: 1,
- unreachable_since: true
- })
- end
-
- test_with_mock "calls `Instances.set_reachable` on successful federation if `unreachable_since` is not specified",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://200.site/users/nick1/inbox"
-
- assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
- assert called(Instances.set_reachable(inbox))
- end
-
- test_with_mock "calls `Instances.set_reachable` on successful federation if `unreachable_since` is set",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://200.site/users/nick1/inbox"
-
- assert {:ok, _} =
- Publisher.publish_one(%{
- inbox: inbox,
- json: "{}",
- actor: actor,
- id: 1,
- unreachable_since: NaiveDateTime.utc_now()
- })
-
- assert called(Instances.set_reachable(inbox))
- end
-
- test_with_mock "does NOT call `Instances.set_reachable` on successful federation if `unreachable_since` is nil",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://200.site/users/nick1/inbox"
-
- assert {:ok, _} =
- Publisher.publish_one(%{
- inbox: inbox,
- json: "{}",
- actor: actor,
- id: 1,
- unreachable_since: nil
- })
-
- refute called(Instances.set_reachable(inbox))
- end
-
- test_with_mock "calls `Instances.set_unreachable` on target inbox on non-2xx HTTP response code",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://404.site/users/nick1/inbox"
-
- assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
-
- assert called(Instances.set_unreachable(inbox))
- end
-
- test_with_mock "it calls `Instances.set_unreachable` on target inbox on request error of any kind",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://connrefused.site/users/nick1/inbox"
-
- 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
-
- test_with_mock "does NOT call `Instances.set_unreachable` if target is reachable",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://200.site/users/nick1/inbox"
-
- assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
-
- refute called(Instances.set_unreachable(inbox))
- end
-
- test_with_mock "does NOT call `Instances.set_unreachable` if target instance has non-nil `unreachable_since`",
- Instances,
- [:passthrough],
- [] do
- actor = insert(:user)
- inbox = "http://connrefused.site/users/nick1/inbox"
-
- 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
- end
-
- describe "publish/2" do
- test_with_mock "publishes an activity with BCC to all relevant peers.",
- Pleroma.Web.Federator.Publisher,
- [:passthrough],
- [] do
- follower =
- insert(:user, %{
- local: false,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
- })
-
- actor = insert(:user, follower_address: follower.ap_id)
- user = insert(:user)
-
- {:ok, _follower_one} = Pleroma.User.follow(follower, actor)
- actor = refresh_record(actor)
-
- note_activity =
- insert(:note_activity,
- recipients: [follower.ap_id],
- data_attrs: %{"bcc" => [user.ap_id]}
- )
-
- res = Publisher.publish(actor, note_activity)
- assert res == :ok
-
- assert called(
- Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
- inbox: "https://domain.com/users/nick1/inbox",
- 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,
- inbox: "https://domain.com/users/nick1/inbox",
- ap_enabled: true
- )
-
- another_fetcher =
- insert(:user,
- local: false,
- inbox: "https://domain2.com/users/nick1/inbox",
- ap_enabled: true
- )
-
- 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
deleted file mode 100644
index 9d657ac4f..000000000
--- a/test/web/activity_pub/relay_test.exs
+++ /dev/null
@@ -1,128 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.RelayTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Relay
- alias Pleroma.Web.CommonAPI
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
- import Mock
-
- test "gets an actor for the relay" do
- user = Relay.get_actor()
- assert user.ap_id == "#{Pleroma.Web.Endpoint.url()}/relay"
- end
-
- test "relay actor is invisible" do
- user = Relay.get_actor()
- assert User.invisible?(user)
- end
-
- describe "follow/1" do
- test "returns errors when user not found" do
- assert capture_log(fn ->
- {:error, _} = Relay.follow("test-ap-id")
- end) =~ "Could not decode user at fetch"
- end
-
- test "returns activity" do
- user = insert(:user)
- service_actor = Relay.get_actor()
- assert {:ok, %Activity{} = activity} = Relay.follow(user.ap_id)
- assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
- assert user.ap_id in activity.recipients
- assert activity.data["type"] == "Follow"
- assert activity.data["actor"] == service_actor.ap_id
- assert activity.data["object"] == user.ap_id
- end
- end
-
- describe "unfollow/1" do
- test "returns errors when user not found" do
- assert capture_log(fn ->
- {:error, _} = Relay.unfollow("test-ap-id")
- end) =~ "Could not decode user at fetch"
- end
-
- test "returns activity" do
- user = insert(:user)
- service_actor = Relay.get_actor()
- CommonAPI.follow(service_actor, user)
- assert "#{user.ap_id}/followers" in User.following(service_actor)
- assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
- assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
- assert user.ap_id in activity.recipients
- assert activity.data["type"] == "Undo"
- assert activity.data["actor"] == service_actor.ap_id
- assert activity.data["to"] == [user.ap_id]
- refute "#{user.ap_id}/followers" in User.following(service_actor)
- end
- end
-
- describe "publish/1" do
- setup do: clear_config([:instance, :federating])
-
- test "returns error when activity not `Create` type" do
- activity = insert(:like_activity)
- assert Relay.publish(activity) == {:error, "Not implemented"}
- end
-
- @tag capture_log: true
- test "returns error when activity not public" do
- activity = insert(:direct_note_activity)
- assert Relay.publish(activity) == {:error, false}
- end
-
- test "returns error when object is unknown" do
- activity =
- insert(:note_activity,
- data: %{
- "type" => "Create",
- "object" => "http://mastodon.example.org/eee/99541947525187367"
- }
- )
-
- Tesla.Mock.mock(fn
- %{method: :get, url: "http://mastodon.example.org/eee/99541947525187367"} ->
- %Tesla.Env{status: 500, body: ""}
- end)
-
- assert capture_log(fn ->
- assert Relay.publish(activity) == {:error, false}
- end) =~ "[error] error: false"
- end
-
- test_with_mock "returns announce activity and publish to federate",
- Pleroma.Web.Federator,
- [:passthrough],
- [] do
- clear_config([:instance, :federating], true)
- service_actor = Relay.get_actor()
- note = insert(:note_activity)
- assert {:ok, %Activity{} = activity} = Relay.publish(note)
- assert activity.data["type"] == "Announce"
- assert activity.data["actor"] == service_actor.ap_id
- assert activity.data["to"] == [service_actor.follower_address]
- assert called(Pleroma.Web.Federator.publish(activity))
- end
-
- test_with_mock "returns announce activity and not publish to federate",
- Pleroma.Web.Federator,
- [:passthrough],
- [] do
- clear_config([:instance, :federating], false)
- service_actor = Relay.get_actor()
- note = insert(:note_activity)
- assert {:ok, %Activity{} = activity} = Relay.publish(note)
- assert activity.data["type"] == "Announce"
- assert activity.data["actor"] == service_actor.ap_id
- refute called(Pleroma.Web.Federator.publish(activity))
- end
- end
-end
diff --git a/test/web/activity_pub/side_effects_test.exs b/test/web/activity_pub/side_effects_test.exs
deleted file mode 100644
index 9efbaad04..000000000
--- a/test/web/activity_pub/side_effects_test.exs
+++ /dev/null
@@ -1,639 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
- use Oban.Testing, repo: Pleroma.Repo
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Notification
- alias Pleroma.Object
- alias Pleroma.Repo
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.Builder
- alias Pleroma.Web.ActivityPub.SideEffects
- alias Pleroma.Web.CommonAPI
-
- import ExUnit.CaptureLog
- import Mock
- import Pleroma.Factory
-
- describe "handle_after_transaction" do
- test "it streams out notifications and streams" do
- author = insert(:user, local: true)
- recipient = insert(:user, local: true)
-
- {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
-
- {:ok, create_activity_data, _meta} =
- Builder.create(author, chat_message_data["id"], [recipient.ap_id])
-
- {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
-
- {:ok, _create_activity, meta} =
- SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
-
- assert [notification] = meta[:notifications]
-
- with_mocks([
- {
- Pleroma.Web.Streamer,
- [],
- [
- stream: fn _, _ -> nil end
- ]
- },
- {
- Pleroma.Web.Push,
- [],
- [
- send: fn _ -> nil end
- ]
- }
- ]) do
- SideEffects.handle_after_transaction(meta)
-
- assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
- assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
- assert called(Pleroma.Web.Push.send(notification))
- end
- end
- end
-
- describe "blocking users" do
- setup do
- user = insert(:user)
- blocked = insert(:user)
- User.follow(blocked, user)
- User.follow(user, blocked)
-
- {:ok, block_data, []} = Builder.block(user, blocked)
- {:ok, block, _meta} = ActivityPub.persist(block_data, local: true)
-
- %{user: user, blocked: blocked, block: block}
- end
-
- test "it unfollows and blocks", %{user: user, blocked: blocked, block: block} do
- assert User.following?(user, blocked)
- assert User.following?(blocked, user)
-
- {:ok, _, _} = SideEffects.handle(block)
-
- refute User.following?(user, blocked)
- refute User.following?(blocked, user)
- assert User.blocks?(user, blocked)
- end
-
- test "it blocks but does not unfollow if the relevant setting is set", %{
- user: user,
- blocked: blocked,
- block: block
- } do
- clear_config([:activitypub, :unfollow_blocked], false)
- assert User.following?(user, blocked)
- assert User.following?(blocked, user)
-
- {:ok, _, _} = SideEffects.handle(block)
-
- refute User.following?(user, blocked)
- assert User.following?(blocked, user)
- assert User.blocks?(user, blocked)
- end
- end
-
- describe "update users" do
- setup do
- user = insert(:user)
- {:ok, update_data, []} = Builder.update(user, %{"id" => user.ap_id, "name" => "new name!"})
- {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
-
- %{user: user, update_data: update_data, update: update}
- end
-
- test "it updates the user", %{user: user, update: update} do
- {:ok, _, _} = SideEffects.handle(update)
- user = User.get_by_id(user.id)
- assert user.name == "new name!"
- end
-
- test "it uses a given changeset to update", %{user: user, update: update} do
- changeset = Ecto.Changeset.change(user, %{default_scope: "direct"})
-
- assert user.default_scope == "public"
- {:ok, _, _} = SideEffects.handle(update, user_update_changeset: changeset)
- user = User.get_by_id(user.id)
- assert user.default_scope == "direct"
- end
- end
-
- describe "delete objects" do
- setup do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
- {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
- {:ok, favorite} = CommonAPI.favorite(user, post.id)
- object = Object.normalize(post)
- {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
- {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
- {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
- {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
-
- %{
- user: user,
- delete: delete,
- post: post,
- object: object,
- delete_user: delete_user,
- op: op,
- favorite: favorite
- }
- end
-
- test "it handles object deletions", %{
- delete: delete,
- post: post,
- object: object,
- user: user,
- op: op,
- favorite: favorite
- } do
- with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
- stream_out: fn _ -> nil end,
- stream_out_participations: fn _, _ -> nil end do
- {:ok, delete, _} = SideEffects.handle(delete)
- user = User.get_cached_by_ap_id(object.data["actor"])
-
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
- end
-
- object = Object.get_by_id(object.id)
- assert object.data["type"] == "Tombstone"
- refute Activity.get_by_id(post.id)
- refute Activity.get_by_id(favorite.id)
-
- user = User.get_by_id(user.id)
- assert user.note_count == 0
-
- object = Object.normalize(op.data["object"], false)
-
- assert object.data["repliesCount"] == 0
- end
-
- test "it handles object deletions when the object itself has been pruned", %{
- delete: delete,
- post: post,
- object: object,
- user: user,
- op: op
- } do
- with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
- stream_out: fn _ -> nil end,
- stream_out_participations: fn _, _ -> nil end do
- {:ok, delete, _} = SideEffects.handle(delete)
- user = User.get_cached_by_ap_id(object.data["actor"])
-
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
- end
-
- object = Object.get_by_id(object.id)
- assert object.data["type"] == "Tombstone"
- refute Activity.get_by_id(post.id)
-
- user = User.get_by_id(user.id)
- assert user.note_count == 0
-
- object = Object.normalize(op.data["object"], false)
-
- assert object.data["repliesCount"] == 0
- end
-
- test "it handles user deletions", %{delete_user: delete, user: user} do
- {:ok, _delete, _} = SideEffects.handle(delete)
- ObanHelpers.perform_all()
-
- assert User.get_cached_by_ap_id(user.ap_id).deactivated
- end
-
- test "it logs issues with objects deletion", %{
- delete: delete,
- object: object
- } do
- {:ok, object} =
- object
- |> Object.change(%{data: Map.delete(object.data, "actor")})
- |> Repo.update()
-
- Object.invalid_object_cache(object)
-
- assert capture_log(fn ->
- {:error, :no_object_actor} = SideEffects.handle(delete)
- end) =~ "object doesn't have an actor"
- end
- end
-
- describe "EmojiReact objects" do
- setup do
- poster = insert(:user)
- user = insert(:user)
-
- {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
-
- {:ok, emoji_react_data, []} = Builder.emoji_react(user, post.object, "👌")
- {:ok, emoji_react, _meta} = ActivityPub.persist(emoji_react_data, local: true)
-
- %{emoji_react: emoji_react, user: user, poster: poster}
- end
-
- test "adds the reaction to the object", %{emoji_react: emoji_react, user: user} do
- {:ok, emoji_react, _} = SideEffects.handle(emoji_react)
- object = Object.get_by_ap_id(emoji_react.data["object"])
-
- assert object.data["reaction_count"] == 1
- assert ["👌", [user.ap_id]] in object.data["reactions"]
- end
-
- test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
- {:ok, emoji_react, _} = SideEffects.handle(emoji_react)
- assert Repo.get_by(Notification, user_id: poster.id, activity_id: emoji_react.id)
- end
- end
-
- describe "delete users with confirmation pending" do
- setup do
- user = insert(:user, confirmation_pending: true)
- {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
- {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
- {:ok, delete: delete_user, user: user}
- end
-
- test "when activation is not required", %{delete: delete, user: user} do
- clear_config([:instance, :account_activation_required], false)
- {:ok, _, _} = SideEffects.handle(delete)
- ObanHelpers.perform_all()
-
- assert User.get_cached_by_id(user.id).deactivated
- end
-
- test "when activation is required", %{delete: delete, user: user} do
- clear_config([:instance, :account_activation_required], true)
- {:ok, _, _} = SideEffects.handle(delete)
- ObanHelpers.perform_all()
-
- refute User.get_cached_by_id(user.id)
- end
- end
-
- describe "Undo objects" do
- setup do
- poster = insert(:user)
- user = insert(:user)
- {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
- {:ok, like} = CommonAPI.favorite(user, post.id)
- {:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
- {:ok, announce} = CommonAPI.repeat(post.id, user)
- {:ok, block} = CommonAPI.block(user, poster)
-
- {:ok, undo_data, _meta} = Builder.undo(user, like)
- {:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
-
- {:ok, undo_data, _meta} = Builder.undo(user, reaction)
- {:ok, reaction_undo, _meta} = ActivityPub.persist(undo_data, local: true)
-
- {:ok, undo_data, _meta} = Builder.undo(user, announce)
- {:ok, announce_undo, _meta} = ActivityPub.persist(undo_data, local: true)
-
- {:ok, undo_data, _meta} = Builder.undo(user, block)
- {:ok, block_undo, _meta} = ActivityPub.persist(undo_data, local: true)
-
- %{
- like_undo: like_undo,
- post: post,
- like: like,
- reaction_undo: reaction_undo,
- reaction: reaction,
- announce_undo: announce_undo,
- announce: announce,
- block_undo: block_undo,
- block: block,
- poster: poster,
- user: user
- }
- end
-
- test "deletes the original block", %{
- block_undo: block_undo,
- block: block
- } do
- {:ok, _block_undo, _meta} = SideEffects.handle(block_undo)
-
- refute Activity.get_by_id(block.id)
- end
-
- test "unblocks the blocked user", %{block_undo: block_undo, block: block} do
- blocker = User.get_by_ap_id(block.data["actor"])
- blocked = User.get_by_ap_id(block.data["object"])
-
- {:ok, _block_undo, _} = SideEffects.handle(block_undo)
- refute User.blocks?(blocker, blocked)
- end
-
- test "an announce undo removes the announce from the object", %{
- announce_undo: announce_undo,
- post: post
- } do
- {:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
-
- object = Object.get_by_ap_id(post.data["object"])
-
- assert object.data["announcement_count"] == 0
- assert object.data["announcements"] == []
- end
-
- test "deletes the original announce", %{announce_undo: announce_undo, announce: announce} do
- {:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
- refute Activity.get_by_id(announce.id)
- end
-
- test "a reaction undo removes the reaction from the object", %{
- reaction_undo: reaction_undo,
- post: post
- } do
- {:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
-
- object = Object.get_by_ap_id(post.data["object"])
-
- assert object.data["reaction_count"] == 0
- assert object.data["reactions"] == []
- end
-
- test "deletes the original reaction", %{reaction_undo: reaction_undo, reaction: reaction} do
- {:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
- refute Activity.get_by_id(reaction.id)
- end
-
- test "a like undo removes the like from the object", %{like_undo: like_undo, post: post} do
- {:ok, _like_undo, _} = SideEffects.handle(like_undo)
-
- object = Object.get_by_ap_id(post.data["object"])
-
- assert object.data["like_count"] == 0
- assert object.data["likes"] == []
- end
-
- test "deletes the original like", %{like_undo: like_undo, like: like} do
- {:ok, _like_undo, _} = SideEffects.handle(like_undo)
- refute Activity.get_by_id(like.id)
- end
- end
-
- describe "like objects" do
- setup do
- poster = insert(:user)
- user = insert(:user)
- {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
-
- {:ok, like_data, _meta} = Builder.like(user, post.object)
- {:ok, like, _meta} = ActivityPub.persist(like_data, local: true)
-
- %{like: like, user: user, poster: poster}
- end
-
- test "add the like to the original object", %{like: like, user: user} do
- {:ok, like, _} = SideEffects.handle(like)
- object = Object.get_by_ap_id(like.data["object"])
- assert object.data["like_count"] == 1
- assert user.ap_id in object.data["likes"]
- end
-
- test "creates a notification", %{like: like, poster: poster} do
- {:ok, like, _} = SideEffects.handle(like)
- assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id)
- end
- end
-
- describe "creation of ChatMessages" do
- test "notifies the recipient" do
- author = insert(:user, local: false)
- recipient = insert(:user, local: true)
-
- {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
-
- {:ok, create_activity_data, _meta} =
- Builder.create(author, chat_message_data["id"], [recipient.ap_id])
-
- {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
-
- {:ok, _create_activity, _meta} =
- SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
-
- assert Repo.get_by(Notification, user_id: recipient.id, activity_id: create_activity.id)
- end
-
- test "it streams the created ChatMessage" do
- author = insert(:user, local: true)
- recipient = insert(:user, local: true)
-
- {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
-
- {:ok, create_activity_data, _meta} =
- Builder.create(author, chat_message_data["id"], [recipient.ap_id])
-
- {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
-
- {:ok, _create_activity, meta} =
- SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
-
- assert [_, _] = meta[:streamables]
- end
-
- test "it creates a Chat and MessageReferences for the local users and bumps the unread count, except for the author" do
- author = insert(:user, local: true)
- recipient = insert(:user, local: true)
-
- {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
-
- {:ok, create_activity_data, _meta} =
- Builder.create(author, chat_message_data["id"], [recipient.ap_id])
-
- {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
-
- with_mocks([
- {
- Pleroma.Web.Streamer,
- [],
- [
- stream: fn _, _ -> nil end
- ]
- },
- {
- Pleroma.Web.Push,
- [],
- [
- send: fn _ -> nil end
- ]
- }
- ]) do
- {:ok, _create_activity, meta} =
- SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
-
- # The notification gets created
- assert [notification] = meta[:notifications]
- assert notification.activity_id == create_activity.id
-
- # But it is not sent out
- refute called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
- refute called(Pleroma.Web.Push.send(notification))
-
- # Same for the user chat stream
- assert [{topics, _}, _] = meta[:streamables]
- assert topics == ["user", "user:pleroma_chat"]
- refute called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
-
- chat = Chat.get(author.id, recipient.ap_id)
-
- [cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all()
-
- assert cm_ref.object.data["content"] == "hey"
- assert cm_ref.unread == false
-
- chat = Chat.get(recipient.id, author.ap_id)
-
- [cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all()
-
- assert cm_ref.object.data["content"] == "hey"
- assert cm_ref.unread == true
- end
- end
-
- test "it creates a Chat for the local users and bumps the unread count" do
- author = insert(:user, local: false)
- recipient = insert(:user, local: true)
-
- {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
-
- {:ok, create_activity_data, _meta} =
- Builder.create(author, chat_message_data["id"], [recipient.ap_id])
-
- {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
-
- {:ok, _create_activity, _meta} =
- SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
-
- # An object is created
- assert Object.get_by_ap_id(chat_message_data["id"])
-
- # The remote user won't get a chat
- chat = Chat.get(author.id, recipient.ap_id)
- refute chat
-
- # The local user will get a chat
- chat = Chat.get(recipient.id, author.ap_id)
- assert chat
-
- author = insert(:user, local: true)
- recipient = insert(:user, local: true)
-
- {:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
-
- {:ok, create_activity_data, _meta} =
- Builder.create(author, chat_message_data["id"], [recipient.ap_id])
-
- {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
-
- {:ok, _create_activity, _meta} =
- SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
-
- # Both users are local and get the chat
- chat = Chat.get(author.id, recipient.ap_id)
- assert chat
-
- chat = Chat.get(recipient.id, author.ap_id)
- assert chat
- end
- end
-
- describe "announce objects" do
- setup do
- poster = insert(:user)
- user = insert(:user)
- {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
- {:ok, private_post} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
-
- {:ok, announce_data, _meta} = Builder.announce(user, post.object, public: true)
-
- {:ok, private_announce_data, _meta} =
- Builder.announce(user, private_post.object, public: false)
-
- {:ok, relay_announce_data, _meta} =
- Builder.announce(Pleroma.Web.ActivityPub.Relay.get_actor(), post.object, public: true)
-
- {:ok, announce, _meta} = ActivityPub.persist(announce_data, local: true)
- {:ok, private_announce, _meta} = ActivityPub.persist(private_announce_data, local: true)
- {:ok, relay_announce, _meta} = ActivityPub.persist(relay_announce_data, local: true)
-
- %{
- announce: announce,
- user: user,
- poster: poster,
- private_announce: private_announce,
- relay_announce: relay_announce
- }
- end
-
- test "adds the announce to the original object", %{announce: announce, user: user} do
- {:ok, announce, _} = SideEffects.handle(announce)
- object = Object.get_by_ap_id(announce.data["object"])
- assert object.data["announcement_count"] == 1
- assert user.ap_id in object.data["announcements"]
- end
-
- test "does not add the announce to the original object if the actor is a service actor", %{
- relay_announce: announce
- } do
- {:ok, announce, _} = SideEffects.handle(announce)
- object = Object.get_by_ap_id(announce.data["object"])
- assert object.data["announcement_count"] == nil
- end
-
- test "creates a notification", %{announce: announce, poster: poster} do
- {:ok, announce, _} = SideEffects.handle(announce)
- assert Repo.get_by(Notification, user_id: poster.id, activity_id: announce.id)
- end
-
- test "it streams out the announce", %{announce: announce} do
- with_mocks([
- {
- Pleroma.Web.Streamer,
- [],
- [
- stream: fn _, _ -> nil end
- ]
- },
- {
- Pleroma.Web.Push,
- [],
- [
- send: fn _ -> nil end
- ]
- }
- ]) do
- {:ok, announce, _} = SideEffects.handle(announce)
-
- assert called(
- Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], announce)
- )
-
- assert called(Pleroma.Web.Push.send(:_))
- end
- end
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/accept_handling_test.exs b/test/web/activity_pub/transmogrifier/accept_handling_test.exs
deleted file mode 100644
index 77d468f5c..000000000
--- a/test/web/activity_pub/transmogrifier/accept_handling_test.exs
+++ /dev/null
@@ -1,91 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.AcceptHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "it works for incoming accepts which were pre-accepted" do
- follower = insert(:user)
- followed = insert(:user)
-
- {:ok, follower} = User.follow(follower, followed)
- assert User.following?(follower, followed) == true
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
-
- accept_data =
- File.read!("test/fixtures/mastodon-accept-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", followed.ap_id)
-
- object =
- accept_data["object"]
- |> Map.put("actor", follower.ap_id)
- |> Map.put("id", follow_activity.data["id"])
-
- accept_data = Map.put(accept_data, "object", object)
-
- {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
- refute activity.local
-
- assert activity.data["object"] == follow_activity.data["id"]
-
- assert activity.data["id"] == accept_data["id"]
-
- follower = User.get_cached_by_id(follower.id)
-
- assert User.following?(follower, followed) == true
- end
-
- test "it works for incoming accepts which are referenced by IRI only" do
- follower = insert(:user)
- followed = insert(:user, locked: true)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
-
- accept_data =
- File.read!("test/fixtures/mastodon-accept-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", followed.ap_id)
- |> Map.put("object", follow_activity.data["id"])
-
- {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
- assert activity.data["object"] == follow_activity.data["id"]
-
- follower = User.get_cached_by_id(follower.id)
-
- assert User.following?(follower, followed) == true
-
- follower = User.get_by_id(follower.id)
- assert follower.following_count == 1
-
- followed = User.get_by_id(followed.id)
- assert followed.follower_count == 1
- end
-
- test "it fails for incoming accepts which cannot be correlated" do
- follower = insert(:user)
- followed = insert(:user, locked: true)
-
- accept_data =
- File.read!("test/fixtures/mastodon-accept-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", followed.ap_id)
-
- accept_data =
- Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
-
- {:error, _} = Transmogrifier.handle_incoming(accept_data)
-
- follower = User.get_cached_by_id(follower.id)
-
- refute User.following?(follower, followed) == true
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/announce_handling_test.exs b/test/web/activity_pub/transmogrifier/announce_handling_test.exs
deleted file mode 100644
index e895636b5..000000000
--- a/test/web/activity_pub/transmogrifier/announce_handling_test.exs
+++ /dev/null
@@ -1,172 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "it works for incoming honk announces" do
- user = insert(:user, ap_id: "https://honktest/u/test", local: false)
- other_user = insert(:user)
- {:ok, post} = CommonAPI.post(other_user, %{status: "bonkeronk"})
-
- announce = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "actor" => "https://honktest/u/test",
- "id" => "https://honktest/u/test/bonk/1793M7B9MQ48847vdx",
- "object" => post.data["object"],
- "published" => "2019-06-25T19:33:58Z",
- "to" => "https://www.w3.org/ns/activitystreams#Public",
- "type" => "Announce"
- }
-
- {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(announce)
-
- object = Object.get_by_ap_id(post.data["object"])
-
- assert length(object.data["announcements"]) == 1
- assert user.ap_id in object.data["announcements"]
- end
-
- test "it works for incoming announces with actor being inlined (kroeg)" do
- data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Poison.decode!()
-
- _user = insert(:user, local: false, ap_id: data["actor"]["id"])
- other_user = insert(:user)
-
- {:ok, post} = CommonAPI.post(other_user, %{status: "kroegeroeg"})
-
- data =
- data
- |> put_in(["object", "id"], post.data["object"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "https://puckipedia.com/"
- end
-
- test "it works for incoming announces, fetching the announced object" do
- data =
- File.read!("test/fixtures/mastodon-announce.json")
- |> Poison.decode!()
- |> Map.put("object", "http://mastodon.example.org/users/admin/statuses/99541947525187367")
-
- Tesla.Mock.mock(fn
- %{method: :get} ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/mastodon-note-object.json")}
- end)
-
- _user = insert(:user, local: false, ap_id: data["actor"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Announce"
-
- assert data["id"] ==
- "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
-
- assert data["object"] ==
- "http://mastodon.example.org/users/admin/statuses/99541947525187367"
-
- assert(Activity.get_create_by_object_ap_id(data["object"]))
- end
-
- @tag capture_log: true
- test "it works for incoming announces with an existing activity" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
-
- data =
- File.read!("test/fixtures/mastodon-announce.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- _user = insert(:user, local: false, ap_id: data["actor"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Announce"
-
- assert data["id"] ==
- "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
-
- assert data["object"] == activity.data["object"]
-
- assert Activity.get_create_by_object_ap_id(data["object"]).id == activity.id
- end
-
- # Ignore inlined activities for now
- @tag skip: true
- test "it works for incoming announces with an inlined activity" do
- data =
- File.read!("test/fixtures/mastodon-announce-private.json")
- |> Poison.decode!()
-
- _user =
- insert(:user,
- local: false,
- ap_id: data["actor"],
- follower_address: data["actor"] <> "/followers"
- )
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Announce"
-
- assert data["id"] ==
- "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
-
- object = Object.normalize(data["object"])
-
- assert object.data["id"] == "http://mastodon.example.org/@admin/99541947525187368"
- assert object.data["content"] == "this is a private toot"
- end
-
- @tag capture_log: true
- test "it rejects incoming announces with an inlined activity from another origin" do
- Tesla.Mock.mock(fn
- %{method: :get} -> %Tesla.Env{status: 404, body: ""}
- end)
-
- data =
- File.read!("test/fixtures/bogus-mastodon-announce.json")
- |> Poison.decode!()
-
- _user = insert(:user, local: false, ap_id: data["actor"])
-
- assert {:error, e} = Transmogrifier.handle_incoming(data)
- end
-
- test "it does not clobber the addressing on announce activities" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
-
- data =
- File.read!("test/fixtures/mastodon-announce.json")
- |> Poison.decode!()
- |> Map.put("object", Object.normalize(activity).data["id"])
- |> Map.put("to", ["http://mastodon.example.org/users/admin/followers"])
- |> Map.put("cc", [])
-
- _user =
- insert(:user,
- local: false,
- ap_id: data["actor"],
- follower_address: "http://mastodon.example.org/users/admin/followers"
- )
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["to"] == ["http://mastodon.example.org/users/admin/followers"]
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/answer_handling_test.exs b/test/web/activity_pub/transmogrifier/answer_handling_test.exs
deleted file mode 100644
index 0f6605c3f..000000000
--- a/test/web/activity_pub/transmogrifier/answer_handling_test.exs
+++ /dev/null
@@ -1,78 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnswerHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "incoming, rewrites Note to Answer and increments vote counters" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "suya...",
- poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
- })
-
- object = Object.normalize(activity)
-
- data =
- File.read!("test/fixtures/mastodon-vote.json")
- |> Poison.decode!()
- |> Kernel.put_in(["to"], user.ap_id)
- |> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
- |> Kernel.put_in(["object", "to"], user.ap_id)
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
- answer_object = Object.normalize(activity)
- assert answer_object.data["type"] == "Answer"
- assert answer_object.data["inReplyTo"] == object.data["id"]
-
- new_object = Object.get_by_ap_id(object.data["id"])
- assert new_object.data["replies_count"] == object.data["replies_count"]
-
- assert Enum.any?(
- new_object.data["oneOf"],
- fn
- %{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true
- _ -> false
- end
- )
- end
-
- test "outgoing, rewrites Answer to Note" do
- user = insert(:user)
-
- {:ok, poll_activity} =
- CommonAPI.post(user, %{
- status: "suya...",
- poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
- })
-
- poll_object = Object.normalize(poll_activity)
- # TODO: Replace with CommonAPI vote creation when implemented
- data =
- File.read!("test/fixtures/mastodon-vote.json")
- |> Poison.decode!()
- |> Kernel.put_in(["to"], user.ap_id)
- |> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"])
- |> Kernel.put_in(["object", "to"], user.ap_id)
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
- {:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert data["object"]["type"] == "Note"
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/audio_handling_test.exs b/test/web/activity_pub/transmogrifier/audio_handling_test.exs
deleted file mode 100644
index 0636d00c5..000000000
--- a/test/web/activity_pub/transmogrifier/audio_handling_test.exs
+++ /dev/null
@@ -1,83 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
- use Oban.Testing, repo: Pleroma.Repo
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Transmogrifier
-
- import Pleroma.Factory
-
- test "it works for incoming listens" do
- _user = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
-
- 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 "Funkwhale Audio object" do
- Tesla.Mock.mock(fn
- %{url: "https://channels.tests.funkwhale.audio/federation/actors/compositions"} ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json")
- }
- end)
-
- data = File.read!("test/fixtures/tesla_mock/funkwhale_create_audio.json") |> Poison.decode!()
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- assert object = Object.normalize(activity, false)
-
- assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
-
- assert object.data["cc"] == []
-
- assert object.data["url"] == "https://channels.tests.funkwhale.audio/library/tracks/74"
-
- assert object.data["attachment"] == [
- %{
- "mediaType" => "audio/ogg",
- "type" => "Link",
- "name" => nil,
- "url" => [
- %{
- "href" =>
- "https://channels.tests.funkwhale.audio/api/v1/listen/3901e5d8-0445-49d5-9711-e096cf32e515/?upload=42342395-0208-4fee-a38d-259a6dae0871&download=false",
- "mediaType" => "audio/ogg",
- "type" => "Link"
- }
- ]
- }
- ]
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/block_handling_test.exs b/test/web/activity_pub/transmogrifier/block_handling_test.exs
deleted file mode 100644
index 71f1a0ed5..000000000
--- a/test/web/activity_pub/transmogrifier/block_handling_test.exs
+++ /dev/null
@@ -1,63 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.BlockHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
-
- import Pleroma.Factory
-
- test "it works for incoming blocks" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-block-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- blocker = insert(:user, ap_id: data["actor"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["type"] == "Block"
- assert data["object"] == user.ap_id
- assert data["actor"] == "http://mastodon.example.org/users/admin"
-
- assert User.blocks?(blocker, user)
- end
-
- test "incoming blocks successfully tear down any follow relationship" do
- blocker = insert(:user)
- blocked = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-block-activity.json")
- |> Poison.decode!()
- |> Map.put("object", blocked.ap_id)
- |> Map.put("actor", blocker.ap_id)
-
- {:ok, blocker} = User.follow(blocker, blocked)
- {:ok, blocked} = User.follow(blocked, blocker)
-
- assert User.following?(blocker, blocked)
- assert User.following?(blocked, blocker)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["type"] == "Block"
- assert data["object"] == blocked.ap_id
- assert data["actor"] == blocker.ap_id
-
- blocker = User.get_cached_by_ap_id(data["actor"])
- blocked = User.get_cached_by_ap_id(data["object"])
-
- assert User.blocks?(blocker, blocked)
-
- refute User.following?(blocker, blocked)
- refute User.following?(blocked, blocker)
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/chat_message_test.exs b/test/web/activity_pub/transmogrifier/chat_message_test.exs
deleted file mode 100644
index 31274c067..000000000
--- a/test/web/activity_pub/transmogrifier/chat_message_test.exs
+++ /dev/null
@@ -1,171 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.ChatMessageTest do
- use Pleroma.DataCase
-
- import Pleroma.Factory
-
- alias Pleroma.Activity
- alias Pleroma.Chat
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Transmogrifier
-
- describe "handle_incoming" do
- test "handles chonks with attachment" do
- data = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "actor" => "https://honk.tedunangst.com/u/tedu",
- "id" => "https://honk.tedunangst.com/u/tedu/honk/x6gt8X8PcyGkQcXxzg1T",
- "object" => %{
- "attachment" => [
- %{
- "mediaType" => "image/jpeg",
- "name" => "298p3RG7j27tfsZ9RQ.jpg",
- "summary" => "298p3RG7j27tfsZ9RQ.jpg",
- "type" => "Document",
- "url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
- }
- ],
- "attributedTo" => "https://honk.tedunangst.com/u/tedu",
- "content" => "",
- "id" => "https://honk.tedunangst.com/u/tedu/chonk/26L4wl5yCbn4dr4y1b",
- "published" => "2020-05-18T01:13:03Z",
- "to" => [
- "https://dontbulling.me/users/lain"
- ],
- "type" => "ChatMessage"
- },
- "published" => "2020-05-18T01:13:03Z",
- "to" => [
- "https://dontbulling.me/users/lain"
- ],
- "type" => "Create"
- }
-
- _user = insert(:user, ap_id: data["actor"])
- _user = insert(:user, ap_id: hd(data["to"]))
-
- assert {:ok, _activity} = Transmogrifier.handle_incoming(data)
- end
-
- test "it rejects messages that don't contain content" do
- data =
- File.read!("test/fixtures/create-chat-message.json")
- |> Poison.decode!()
-
- object =
- data["object"]
- |> Map.delete("content")
-
- data =
- data
- |> Map.put("object", object)
-
- _author =
- insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
-
- _recipient =
- insert(:user,
- ap_id: List.first(data["to"]),
- local: true,
- last_refreshed_at: DateTime.utc_now()
- )
-
- {:error, _} = Transmogrifier.handle_incoming(data)
- end
-
- test "it rejects messages that don't concern local users" do
- data =
- File.read!("test/fixtures/create-chat-message.json")
- |> Poison.decode!()
-
- _author =
- insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
-
- _recipient =
- insert(:user,
- ap_id: List.first(data["to"]),
- local: false,
- last_refreshed_at: DateTime.utc_now()
- )
-
- {:error, _} = Transmogrifier.handle_incoming(data)
- end
-
- test "it rejects messages where the `to` field of activity and object don't match" do
- data =
- File.read!("test/fixtures/create-chat-message.json")
- |> Poison.decode!()
-
- author = insert(:user, ap_id: data["actor"])
- _recipient = insert(:user, ap_id: List.first(data["to"]))
-
- data =
- data
- |> Map.put("to", author.ap_id)
-
- assert match?({:error, _}, Transmogrifier.handle_incoming(data))
- refute Object.get_by_ap_id(data["object"]["id"])
- end
-
- test "it fetches the actor if they aren't in our system" do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
-
- data =
- File.read!("test/fixtures/create-chat-message.json")
- |> Poison.decode!()
- |> Map.put("actor", "http://mastodon.example.org/users/admin")
- |> put_in(["object", "actor"], "http://mastodon.example.org/users/admin")
-
- _recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
-
- {:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data)
- end
-
- test "it doesn't work for deactivated users" do
- data =
- File.read!("test/fixtures/create-chat-message.json")
- |> Poison.decode!()
-
- _author =
- insert(:user,
- ap_id: data["actor"],
- local: false,
- last_refreshed_at: DateTime.utc_now(),
- deactivated: true
- )
-
- _recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
-
- assert {:error, _} = Transmogrifier.handle_incoming(data)
- end
-
- test "it inserts it and creates a chat" do
- data =
- File.read!("test/fixtures/create-chat-message.json")
- |> Poison.decode!()
-
- author =
- insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
-
- recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
-
- {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data)
- assert activity.local == false
-
- assert activity.actor == author.ap_id
- assert activity.recipients == [recipient.ap_id, author.ap_id]
-
- %Object{} = object = Object.get_by_ap_id(activity.data["object"])
-
- assert object
- assert object.data["content"] == "You expected a cute girl? Too bad. alert(&#39;XSS&#39;)"
- assert match?(%{"firefox" => _}, object.data["emoji"])
-
- refute Chat.get(author.id, recipient.ap_id)
- assert Chat.get(recipient.id, author.ap_id)
- end
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/delete_handling_test.exs b/test/web/activity_pub/transmogrifier/delete_handling_test.exs
deleted file mode 100644
index c9a53918c..000000000
--- a/test/web/activity_pub/transmogrifier/delete_handling_test.exs
+++ /dev/null
@@ -1,114 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do
- use Oban.Testing, repo: Pleroma.Repo
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
-
- import Pleroma.Factory
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "it works for incoming deletes" do
- activity = insert(:note_activity)
- deleting_user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-delete.json")
- |> Poison.decode!()
- |> Map.put("actor", deleting_user.ap_id)
- |> put_in(["object", "id"], activity.data["object"])
-
- {:ok, %Activity{actor: actor, local: false, data: %{"id" => id}}} =
- Transmogrifier.handle_incoming(data)
-
- assert id == data["id"]
-
- # We delete the Create activity because we base our timelines on it.
- # This should be changed after we unify objects and activities
- refute Activity.get_by_id(activity.id)
- assert actor == deleting_user.ap_id
-
- # Objects are replaced by a tombstone object.
- object = Object.normalize(activity.data["object"])
- assert object.data["type"] == "Tombstone"
- end
-
- test "it works for incoming when the object has been pruned" do
- activity = insert(:note_activity)
-
- {:ok, object} =
- Object.normalize(activity.data["object"])
- |> Repo.delete()
-
- Cachex.del(:object_cache, "object:#{object.data["id"]}")
-
- deleting_user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-delete.json")
- |> Poison.decode!()
- |> Map.put("actor", deleting_user.ap_id)
- |> put_in(["object", "id"], activity.data["object"])
-
- {:ok, %Activity{actor: actor, local: false, data: %{"id" => id}}} =
- Transmogrifier.handle_incoming(data)
-
- assert id == data["id"]
-
- # We delete the Create activity because we base our timelines on it.
- # This should be changed after we unify objects and activities
- refute Activity.get_by_id(activity.id)
- assert actor == deleting_user.ap_id
- end
-
- test "it fails for incoming deletes with spoofed origin" do
- activity = insert(:note_activity)
- %{ap_id: ap_id} = insert(:user, ap_id: "https://gensokyo.2hu/users/raymoo")
-
- data =
- File.read!("test/fixtures/mastodon-delete.json")
- |> Poison.decode!()
- |> Map.put("actor", ap_id)
- |> put_in(["object", "id"], activity.data["object"])
-
- assert match?({:error, _}, Transmogrifier.handle_incoming(data))
- end
-
- @tag capture_log: true
- test "it works for incoming user deletes" do
- %{ap_id: ap_id} = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
-
- data =
- File.read!("test/fixtures/mastodon-delete-user.json")
- |> Poison.decode!()
-
- {:ok, _} = Transmogrifier.handle_incoming(data)
- ObanHelpers.perform_all()
-
- assert User.get_cached_by_ap_id(ap_id).deactivated
- end
-
- test "it fails for incoming user deletes with spoofed origin" do
- %{ap_id: ap_id} = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-delete-user.json")
- |> Poison.decode!()
- |> Map.put("actor", ap_id)
-
- assert match?({:error, _}, Transmogrifier.handle_incoming(data))
-
- assert User.get_cached_by_ap_id(ap_id)
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/emoji_react_handling_test.exs b/test/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
deleted file mode 100644
index 0fb056b50..000000000
--- a/test/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
+++ /dev/null
@@ -1,61 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "it works for incoming emoji reactions" do
- user = insert(:user)
- other_user = insert(:user, local: false)
- {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
-
- data =
- File.read!("test/fixtures/emoji-reaction.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
- |> Map.put("actor", other_user.ap_id)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == other_user.ap_id
- assert data["type"] == "EmojiReact"
- assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2"
- assert data["object"] == activity.data["object"]
- assert data["content"] == "👌"
-
- object = Object.get_by_ap_id(data["object"])
-
- assert object.data["reaction_count"] == 1
- assert match?([["👌", _]], object.data["reactions"])
- end
-
- test "it reject invalid emoji reactions" do
- user = insert(:user)
- other_user = insert(:user, local: false)
- {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
-
- data =
- File.read!("test/fixtures/emoji-reaction-too-long.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
- |> Map.put("actor", other_user.ap_id)
-
- assert {:error, _} = Transmogrifier.handle_incoming(data)
-
- data =
- File.read!("test/fixtures/emoji-reaction-no-emoji.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
- |> Map.put("actor", other_user.ap_id)
-
- assert {:error, _} = Transmogrifier.handle_incoming(data)
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/event_handling_test.exs b/test/web/activity_pub/transmogrifier/event_handling_test.exs
deleted file mode 100644
index 7f1ef2cbd..000000000
--- a/test/web/activity_pub/transmogrifier/event_handling_test.exs
+++ /dev/null
@@ -1,40 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.EventHandlingTest do
- use Oban.Testing, repo: Pleroma.Repo
- use Pleroma.DataCase
-
- alias Pleroma.Object.Fetcher
-
- test "Mobilizon Event object" do
- Tesla.Mock.mock(fn
- %{url: "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"} ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/fixtures/tesla_mock/mobilizon.org-event.json")
- }
-
- %{url: "https://mobilizon.org/@tcit"} ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/fixtures/tesla_mock/mobilizon.org-user.json")
- }
- end)
-
- assert {:ok, object} =
- Fetcher.fetch_object_from_id(
- "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
- )
-
- assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
- assert object.data["cc"] == []
-
- assert object.data["url"] ==
- "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
-
- assert object.data["published"] == "2019-12-17T11:33:56Z"
- assert object.data["name"] == "Mobilizon Launching Party"
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
deleted file mode 100644
index 757d90941..000000000
--- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs
+++ /dev/null
@@ -1,208 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
- use Pleroma.DataCase
- alias Pleroma.Activity
- alias Pleroma.Notification
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.ActivityPub.Utils
-
- import Pleroma.Factory
- import Ecto.Query
- import Mock
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- describe "handle_incoming" do
- setup do: clear_config([:user, :deny_follow_blocked])
-
- test "it works for osada follow request" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/osada-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "https://apfed.club/channel/indio"
- assert data["type"] == "Follow"
- assert data["id"] == "https://apfed.club/follow/9"
-
- activity = Repo.get(Activity, activity.id)
- assert activity.data["state"] == "accept"
- assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
- end
-
- test "it works for incoming follow requests" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Follow"
- assert data["id"] == "http://mastodon.example.org/users/admin#follows/2"
-
- activity = Repo.get(Activity, activity.id)
- assert activity.data["state"] == "accept"
- assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
-
- [notification] = Notification.for_user(user)
- assert notification.type == "follow"
- end
-
- test "with locked accounts, it does create a Follow, but not an Accept" do
- user = insert(:user, locked: true)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["state"] == "pending"
-
- refute User.following?(User.get_cached_by_ap_id(data["actor"]), user)
-
- accepts =
- from(
- a in Activity,
- where: fragment("?->>'type' = ?", a.data, "Accept")
- )
- |> Repo.all()
-
- assert Enum.empty?(accepts)
-
- [notification] = Notification.for_user(user)
- assert notification.type == "follow_request"
- end
-
- test "it works for follow requests when you are already followed, creating a new accept activity" do
- # This is important because the remote might have the wrong idea about the
- # current follow status. This can lead to instance A thinking that x@A is
- # followed by y@B, but B thinks they are not. In this case, the follow can
- # never go through again because it will never get an Accept.
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
-
- accepts =
- from(
- a in Activity,
- where: fragment("?->>'type' = ?", a.data, "Accept")
- )
- |> Repo.all()
-
- assert length(accepts) == 1
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("id", String.replace(data["id"], "2", "3"))
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
-
- accepts =
- from(
- a in Activity,
- where: fragment("?->>'type' = ?", a.data, "Accept")
- )
- |> Repo.all()
-
- assert length(accepts) == 2
- end
-
- test "it rejects incoming follow requests from blocked users when deny_follow_blocked is enabled" do
- Pleroma.Config.put([:user, :deny_follow_blocked], true)
-
- user = insert(:user)
- {:ok, target} = User.get_or_fetch("http://mastodon.example.org/users/admin")
-
- {:ok, _user_relationship} = User.block(user, target)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
-
- %Activity{} = activity = Activity.get_by_ap_id(id)
-
- assert activity.data["state"] == "reject"
- end
-
- test "it rejects incoming follow requests if the following errors for some reason" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- with_mock Pleroma.User, [:passthrough], follow: fn _, _, _ -> {:error, :testing} end do
- {:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
-
- %Activity{} = activity = Activity.get_by_ap_id(id)
-
- assert activity.data["state"] == "reject"
- end
- end
-
- test "it works for incoming follow requests from hubzilla" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/hubzilla-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
- |> Utils.normalize_params()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "https://hubzilla.example.org/channel/kaniini"
- assert data["type"] == "Follow"
- assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2"
- assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
- end
-
- test "it works for incoming follows to locked account" do
- pending_follower = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
- user = insert(:user, locked: true)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["type"] == "Follow"
- assert data["object"] == user.ap_id
- assert data["state"] == "pending"
- assert data["actor"] == "http://mastodon.example.org/users/admin"
-
- assert [^pending_follower] = User.get_follow_requests(user)
- end
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/like_handling_test.exs b/test/web/activity_pub/transmogrifier/like_handling_test.exs
deleted file mode 100644
index 53fe1d550..000000000
--- a/test/web/activity_pub/transmogrifier/like_handling_test.exs
+++ /dev/null
@@ -1,78 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.LikeHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "it works for incoming likes" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
-
- data =
- File.read!("test/fixtures/mastodon-like.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- _actor = insert(:user, ap_id: data["actor"], local: false)
-
- {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- refute Enum.empty?(activity.recipients)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Like"
- assert data["id"] == "http://mastodon.example.org/users/admin#likes/2"
- assert data["object"] == activity.data["object"]
- end
-
- test "it works for incoming misskey likes, turning them into EmojiReacts" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
-
- data =
- File.read!("test/fixtures/misskey-like.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- _actor = insert(:user, ap_id: data["actor"], local: false)
-
- {:ok, %Activity{data: activity_data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert activity_data["actor"] == data["actor"]
- assert activity_data["type"] == "EmojiReact"
- assert activity_data["id"] == data["id"]
- assert activity_data["object"] == activity.data["object"]
- assert activity_data["content"] == "🍮"
- end
-
- test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReacts" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
-
- data =
- File.read!("test/fixtures/misskey-like.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
- |> Map.put("_misskey_reaction", "⭐")
-
- _actor = insert(:user, ap_id: data["actor"], local: false)
-
- {:ok, %Activity{data: activity_data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert activity_data["actor"] == data["actor"]
- assert activity_data["type"] == "EmojiReact"
- assert activity_data["id"] == data["id"]
- assert activity_data["object"] == activity.data["object"]
- assert activity_data["content"] == "⭐"
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/question_handling_test.exs b/test/web/activity_pub/transmogrifier/question_handling_test.exs
deleted file mode 100644
index c82361828..000000000
--- a/test/web/activity_pub/transmogrifier/question_handling_test.exs
+++ /dev/null
@@ -1,125 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "Mastodon Question activity" do
- data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- object = Object.normalize(activity, false)
-
- assert object.data["url"] == "https://mastodon.sdf.org/@rinpatch/102070944809637304"
-
- assert object.data["closed"] == "2019-05-11T09:03:36Z"
-
- assert object.data["context"] == activity.data["context"]
-
- assert object.data["context"] ==
- "tag:mastodon.sdf.org,2019-05-10:objectId=15095122:objectType=Conversation"
-
- assert object.data["context_id"]
-
- assert object.data["anyOf"] == []
-
- assert Enum.sort(object.data["oneOf"]) ==
- Enum.sort([
- %{
- "name" => "25 char limit is dumb",
- "replies" => %{"totalItems" => 0, "type" => "Collection"},
- "type" => "Note"
- },
- %{
- "name" => "Dunno",
- "replies" => %{"totalItems" => 0, "type" => "Collection"},
- "type" => "Note"
- },
- %{
- "name" => "Everyone knows that!",
- "replies" => %{"totalItems" => 1, "type" => "Collection"},
- "type" => "Note"
- },
- %{
- "name" => "I can't even fit a funny",
- "replies" => %{"totalItems" => 1, "type" => "Collection"},
- "type" => "Note"
- }
- ])
-
- user = insert(:user)
-
- {:ok, reply_activity} = CommonAPI.post(user, %{status: "hewwo", in_reply_to_id: activity.id})
-
- reply_object = Object.normalize(reply_activity, false)
-
- assert reply_object.data["context"] == object.data["context"]
- assert reply_object.data["context_id"] == object.data["context_id"]
- end
-
- test "Mastodon Question activity with HTML tags in plaintext" do
- options = [
- %{
- "type" => "Note",
- "name" => "<input type=\"date\">",
- "replies" => %{"totalItems" => 0, "type" => "Collection"}
- },
- %{
- "type" => "Note",
- "name" => "<input type=\"date\"/>",
- "replies" => %{"totalItems" => 0, "type" => "Collection"}
- },
- %{
- "type" => "Note",
- "name" => "<input type=\"date\" />",
- "replies" => %{"totalItems" => 1, "type" => "Collection"}
- },
- %{
- "type" => "Note",
- "name" => "<input type=\"date\"></input>",
- "replies" => %{"totalItems" => 1, "type" => "Collection"}
- }
- ]
-
- data =
- File.read!("test/fixtures/mastodon-question-activity.json")
- |> Poison.decode!()
- |> Kernel.put_in(["object", "oneOf"], options)
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(activity, false)
-
- assert Enum.sort(object.data["oneOf"]) == Enum.sort(options)
- end
-
- test "returns an error if received a second time" do
- data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
-
- assert {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- assert {:error, {:validate_object, {:error, _}}} = Transmogrifier.handle_incoming(data)
- end
-
- test "accepts a Question with no content" do
- data =
- File.read!("test/fixtures/mastodon-question-activity.json")
- |> Poison.decode!()
- |> Kernel.put_in(["object", "content"], "")
-
- assert {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/reject_handling_test.exs b/test/web/activity_pub/transmogrifier/reject_handling_test.exs
deleted file mode 100644
index 7592fbe1c..000000000
--- a/test/web/activity_pub/transmogrifier/reject_handling_test.exs
+++ /dev/null
@@ -1,67 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.RejectHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "it fails for incoming rejects which cannot be correlated" do
- follower = insert(:user)
- followed = insert(:user, locked: true)
-
- accept_data =
- File.read!("test/fixtures/mastodon-reject-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", followed.ap_id)
-
- accept_data =
- Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
-
- {:error, _} = Transmogrifier.handle_incoming(accept_data)
-
- follower = User.get_cached_by_id(follower.id)
-
- refute User.following?(follower, followed) == true
- end
-
- test "it works for incoming rejects which are referenced by IRI only" do
- follower = insert(:user)
- followed = insert(:user, locked: true)
-
- {:ok, follower} = User.follow(follower, followed)
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
-
- assert User.following?(follower, followed) == true
-
- reject_data =
- File.read!("test/fixtures/mastodon-reject-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", followed.ap_id)
- |> Map.put("object", follow_activity.data["id"])
-
- {:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data)
-
- follower = User.get_cached_by_id(follower.id)
-
- assert User.following?(follower, followed) == false
- end
-
- test "it rejects activities without a valid ID" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
- |> Map.put("id", "")
-
- :error = Transmogrifier.handle_incoming(data)
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/undo_handling_test.exs b/test/web/activity_pub/transmogrifier/undo_handling_test.exs
deleted file mode 100644
index 8683f7135..000000000
--- a/test/web/activity_pub/transmogrifier/undo_handling_test.exs
+++ /dev/null
@@ -1,185 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.UndoHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "it works for incoming emoji reaction undos" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hello"})
- {:ok, reaction_activity} = CommonAPI.react_with_emoji(activity.id, user, "👌")
-
- data =
- File.read!("test/fixtures/mastodon-undo-like.json")
- |> Poison.decode!()
- |> Map.put("object", reaction_activity.data["id"])
- |> Map.put("actor", user.ap_id)
-
- {:ok, activity} = Transmogrifier.handle_incoming(data)
-
- assert activity.actor == user.ap_id
- assert activity.data["id"] == data["id"]
- assert activity.data["type"] == "Undo"
- end
-
- test "it returns an error for incoming unlikes wihout a like activity" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "leave a like pls"})
-
- data =
- File.read!("test/fixtures/mastodon-undo-like.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- assert Transmogrifier.handle_incoming(data) == :error
- end
-
- test "it works for incoming unlikes with an existing like activity" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "leave a like pls"})
-
- like_data =
- File.read!("test/fixtures/mastodon-like.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- _liker = insert(:user, ap_id: like_data["actor"], local: false)
-
- {:ok, %Activity{data: like_data, local: false}} = Transmogrifier.handle_incoming(like_data)
-
- data =
- File.read!("test/fixtures/mastodon-undo-like.json")
- |> Poison.decode!()
- |> Map.put("object", like_data)
- |> Map.put("actor", like_data["actor"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Undo"
- assert data["id"] == "http://mastodon.example.org/users/admin#likes/2/undo"
- assert data["object"] == "http://mastodon.example.org/users/admin#likes/2"
-
- note = Object.get_by_ap_id(like_data["object"])
- assert note.data["like_count"] == 0
- assert note.data["likes"] == []
- end
-
- test "it works for incoming unlikes with an existing like activity and a compact object" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "leave a like pls"})
-
- like_data =
- File.read!("test/fixtures/mastodon-like.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- _liker = insert(:user, ap_id: like_data["actor"], local: false)
-
- {:ok, %Activity{data: like_data, local: false}} = Transmogrifier.handle_incoming(like_data)
-
- data =
- File.read!("test/fixtures/mastodon-undo-like.json")
- |> Poison.decode!()
- |> Map.put("object", like_data["id"])
- |> Map.put("actor", like_data["actor"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
- assert data["type"] == "Undo"
- assert data["id"] == "http://mastodon.example.org/users/admin#likes/2/undo"
- assert data["object"] == "http://mastodon.example.org/users/admin#likes/2"
- end
-
- test "it works for incoming unannounces with an existing notice" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
-
- announce_data =
- File.read!("test/fixtures/mastodon-announce.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
-
- _announcer = insert(:user, ap_id: announce_data["actor"], local: false)
-
- {:ok, %Activity{data: announce_data, local: false}} =
- Transmogrifier.handle_incoming(announce_data)
-
- data =
- File.read!("test/fixtures/mastodon-undo-announce.json")
- |> Poison.decode!()
- |> Map.put("object", announce_data)
- |> Map.put("actor", announce_data["actor"])
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["type"] == "Undo"
-
- assert data["object"] ==
- "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
- end
-
- test "it works for incoming unfollows with an existing follow" do
- user = insert(:user)
-
- follow_data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- _follower = insert(:user, ap_id: follow_data["actor"], local: false)
-
- {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(follow_data)
-
- data =
- File.read!("test/fixtures/mastodon-unfollow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", follow_data)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["type"] == "Undo"
- assert data["object"]["type"] == "Follow"
- assert data["object"]["object"] == user.ap_id
- assert data["actor"] == "http://mastodon.example.org/users/admin"
-
- refute User.following?(User.get_cached_by_ap_id(data["actor"]), user)
- end
-
- test "it works for incoming unblocks with an existing block" do
- user = insert(:user)
-
- block_data =
- File.read!("test/fixtures/mastodon-block-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- _blocker = insert(:user, ap_id: block_data["actor"], local: false)
-
- {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(block_data)
-
- data =
- File.read!("test/fixtures/mastodon-unblock-activity.json")
- |> Poison.decode!()
- |> Map.put("object", block_data)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- assert data["type"] == "Undo"
- assert data["object"] == block_data["id"]
-
- blocker = User.get_cached_by_ap_id(data["actor"])
-
- refute User.blocks?(blocker, user)
- end
-end
diff --git a/test/web/activity_pub/transmogrifier/user_update_handling_test.exs b/test/web/activity_pub/transmogrifier/user_update_handling_test.exs
deleted file mode 100644
index 64636656c..000000000
--- a/test/web/activity_pub/transmogrifier/user_update_handling_test.exs
+++ /dev/null
@@ -1,159 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.Transmogrifier.UserUpdateHandlingTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
-
- import Pleroma.Factory
-
- test "it works for incoming update activities" do
- user = insert(:user, local: false)
-
- update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
-
- object =
- update_data["object"]
- |> Map.put("actor", user.ap_id)
- |> Map.put("id", user.ap_id)
-
- update_data =
- update_data
- |> Map.put("actor", user.ap_id)
- |> Map.put("object", object)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
-
- assert data["id"] == update_data["id"]
-
- user = User.get_cached_by_ap_id(data["actor"])
- assert user.name == "gargle"
-
- assert user.avatar["url"] == [
- %{
- "href" =>
- "https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
- }
- ]
-
- assert user.banner["url"] == [
- %{
- "href" =>
- "https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
- }
- ]
-
- assert user.bio == "<p>Some bio</p>"
- end
-
- test "it works with alsoKnownAs" do
- %{ap_id: actor} = insert(:user, local: false)
-
- assert User.get_cached_by_ap_id(actor).also_known_as == []
-
- {:ok, _activity} =
- "test/fixtures/mastodon-update.json"
- |> File.read!()
- |> Poison.decode!()
- |> Map.put("actor", actor)
- |> Map.update!("object", fn object ->
- object
- |> Map.put("actor", actor)
- |> Map.put("id", actor)
- |> Map.put("alsoKnownAs", [
- "http://mastodon.example.org/users/foo",
- "http://example.org/users/bar"
- ])
- end)
- |> Transmogrifier.handle_incoming()
-
- assert User.get_cached_by_ap_id(actor).also_known_as == [
- "http://mastodon.example.org/users/foo",
- "http://example.org/users/bar"
- ]
- end
-
- test "it works with custom profile fields" do
- user = insert(:user, local: false)
-
- assert user.fields == []
-
- update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
-
- object =
- update_data["object"]
- |> Map.put("actor", user.ap_id)
- |> Map.put("id", user.ap_id)
-
- update_data =
- update_data
- |> Map.put("actor", user.ap_id)
- |> Map.put("object", object)
-
- {:ok, _update_activity} = Transmogrifier.handle_incoming(update_data)
-
- user = User.get_cached_by_ap_id(user.ap_id)
-
- assert user.fields == [
- %{"name" => "foo", "value" => "updated"},
- %{"name" => "foo1", "value" => "updated"}
- ]
-
- Pleroma.Config.put([:instance, :max_remote_account_fields], 2)
-
- update_data =
- update_data
- |> put_in(["object", "attachment"], [
- %{"name" => "foo", "type" => "PropertyValue", "value" => "bar"},
- %{"name" => "foo11", "type" => "PropertyValue", "value" => "bar11"},
- %{"name" => "foo22", "type" => "PropertyValue", "value" => "bar22"}
- ])
- |> Map.put("id", update_data["id"] <> ".")
-
- {:ok, _} = Transmogrifier.handle_incoming(update_data)
-
- user = User.get_cached_by_ap_id(user.ap_id)
-
- assert user.fields == [
- %{"name" => "foo", "value" => "updated"},
- %{"name" => "foo1", "value" => "updated"}
- ]
-
- update_data =
- update_data
- |> put_in(["object", "attachment"], [])
- |> Map.put("id", update_data["id"] <> ".")
-
- {:ok, _} = Transmogrifier.handle_incoming(update_data)
-
- user = User.get_cached_by_ap_id(user.ap_id)
-
- assert user.fields == []
- end
-
- test "it works for incoming update activities which lock the account" do
- user = insert(:user, local: false)
-
- update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
-
- object =
- update_data["object"]
- |> Map.put("actor", user.ap_id)
- |> Map.put("id", user.ap_id)
- |> Map.put("manuallyApprovesFollowers", true)
-
- update_data =
- update_data
- |> Map.put("actor", user.ap_id)
- |> Map.put("object", object)
-
- {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(update_data)
-
- user = User.get_cached_by_ap_id(user.ap_id)
- assert user.locked == true
- end
-end
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
deleted file mode 100644
index 3fa41b0c7..000000000
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ /dev/null
@@ -1,1379 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
- use Oban.Testing, repo: Pleroma.Repo
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Object.Fetcher
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.AdminAPI.AccountView
- alias Pleroma.Web.CommonAPI
-
- import Mock
- import Pleroma.Factory
- import ExUnit.CaptureLog
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup do: clear_config([:instance, :max_remote_account_fields])
-
- describe "handle_incoming" do
- test "it works for incoming notices with tag not being an array (kroeg)" do
- data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(data["object"])
-
- assert object.data["emoji"] == %{
- "icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png"
- }
-
- data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(data["object"])
-
- assert "test" in object.data["tag"]
- end
-
- test "it works for incoming notices with url not being a string (prismo)" do
- data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(data["object"])
-
- assert object.data["url"] == "https://prismo.news/posts/83"
- end
-
- test "it cleans up incoming notices which are not really DMs" do
- user = insert(:user)
- other_user = insert(:user)
-
- to = [user.ap_id, other_user.ap_id]
-
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
- |> Map.put("to", to)
- |> Map.put("cc", [])
-
- object =
- data["object"]
- |> Map.put("to", to)
- |> Map.put("cc", [])
-
- data = Map.put(data, "object", object)
-
- {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- assert data["to"] == []
- assert data["cc"] == to
-
- object_data = Object.normalize(activity).data
-
- assert object_data["to"] == []
- assert object_data["cc"] == to
- end
-
- test "it ignores an incoming notice if we already have it" do
- activity = insert(:note_activity)
-
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
- |> Map.put("object", Object.normalize(activity).data)
-
- {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
-
- assert activity == returned_activity
- end
-
- @tag capture_log: true
- test "it fetches reply-to activities if we don't have them" do
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
-
- object =
- data["object"]
- |> Map.put("inReplyTo", "https://shitposter.club/notice/2827873")
-
- data = Map.put(data, "object", object)
- {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
- returned_object = Object.normalize(returned_activity, false)
-
- assert activity =
- Activity.get_create_by_object_ap_id(
- "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
- )
-
- assert returned_object.data["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
- end
-
- test "it does not fetch reply-to activities beyond max replies depth limit" do
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
-
- object =
- data["object"]
- |> Map.put("inReplyTo", "https://shitposter.club/notice/2827873")
-
- data = Map.put(data, "object", object)
-
- with_mock Pleroma.Web.Federator,
- allowed_thread_distance?: fn _ -> false end do
- {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
-
- returned_object = Object.normalize(returned_activity, false)
-
- refute Activity.get_create_by_object_ap_id(
- "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
- )
-
- assert returned_object.data["inReplyToAtomUri"] ==
- "https://shitposter.club/notice/2827873"
- end
- end
-
- test "it does not crash if the object in inReplyTo can't be fetched" do
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
-
- object =
- data["object"]
- |> Map.put("inReplyTo", "https://404.site/whatever")
-
- data =
- data
- |> Map.put("object", object)
-
- assert capture_log(fn ->
- {:ok, _returned_activity} = Transmogrifier.handle_incoming(data)
- end) =~ "[warn] Couldn't fetch \"https://404.site/whatever\", error: nil"
- end
-
- test "it does not work for deactivated users" do
- data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
-
- insert(:user, ap_id: data["actor"], deactivated: true)
-
- assert {:error, _} = Transmogrifier.handle_incoming(data)
- end
-
- test "it works for incoming notices" do
- data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["id"] ==
- "http://mastodon.example.org/users/admin/statuses/99512778738411822/activity"
-
- assert data["context"] ==
- "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
-
- assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
-
- assert data["cc"] == [
- "http://mastodon.example.org/users/admin/followers",
- "http://localtesting.pleroma.lol/users/lain"
- ]
-
- assert data["actor"] == "http://mastodon.example.org/users/admin"
-
- object_data = Object.normalize(data["object"]).data
-
- assert object_data["id"] ==
- "http://mastodon.example.org/users/admin/statuses/99512778738411822"
-
- assert object_data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
-
- assert object_data["cc"] == [
- "http://mastodon.example.org/users/admin/followers",
- "http://localtesting.pleroma.lol/users/lain"
- ]
-
- assert object_data["actor"] == "http://mastodon.example.org/users/admin"
- assert object_data["attributedTo"] == "http://mastodon.example.org/users/admin"
-
- assert object_data["context"] ==
- "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
-
- assert object_data["sensitive"] == true
-
- user = User.get_cached_by_ap_id(object_data["actor"])
-
- assert user.note_count == 1
- end
-
- test "it works for incoming notices with hashtags" do
- data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(data["object"])
-
- assert Enum.at(object.data["tag"], 2) == "moo"
- end
-
- test "it works for incoming notices with contentMap" do
- data =
- File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(data["object"])
-
- assert object.data["content"] ==
- "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>"
- end
-
- test "it works for incoming notices with to/cc not being an array (kroeg)" do
- data = File.read!("test/fixtures/kroeg-post-activity.json") |> Poison.decode!()
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
- object = Object.normalize(data["object"])
-
- assert object.data["content"] ==
- "<p>henlo from my Psion netBook</p><p>message sent from my Psion netBook</p>"
- end
-
- test "it ensures that as:Public activities make it to their followers collection" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", user.ap_id)
- |> Map.put("to", ["https://www.w3.org/ns/activitystreams#Public"])
- |> Map.put("cc", [])
-
- object =
- data["object"]
- |> Map.put("attributedTo", user.ap_id)
- |> Map.put("to", ["https://www.w3.org/ns/activitystreams#Public"])
- |> Map.put("cc", [])
- |> Map.put("id", user.ap_id <> "/activities/12345678")
-
- data = Map.put(data, "object", object)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["cc"] == [User.ap_followers(user)]
- end
-
- test "it ensures that address fields become lists" do
- user = insert(:user)
-
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
- |> Map.put("actor", user.ap_id)
- |> Map.put("to", nil)
- |> Map.put("cc", nil)
-
- object =
- data["object"]
- |> Map.put("attributedTo", user.ap_id)
- |> Map.put("to", nil)
- |> Map.put("cc", nil)
- |> Map.put("id", user.ap_id <> "/activities/12345678")
-
- data = Map.put(data, "object", object)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert !is_nil(data["to"])
- assert !is_nil(data["cc"])
- end
-
- test "it strips internal likes" do
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
-
- likes = %{
- "first" =>
- "http://mastodon.example.org/objects/dbdbc507-52c8-490d-9b7c-1e1d52e5c132/likes?page=1",
- "id" => "http://mastodon.example.org/objects/dbdbc507-52c8-490d-9b7c-1e1d52e5c132/likes",
- "totalItems" => 3,
- "type" => "OrderedCollection"
- }
-
- object = Map.put(data["object"], "likes", likes)
- data = Map.put(data, "object", object)
-
- {:ok, %Activity{object: object}} = Transmogrifier.handle_incoming(data)
-
- refute Map.has_key?(object.data, "likes")
- end
-
- test "it strips internal reactions" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "📢")
-
- %{object: object} = Activity.get_by_id_with_object(activity.id)
- assert Map.has_key?(object.data, "reactions")
- assert Map.has_key?(object.data, "reaction_count")
-
- object_data = Transmogrifier.strip_internal_fields(object.data)
- refute Map.has_key?(object_data, "reactions")
- refute Map.has_key?(object_data, "reaction_count")
- end
-
- test "it works for incoming unfollows with an existing follow" do
- user = insert(:user)
-
- follow_data =
- File.read!("test/fixtures/mastodon-follow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", user.ap_id)
-
- {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(follow_data)
-
- data =
- File.read!("test/fixtures/mastodon-unfollow-activity.json")
- |> Poison.decode!()
- |> Map.put("object", follow_data)
-
- {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-
- assert data["type"] == "Undo"
- assert data["object"]["type"] == "Follow"
- assert data["object"]["object"] == user.ap_id
- assert data["actor"] == "http://mastodon.example.org/users/admin"
-
- refute User.following?(User.get_cached_by_ap_id(data["actor"]), user)
- end
-
- test "skip converting the content when it is nil" do
- object_id = "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe"
-
- {:ok, object} = Fetcher.fetch_and_contain_remote_object_from_id(object_id)
-
- result =
- Pleroma.Web.ActivityPub.Transmogrifier.fix_object(Map.merge(object, %{"content" => nil}))
-
- assert result["content"] == nil
- end
-
- test "it converts content of object to html" do
- object_id = "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe"
-
- {:ok, %{"content" => content_markdown}} =
- Fetcher.fetch_and_contain_remote_object_from_id(object_id)
-
- {:ok, %Pleroma.Object{data: %{"content" => content}} = object} =
- Fetcher.fetch_object_from_id(object_id)
-
- assert content_markdown ==
- "Support this and our other Michigan!/usr/group videos and meetings. Learn more at http://mug.org/membership\n\nTwenty Years in Jail: FreeBSD's Jails, Then and Now\n\nJails started as a limited virtualization system, but over the last two years they've..."
-
- assert content ==
- "<p>Support this and our other Michigan!/usr/group videos and meetings. Learn more at <a href=\"http://mug.org/membership\">http://mug.org/membership</a></p><p>Twenty Years in Jail: FreeBSD’s Jails, Then and Now</p><p>Jails started as a limited virtualization system, but over the last two years they’ve…</p>"
-
- assert object.data["mediaType"] == "text/html"
- end
-
- test "it remaps video URLs as attachments if necessary" do
- {:ok, object} =
- Fetcher.fetch_object_from_id(
- "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
- )
-
- assert object.data["url"] ==
- "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
-
- assert object.data["attachment"] == [
- %{
- "type" => "Link",
- "mediaType" => "video/mp4",
- "url" => [
- %{
- "href" =>
- "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
- "mediaType" => "video/mp4",
- "type" => "Link"
- }
- ]
- }
- ]
-
- {:ok, object} =
- Fetcher.fetch_object_from_id(
- "https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
- )
-
- assert object.data["attachment"] == [
- %{
- "type" => "Link",
- "mediaType" => "video/mp4",
- "url" => [
- %{
- "href" =>
- "https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4",
- "mediaType" => "video/mp4",
- "type" => "Link"
- }
- ]
- }
- ]
-
- assert object.data["url"] ==
- "https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
- end
-
- test "it accepts Flag activities" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
- object = Object.normalize(activity)
-
- note_obj = %{
- "type" => "Note",
- "id" => activity.data["id"],
- "content" => "test post",
- "published" => object.data["published"],
- "actor" => AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- }
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "cc" => [user.ap_id],
- "object" => [user.ap_id, activity.data["id"]],
- "type" => "Flag",
- "content" => "blocked AND reported!!!",
- "actor" => other_user.ap_id
- }
-
- assert {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- assert activity.data["object"] == [user.ap_id, note_obj]
- assert activity.data["content"] == "blocked AND reported!!!"
- assert activity.data["actor"] == other_user.ap_id
- assert activity.data["cc"] == [user.ap_id]
- end
-
- test "it correctly processes messages with non-array to field" do
- user = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => "https://www.w3.org/ns/activitystreams#Public",
- "type" => "Create",
- "object" => %{
- "content" => "blah blah blah",
- "type" => "Note",
- "attributedTo" => user.ap_id,
- "inReplyTo" => nil
- },
- "actor" => user.ap_id
- }
-
- assert {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["to"]
- end
-
- test "it correctly processes messages with non-array cc field" do
- user = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => user.follower_address,
- "cc" => "https://www.w3.org/ns/activitystreams#Public",
- "type" => "Create",
- "object" => %{
- "content" => "blah blah blah",
- "type" => "Note",
- "attributedTo" => user.ap_id,
- "inReplyTo" => nil
- },
- "actor" => user.ap_id
- }
-
- assert {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"]
- assert [user.follower_address] == activity.data["to"]
- end
-
- test "it correctly processes messages with weirdness in address fields" do
- user = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => [nil, user.follower_address],
- "cc" => ["https://www.w3.org/ns/activitystreams#Public", ["¿"]],
- "type" => "Create",
- "object" => %{
- "content" => "…",
- "type" => "Note",
- "attributedTo" => user.ap_id,
- "inReplyTo" => nil
- },
- "actor" => user.ap_id
- }
-
- assert {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"]
- assert [user.follower_address] == activity.data["to"]
- end
-
- test "it accepts Move activities" do
- old_user = insert(:user)
- new_user = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "type" => "Move",
- "actor" => old_user.ap_id,
- "object" => old_user.ap_id,
- "target" => new_user.ap_id
- }
-
- assert :error = Transmogrifier.handle_incoming(message)
-
- {:ok, _new_user} = User.update_and_set_cache(new_user, %{also_known_as: [old_user.ap_id]})
-
- assert {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(message)
- assert activity.actor == old_user.ap_id
- assert activity.data["actor"] == old_user.ap_id
- assert activity.data["object"] == old_user.ap_id
- assert activity.data["target"] == new_user.ap_id
- assert activity.data["type"] == "Move"
- end
- end
-
- describe "`handle_incoming/2`, Mastodon format `replies` handling" do
- setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
- setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
-
- setup do
- data =
- "test/fixtures/mastodon-post-activity.json"
- |> File.read!()
- |> Poison.decode!()
-
- items = get_in(data, ["object", "replies", "first", "items"])
- assert length(items) > 0
-
- %{data: data, items: items}
- end
-
- test "schedules background fetching of `replies` items if max thread depth limit allows", %{
- data: data,
- items: items
- } do
- Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 10)
-
- {:ok, _activity} = Transmogrifier.handle_incoming(data)
-
- for id <- items do
- job_args = %{"op" => "fetch_remote", "id" => id, "depth" => 1}
- assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args)
- end
- end
-
- test "does NOT schedule background fetching of `replies` beyond max thread depth limit allows",
- %{data: data} do
- Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0)
-
- {:ok, _activity} = Transmogrifier.handle_incoming(data)
-
- assert all_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker) == []
- end
- end
-
- describe "`handle_incoming/2`, Pleroma format `replies` handling" do
- setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
- setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
-
- setup do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "post1"})
-
- {:ok, reply1} =
- CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: activity.id})
-
- {:ok, reply2} =
- CommonAPI.post(user, %{status: "reply2", in_reply_to_status_id: activity.id})
-
- replies_uris = Enum.map([reply1, reply2], fn a -> a.object.data["id"] end)
-
- {:ok, federation_output} = Transmogrifier.prepare_outgoing(activity.data)
-
- Repo.delete(activity.object)
- Repo.delete(activity)
-
- %{federation_output: federation_output, replies_uris: replies_uris}
- end
-
- test "schedules background fetching of `replies` items if max thread depth limit allows", %{
- federation_output: federation_output,
- replies_uris: replies_uris
- } do
- Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 1)
-
- {:ok, _activity} = Transmogrifier.handle_incoming(federation_output)
-
- for id <- replies_uris do
- job_args = %{"op" => "fetch_remote", "id" => id, "depth" => 1}
- assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args)
- end
- end
-
- test "does NOT schedule background fetching of `replies` beyond max thread depth limit allows",
- %{federation_output: federation_output} do
- Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0)
-
- {:ok, _activity} = Transmogrifier.handle_incoming(federation_output)
-
- assert all_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker) == []
- end
- end
-
- describe "prepare outgoing" do
- test "it inlines private announced objects" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hey", visibility: "private"})
-
- {:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(announce_activity.data)
-
- assert modified["object"]["content"] == "hey"
- assert modified["object"]["actor"] == modified["object"]["attributedTo"]
- end
-
- test "it turns mentions into tags" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{status: "hey, @#{other_user.nickname}, how are ya? #2hu"})
-
- with_mock Pleroma.Notification,
- get_notified_from_activity: fn _, _ -> [] end do
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- object = modified["object"]
-
- expected_mention = %{
- "href" => other_user.ap_id,
- "name" => "@#{other_user.nickname}",
- "type" => "Mention"
- }
-
- expected_tag = %{
- "href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
- "type" => "Hashtag",
- "name" => "#2hu"
- }
-
- refute called(Pleroma.Notification.get_notified_from_activity(:_, :_))
- assert Enum.member?(object["tag"], expected_tag)
- assert Enum.member?(object["tag"], expected_mention)
- end
- end
-
- test "it adds the sensitive property" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#nsfw hey"})
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["object"]["sensitive"]
- end
-
- test "it adds the json-ld context and the conversation property" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["@context"] ==
- Pleroma.Web.ActivityPub.Utils.make_json_ld_header()["@context"]
-
- assert modified["object"]["conversation"] == modified["context"]
- end
-
- test "it sets the 'attributedTo' property to the actor of the object if it doesn't have one" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["object"]["actor"] == modified["object"]["attributedTo"]
- end
-
- test "it strips internal hashtag data" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#2hu"})
-
- expected_tag = %{
- "href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
- "type" => "Hashtag",
- "name" => "#2hu"
- }
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["object"]["tag"] == [expected_tag]
- end
-
- test "it strips internal fields" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#2hu :firefox:"})
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert length(modified["object"]["tag"]) == 2
-
- assert is_nil(modified["object"]["emoji"])
- assert is_nil(modified["object"]["like_count"])
- assert is_nil(modified["object"]["announcements"])
- assert is_nil(modified["object"]["announcement_count"])
- assert is_nil(modified["object"]["context_id"])
- end
-
- test "it strips internal fields of article" do
- activity = insert(:article_activity)
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert length(modified["object"]["tag"]) == 2
-
- assert is_nil(modified["object"]["emoji"])
- assert is_nil(modified["object"]["like_count"])
- assert is_nil(modified["object"]["announcements"])
- assert is_nil(modified["object"]["announcement_count"])
- assert is_nil(modified["object"]["context_id"])
- assert is_nil(modified["object"]["likes"])
- end
-
- test "the directMessage flag is present" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "2hu :moominmamma:"})
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["directMessage"] == false
-
- {:ok, activity} = CommonAPI.post(user, %{status: "@#{other_user.nickname} :moominmamma:"})
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["directMessage"] == false
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "@#{other_user.nickname} :moominmamma:",
- visibility: "direct"
- })
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert modified["directMessage"] == true
- end
-
- test "it strips BCC field" do
- user = insert(:user)
- {:ok, list} = Pleroma.List.create("foo", user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
-
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
-
- 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
- test "it upgrades a user to activitypub" do
- user =
- insert(:user, %{
- nickname: "rye@niu.moe",
- local: false,
- ap_id: "https://niu.moe/users/rye",
- follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
- })
-
- user_two = insert(:user)
- Pleroma.FollowingRelationship.follow(user_two, user, :follow_accept)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "test"})
- {:ok, unrelated_activity} = CommonAPI.post(user_two, %{status: "test"})
- assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
-
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 1
-
- {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
- ObanHelpers.perform_all()
-
- assert user.ap_enabled
- assert user.note_count == 1
- assert user.follower_address == "https://niu.moe/users/rye/followers"
- assert user.following_address == "https://niu.moe/users/rye/following"
-
- user = User.get_cached_by_id(user.id)
- assert user.note_count == 1
-
- activity = Activity.get_by_id(activity.id)
- assert user.follower_address in activity.recipients
-
- assert %{
- "url" => [
- %{
- "href" =>
- "https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
- }
- ]
- } = user.avatar
-
- assert %{
- "url" => [
- %{
- "href" =>
- "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
- }
- ]
- } = user.banner
-
- refute "..." in activity.recipients
-
- unrelated_activity = Activity.get_by_id(unrelated_activity.id)
- refute user.follower_address in unrelated_activity.recipients
-
- user_two = User.get_cached_by_id(user_two.id)
- assert User.following?(user_two, user)
- refute "..." in User.following(user_two)
- end
- end
-
- describe "actor rewriting" do
- test "it fixes the actor URL property to be a proper URI" do
- data = %{
- "url" => %{"href" => "http://example.com"}
- }
-
- rewritten = Transmogrifier.maybe_fix_user_object(data)
- assert rewritten["url"] == "http://example.com"
- end
- end
-
- describe "actor origin containment" do
- test "it rejects activities which reference objects with bogus origins" do
- data = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "id" => "http://mastodon.example.org/users/admin/activities/1234",
- "actor" => "http://mastodon.example.org/users/admin",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => "https://info.pleroma.site/activity.json",
- "type" => "Announce"
- }
-
- assert capture_log(fn ->
- {:error, _} = Transmogrifier.handle_incoming(data)
- end) =~ "Object containment failed"
- end
-
- test "it rejects activities which reference objects that have an incorrect attribution (variant 1)" do
- data = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "id" => "http://mastodon.example.org/users/admin/activities/1234",
- "actor" => "http://mastodon.example.org/users/admin",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => "https://info.pleroma.site/activity2.json",
- "type" => "Announce"
- }
-
- assert capture_log(fn ->
- {:error, _} = Transmogrifier.handle_incoming(data)
- end) =~ "Object containment failed"
- end
-
- test "it rejects activities which reference objects that have an incorrect attribution (variant 2)" do
- data = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "id" => "http://mastodon.example.org/users/admin/activities/1234",
- "actor" => "http://mastodon.example.org/users/admin",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "object" => "https://info.pleroma.site/activity3.json",
- "type" => "Announce"
- }
-
- assert capture_log(fn ->
- {:error, _} = Transmogrifier.handle_incoming(data)
- end) =~ "Object containment failed"
- end
- end
-
- describe "reserialization" do
- test "successfully reserializes a message with inReplyTo == nil" do
- user = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [],
- "type" => "Create",
- "object" => %{
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [],
- "type" => "Note",
- "content" => "Hi",
- "inReplyTo" => nil,
- "attributedTo" => user.ap_id
- },
- "actor" => user.ap_id
- }
-
- {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
- end
-
- test "successfully reserializes a message with AS2 objects in IR" do
- user = insert(:user)
-
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [],
- "type" => "Create",
- "object" => %{
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [],
- "type" => "Note",
- "content" => "Hi",
- "inReplyTo" => nil,
- "attributedTo" => user.ap_id,
- "tag" => [
- %{"name" => "#2hu", "href" => "http://example.com/2hu", "type" => "Hashtag"},
- %{"name" => "Bob", "href" => "http://example.com/bob", "type" => "Mention"}
- ]
- },
- "actor" => user.ap_id
- }
-
- {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
- end
- end
-
- describe "fix_explicit_addressing" do
- setup do
- user = insert(:user)
- [user: user]
- end
-
- test "moves non-explicitly mentioned actors to cc", %{user: user} do
- explicitly_mentioned_actors = [
- "https://pleroma.gold/users/user1",
- "https://pleroma.gold/user2"
- ]
-
- object = %{
- "actor" => user.ap_id,
- "to" => explicitly_mentioned_actors ++ ["https://social.beepboop.ga/users/dirb"],
- "cc" => [],
- "tag" =>
- Enum.map(explicitly_mentioned_actors, fn href ->
- %{"type" => "Mention", "href" => href}
- end)
- }
-
- fixed_object = Transmogrifier.fix_explicit_addressing(object)
- assert Enum.all?(explicitly_mentioned_actors, &(&1 in fixed_object["to"]))
- refute "https://social.beepboop.ga/users/dirb" in fixed_object["to"]
- assert "https://social.beepboop.ga/users/dirb" in fixed_object["cc"]
- end
-
- test "does not move actor's follower collection to cc", %{user: user} do
- object = %{
- "actor" => user.ap_id,
- "to" => [user.follower_address],
- "cc" => []
- }
-
- fixed_object = Transmogrifier.fix_explicit_addressing(object)
- assert user.follower_address in fixed_object["to"]
- refute user.follower_address in fixed_object["cc"]
- end
-
- test "removes recipient's follower collection from cc", %{user: user} do
- recipient = insert(:user)
-
- object = %{
- "actor" => user.ap_id,
- "to" => [recipient.ap_id, "https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [user.follower_address, recipient.follower_address]
- }
-
- fixed_object = Transmogrifier.fix_explicit_addressing(object)
-
- assert user.follower_address in fixed_object["cc"]
- refute recipient.follower_address in fixed_object["cc"]
- 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
- setup 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
-
- @tag capture_log: true
- 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["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
- assert capture_log(fn ->
- refute Transmogrifier.get_obj_helper("test-obj-id")
- end) =~ "Unsupported URI scheme"
- end
-
- @tag capture_log: true
- 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",
- "type" => "Document",
- "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",
- "type" => "Document",
- "url" => [
- %{
- "href" => "https://pe.er/stat-480.mp4",
- "mediaType" => "video/mp4",
- "type" => "Link"
- }
- ]
- },
- %{
- "mediaType" => "video/mp4",
- "type" => "Document",
- "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
-
- describe "set_replies/1" do
- setup do: clear_config([:activitypub, :note_replies_output_limit], 2)
-
- test "returns unmodified object if activity doesn't have self-replies" do
- data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
- assert Transmogrifier.set_replies(data) == data
- end
-
- test "sets `replies` collection with a limited number of self-replies" do
- [user, another_user] = insert_list(2, :user)
-
- {:ok, %{id: id1} = activity} = CommonAPI.post(user, %{status: "1"})
-
- {:ok, %{id: id2} = self_reply1} =
- CommonAPI.post(user, %{status: "self-reply 1", in_reply_to_status_id: id1})
-
- {:ok, self_reply2} =
- CommonAPI.post(user, %{status: "self-reply 2", in_reply_to_status_id: id1})
-
- # Assuming to _not_ be present in `replies` due to :note_replies_output_limit is set to 2
- {:ok, _} = CommonAPI.post(user, %{status: "self-reply 3", in_reply_to_status_id: id1})
-
- {:ok, _} =
- CommonAPI.post(user, %{
- status: "self-reply to self-reply",
- in_reply_to_status_id: id2
- })
-
- {:ok, _} =
- CommonAPI.post(another_user, %{
- status: "another user's reply",
- in_reply_to_status_id: id1
- })
-
- object = Object.normalize(activity)
- replies_uris = Enum.map([self_reply1, self_reply2], fn a -> a.object.data["id"] end)
-
- assert %{"type" => "Collection", "items" => ^replies_uris} =
- Transmogrifier.set_replies(object.data)["replies"]
- end
- end
-
- test "take_emoji_tags/1" do
- user = insert(:user, %{emoji: %{"firefox" => "https://example.org/firefox.png"}})
-
- assert Transmogrifier.take_emoji_tags(user) == [
- %{
- "icon" => %{"type" => "Image", "url" => "https://example.org/firefox.png"},
- "id" => "https://example.org/firefox.png",
- "name" => ":firefox:",
- "type" => "Emoji",
- "updated" => "1970-01-01T00:00:00Z"
- }
- ]
- end
-end
diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs
deleted file mode 100644
index d50213545..000000000
--- a/test/web/activity_pub/utils_test.exs
+++ /dev/null
@@ -1,548 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.UtilsTest do
- use Pleroma.DataCase
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.Utils
- alias Pleroma.Web.AdminAPI.AccountView
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- require Pleroma.Constants
-
- describe "fetch the latest Follow" do
- test "fetches the latest Follow activity" do
- %Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity)
- follower = User.get_cached_by_ap_id(activity.data["actor"])
- followed = User.get_cached_by_ap_id(activity.data["object"])
-
- assert activity == Utils.fetch_latest_follow(follower, followed)
- end
- end
-
- describe "determine_explicit_mentions()" do
- test "works with an object that has mentions" 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
-
- test "works with an object that does not have mentions" do
- object = %{
- "tag" => [
- %{"type" => "Hashtag", "href" => "https://example.com/tag/2hu", "name" => "2hu"}
- ]
- }
-
- assert Utils.determine_explicit_mentions(object) == []
- end
-
- test "works with an object that has mentions and other tags" do
- object = %{
- "tag" => [
- %{
- "type" => "Mention",
- "href" => "https://example.com/~alyssa",
- "name" => "Alyssa P. Hacker"
- },
- %{"type" => "Hashtag", "href" => "https://example.com/tag/2hu", "name" => "2hu"}
- ]
- }
-
- assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
- end
-
- test "works with an object that has no tags" do
- object = %{}
-
- assert Utils.determine_explicit_mentions(object) == []
- end
-
- test "works with an object that has only IR tags" do
- object = %{"tag" => ["2hu"]}
-
- 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_like_data" do
- setup do
- user = insert(:user)
- other_user = insert(:user)
- third_user = insert(:user)
- [user: user, other_user: other_user, third_user: third_user]
- end
-
- test "addresses actor's follower address if the activity is public", %{
- user: user,
- other_user: other_user,
- third_user: third_user
- } do
- expected_to = Enum.sort([user.ap_id, other_user.follower_address])
- expected_cc = Enum.sort(["https://www.w3.org/ns/activitystreams#Public", third_user.ap_id])
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status:
- "hey @#{other_user.nickname}, @#{third_user.nickname} how about beering together this weekend?"
- })
-
- %{"to" => to, "cc" => cc} = Utils.make_like_data(other_user, activity, nil)
- assert Enum.sort(to) == expected_to
- assert Enum.sort(cc) == expected_cc
- end
-
- test "does not adress actor's follower address if the activity is not public", %{
- user: user,
- other_user: other_user,
- third_user: third_user
- } do
- expected_to = Enum.sort([user.ap_id])
- expected_cc = [third_user.ap_id]
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "@#{other_user.nickname} @#{third_user.nickname} bought a new swimsuit!",
- visibility: "private"
- })
-
- %{"to" => to, "cc" => cc} = Utils.make_like_data(other_user, activity, nil)
- assert Enum.sort(to) == expected_to
- assert Enum.sort(cc) == expected_cc
- end
- end
-
- test "make_json_ld_header/0" do
- assert Utils.make_json_ld_header() == %{
- "@context" => [
- "https://www.w3.org/ns/activitystreams",
- "http://localhost:4001/schemas/litepub-0.1.jsonld",
- %{
- "@language" => "und"
- }
- ]
- }
- end
-
- describe "get_existing_votes" do
- test "fetches existing votes" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "How do I pronounce LaTeX?",
- poll: %{
- options: ["laytekh", "lahtekh", "latex"],
- expires_in: 20,
- multiple: true
- }
- })
-
- object = Object.normalize(activity)
- {:ok, votes, object} = CommonAPI.vote(other_user, object, [0, 1])
- assert Enum.sort(Utils.get_existing_votes(other_user.ap_id, object)) == Enum.sort(votes)
- end
-
- test "fetches only Create activities" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Are we living in a society?",
- poll: %{
- options: ["yes", "no"],
- expires_in: 20
- }
- })
-
- object = Object.normalize(activity)
- {:ok, [vote], object} = CommonAPI.vote(other_user, object, [0])
- {:ok, _activity} = CommonAPI.favorite(user, activity.id)
- [fetched_vote] = Utils.get_existing_votes(other_user.ap_id, object)
- assert fetched_vote.id == vote.id
- end
- end
-
- describe "update_follow_state_for_all/2" do
- test "updates the state of all Follow activities with the same actor and object" do
- user = insert(:user, locked: true)
- follower = insert(:user)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
-
- data =
- follow_activity_two.data
- |> Map.put("state", "accept")
-
- cng = Ecto.Changeset.change(follow_activity_two, data: data)
-
- {:ok, follow_activity_two} = Repo.update(cng)
-
- {:ok, follow_activity_two} =
- Utils.update_follow_state_for_all(follow_activity_two, "accept")
-
- assert refresh_record(follow_activity).data["state"] == "accept"
- assert refresh_record(follow_activity_two).data["state"] == "accept"
- end
- end
-
- describe "update_follow_state/2" do
- test "updates the state of the given follow activity" do
- user = insert(:user, locked: true)
- follower = insert(:user)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
-
- data =
- follow_activity_two.data
- |> Map.put("state", "accept")
-
- cng = Ecto.Changeset.change(follow_activity_two, data: data)
-
- {:ok, follow_activity_two} = Repo.update(cng)
-
- {:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject")
-
- assert refresh_record(follow_activity).data["state"] == "pending"
- assert refresh_record(follow_activity_two).data["state"] == "reject"
- end
- end
-
- describe "update_element_in_object/3" do
- test "updates likes" do
- user = insert(:user)
- activity = insert(:note_activity)
- object = Object.normalize(activity)
-
- assert {:ok, updated_object} =
- Utils.update_element_in_object(
- "like",
- [user.ap_id],
- object
- )
-
- assert updated_object.data["likes"] == [user.ap_id]
- assert updated_object.data["like_count"] == 1
- end
- end
-
- describe "add_like_to_object/2" do
- test "add actor to likes" do
- user = insert(:user)
- user2 = insert(:user)
- object = insert(:note)
-
- assert {:ok, updated_object} =
- Utils.add_like_to_object(
- %Activity{data: %{"actor" => user.ap_id}},
- object
- )
-
- assert updated_object.data["likes"] == [user.ap_id]
- assert updated_object.data["like_count"] == 1
-
- assert {:ok, updated_object2} =
- Utils.add_like_to_object(
- %Activity{data: %{"actor" => user2.ap_id}},
- updated_object
- )
-
- assert updated_object2.data["likes"] == [user2.ap_id, user.ap_id]
- assert updated_object2.data["like_count"] == 2
- end
- end
-
- describe "remove_like_from_object/2" do
- test "removes ap_id from likes" do
- user = insert(:user)
- user2 = insert(:user)
- object = insert(:note, data: %{"likes" => [user.ap_id, user2.ap_id], "like_count" => 2})
-
- assert {:ok, updated_object} =
- Utils.remove_like_from_object(
- %Activity{data: %{"actor" => user.ap_id}},
- object
- )
-
- assert updated_object.data["likes"] == [user2.ap_id]
- assert updated_object.data["like_count"] == 1
- end
- end
-
- describe "get_existing_like/2" do
- test "fetches existing like" do
- note_activity = insert(:note_activity)
- assert object = Object.normalize(note_activity)
-
- user = insert(:user)
- refute Utils.get_existing_like(user.ap_id, object)
- {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id)
-
- 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} = CommonAPI.repeat(note_activity.id, actor)
- 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{} = _} = CommonAPI.block(user1, user2)
- assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
- assert {:ok, %Activity{} = activity} = CommonAPI.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
- },
- %{}
- )
-
- note_obj = %{
- "type" => "Note",
- "id" => activity_ap_id,
- "content" => content,
- "published" => activity.object.data["published"],
- "actor" =>
- AccountView.render("show.json", %{user: target_account, skip_visibility_check: true})
- }
-
- assert %{
- "type" => "Flag",
- "content" => ^content,
- "context" => ^context,
- "object" => [^target_ap_id, ^note_obj],
- "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
-
- describe "get_cached_emoji_reactions/1" do
- test "returns the data or an emtpy list" do
- object = insert(:note)
- assert Utils.get_cached_emoji_reactions(object) == []
-
- object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]})
- assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]]
-
- object = insert(:note, data: %{"reactions" => %{}})
- assert Utils.get_cached_emoji_reactions(object) == []
- end
- end
-end
diff --git a/test/web/activity_pub/views/object_view_test.exs b/test/web/activity_pub/views/object_view_test.exs
deleted file mode 100644
index f0389845d..000000000
--- a/test/web/activity_pub/views/object_view_test.exs
+++ /dev/null
@@ -1,84 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.ObjectView
- alias Pleroma.Web.CommonAPI
-
- test "renders a note object" do
- note = insert(:note)
-
- result = ObjectView.render("object.json", %{object: note})
-
- assert result["id"] == note.data["id"]
- assert result["to"] == note.data["to"]
- assert result["content"] == note.data["content"]
- assert result["type"] == "Note"
- assert result["@context"]
- end
-
- test "renders a note activity" do
- note = insert(:note_activity)
- object = Object.normalize(note)
-
- result = ObjectView.render("object.json", %{object: note})
-
- assert result["id"] == note.data["id"]
- assert result["to"] == note.data["to"]
- assert result["object"]["type"] == "Note"
- assert result["object"]["content"] == object.data["content"]
- assert result["type"] == "Create"
- assert result["@context"]
- end
-
- describe "note activity's `replies` collection rendering" do
- setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
-
- test "renders `replies` collection for a note activity" do
- user = insert(:user)
- activity = insert(:note_activity, user: user)
-
- {:ok, self_reply1} =
- CommonAPI.post(user, %{status: "self-reply 1", in_reply_to_status_id: activity.id})
-
- replies_uris = [self_reply1.object.data["id"]]
- result = ObjectView.render("object.json", %{object: refresh_record(activity)})
-
- assert %{"type" => "Collection", "items" => ^replies_uris} =
- get_in(result, ["object", "replies"])
- end
- end
-
- test "renders a like activity" do
- note = insert(:note_activity)
- object = Object.normalize(note)
- user = insert(:user)
-
- {:ok, like_activity} = CommonAPI.favorite(user, note.id)
-
- result = ObjectView.render("object.json", %{object: like_activity})
-
- assert result["id"] == like_activity.data["id"]
- assert result["object"] == object.data["id"]
- assert result["type"] == "Like"
- end
-
- test "renders an announce activity" do
- note = insert(:note_activity)
- object = Object.normalize(note)
- user = insert(:user)
-
- {:ok, announce_activity} = CommonAPI.repeat(note.id, user)
-
- result = ObjectView.render("object.json", %{object: announce_activity})
-
- assert result["id"] == announce_activity.data["id"]
- assert result["object"] == object.data["id"]
- assert result["type"] == "Announce"
- end
-end
diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs
deleted file mode 100644
index 98c7c9d09..000000000
--- a/test/web/activity_pub/views/user_view_test.exs
+++ /dev/null
@@ -1,180 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.UserViewTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.UserView
- alias Pleroma.Web.CommonAPI
-
- test "Renders a user, including the public key" do
- user = insert(:user)
- {:ok, user} = User.ensure_keys_present(user)
-
- result = UserView.render("user.json", %{user: user})
-
- assert result["id"] == user.ap_id
- assert result["preferredUsername"] == user.nickname
-
- assert String.contains?(result["publicKey"]["publicKeyPem"], "BEGIN PUBLIC KEY")
- end
-
- test "Renders profile fields" do
- fields = [
- %{"name" => "foo", "value" => "bar"}
- ]
-
- {:ok, user} =
- insert(:user)
- |> User.update_changeset(%{fields: fields})
- |> User.update_and_set_cache()
-
- assert %{
- "attachment" => [%{"name" => "foo", "type" => "PropertyValue", "value" => "bar"}]
- } = UserView.render("user.json", %{user: user})
- end
-
- test "Renders with emoji tags" do
- user = insert(:user, 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)
-
- result = UserView.render("user.json", %{user: user})
- refute result["icon"]
- refute result["image"]
-
- user =
- insert(:user,
- avatar: %{"url" => [%{"href" => "https://someurl"}]},
- banner: %{"url" => [%{"href" => "https://somebanner"}]}
- )
-
- {:ok, user} = User.ensure_keys_present(user)
-
- result = UserView.render("user.json", %{user: user})
- assert result["icon"]["url"] == "https://someurl"
- assert result["image"]["url"] == "https://somebanner"
- end
-
- test "renders an invisible user with the invisible property set to true" do
- user = insert(:user, invisible: true)
-
- assert %{"invisible" => true} = UserView.render("service.json", %{user: user})
- end
-
- describe "endpoints" do
- test "local users have a usable endpoints structure" do
- user = insert(:user)
- {:ok, user} = User.ensure_keys_present(user)
-
- result = UserView.render("user.json", %{user: user})
-
- assert result["id"] == user.ap_id
-
- %{
- "sharedInbox" => _,
- "oauthAuthorizationEndpoint" => _,
- "oauthRegistrationEndpoint" => _,
- "oauthTokenEndpoint" => _
- } = result["endpoints"]
- end
-
- test "remote users have an empty endpoints structure" do
- user = insert(:user, local: false)
- {:ok, user} = User.ensure_keys_present(user)
-
- result = UserView.render("user.json", %{user: user})
-
- assert result["id"] == user.ap_id
- assert result["endpoints"] == %{}
- end
-
- test "instance users do not expose oAuth endpoints" do
- user = insert(:user, nickname: nil, local: true)
- {:ok, user} = User.ensure_keys_present(user)
-
- result = UserView.render("user.json", %{user: user})
-
- refute result["endpoints"]["oauthAuthorizationEndpoint"]
- refute result["endpoints"]["oauthRegistrationEndpoint"]
- refute result["endpoints"]["oauthTokenEndpoint"]
- end
- end
-
- describe "followers" do
- test "sets totalItems to zero when followers are hidden" 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})
- user = Map.merge(user, %{hide_followers_count: true, hide_followers: true})
- refute UserView.render("followers.json", %{user: user}) |> Map.has_key?("totalItems")
- 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})
- user = Map.merge(user, %{hide_followers_count: false, hide_followers: true})
- assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
- end
- end
-
- describe "following" do
- test "sets totalItems to zero when follows are hidden" 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})
- user = Map.merge(user, %{hide_follows_count: true, hide_follows: true})
- 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})
- user = Map.merge(user, %{hide_follows_count: false, hide_follows: true})
- assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
- end
- end
-
- describe "acceptsChatMessages" do
- test "it returns this value if it is set" do
- true_user = insert(:user, accepts_chat_messages: true)
- false_user = insert(:user, accepts_chat_messages: false)
- nil_user = insert(:user, accepts_chat_messages: nil)
-
- assert %{"capabilities" => %{"acceptsChatMessages" => true}} =
- UserView.render("user.json", user: true_user)
-
- assert %{"capabilities" => %{"acceptsChatMessages" => false}} =
- UserView.render("user.json", user: false_user)
-
- refute Map.has_key?(
- UserView.render("user.json", user: nil_user)["capabilities"],
- "acceptsChatMessages"
- )
- end
- end
-end
diff --git a/test/web/activity_pub/visibilty_test.exs b/test/web/activity_pub/visibilty_test.exs
deleted file mode 100644
index 8e9354c65..000000000
--- a/test/web/activity_pub/visibilty_test.exs
+++ /dev/null
@@ -1,230 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.VisibilityTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Web.ActivityPub.Visibility
- alias Pleroma.Web.CommonAPI
- import Pleroma.Factory
-
- setup do
- user = insert(:user)
- mentioned = insert(:user)
- following = insert(:user)
- unrelated = insert(:user)
- {:ok, following} = Pleroma.User.follow(following, user)
- {:ok, list} = Pleroma.List.create("foo", user)
-
- Pleroma.List.follow(list, unrelated)
-
- {:ok, public} =
- CommonAPI.post(user, %{status: "@#{mentioned.nickname}", visibility: "public"})
-
- {:ok, private} =
- CommonAPI.post(user, %{status: "@#{mentioned.nickname}", visibility: "private"})
-
- {:ok, direct} =
- CommonAPI.post(user, %{status: "@#{mentioned.nickname}", visibility: "direct"})
-
- {:ok, unlisted} =
- CommonAPI.post(user, %{status: "@#{mentioned.nickname}", visibility: "unlisted"})
-
- {:ok, list} =
- CommonAPI.post(user, %{
- status: "@#{mentioned.nickname}",
- visibility: "list:#{list.id}"
- })
-
- %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- user: user,
- mentioned: mentioned,
- following: following,
- unrelated: unrelated,
- list: list
- }
- end
-
- test "is_direct?", %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- list: list
- } do
- assert Visibility.is_direct?(direct)
- refute Visibility.is_direct?(public)
- refute Visibility.is_direct?(private)
- refute Visibility.is_direct?(unlisted)
- assert Visibility.is_direct?(list)
- end
-
- test "is_public?", %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- list: list
- } do
- refute Visibility.is_public?(direct)
- assert Visibility.is_public?(public)
- refute Visibility.is_public?(private)
- assert Visibility.is_public?(unlisted)
- refute Visibility.is_public?(list)
- end
-
- test "is_private?", %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- list: list
- } do
- refute Visibility.is_private?(direct)
- refute Visibility.is_private?(public)
- assert Visibility.is_private?(private)
- refute Visibility.is_private?(unlisted)
- refute Visibility.is_private?(list)
- end
-
- test "is_list?", %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- list: list
- } do
- refute Visibility.is_list?(direct)
- refute Visibility.is_list?(public)
- refute Visibility.is_list?(private)
- refute Visibility.is_list?(unlisted)
- assert Visibility.is_list?(list)
- end
-
- test "visible_for_user?", %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- user: user,
- mentioned: mentioned,
- following: following,
- unrelated: unrelated,
- list: list
- } do
- # All visible to author
-
- assert Visibility.visible_for_user?(public, user)
- assert Visibility.visible_for_user?(private, user)
- assert Visibility.visible_for_user?(unlisted, user)
- assert Visibility.visible_for_user?(direct, user)
- assert Visibility.visible_for_user?(list, user)
-
- # All visible to a mentioned user
-
- assert Visibility.visible_for_user?(public, mentioned)
- assert Visibility.visible_for_user?(private, mentioned)
- assert Visibility.visible_for_user?(unlisted, mentioned)
- assert Visibility.visible_for_user?(direct, mentioned)
- assert Visibility.visible_for_user?(list, mentioned)
-
- # DM not visible for just follower
-
- assert Visibility.visible_for_user?(public, following)
- assert Visibility.visible_for_user?(private, following)
- assert Visibility.visible_for_user?(unlisted, following)
- refute Visibility.visible_for_user?(direct, following)
- refute Visibility.visible_for_user?(list, following)
-
- # Public and unlisted visible for unrelated user
-
- assert Visibility.visible_for_user?(public, unrelated)
- assert Visibility.visible_for_user?(unlisted, unrelated)
- refute Visibility.visible_for_user?(private, unrelated)
- refute Visibility.visible_for_user?(direct, unrelated)
-
- # Visible for a list member
- assert Visibility.visible_for_user?(list, unrelated)
- end
-
- test "doesn't die when the user doesn't exist",
- %{
- direct: direct,
- user: user
- } do
- Repo.delete(user)
- Cachex.clear(:user_cache)
- refute Visibility.is_private?(direct)
- end
-
- test "get_visibility", %{
- public: public,
- private: private,
- direct: direct,
- unlisted: unlisted,
- list: list
- } do
- assert Visibility.get_visibility(public) == "public"
- assert Visibility.get_visibility(private) == "private"
- assert Visibility.get_visibility(direct) == "direct"
- assert Visibility.get_visibility(unlisted) == "unlisted"
- assert Visibility.get_visibility(list) == "list"
- end
-
- test "get_visibility with directMessage flag" do
- assert Visibility.get_visibility(%{data: %{"directMessage" => true}}) == "direct"
- end
-
- test "get_visibility with listMessage flag" do
- assert Visibility.get_visibility(%{data: %{"listMessage" => ""}}) == "list"
- end
-
- describe "entire_thread_visible_for_user?/2" do
- test "returns false if not found activity", %{user: user} do
- refute Visibility.entire_thread_visible_for_user?(%Activity{}, user)
- end
-
- test "returns true if activity hasn't 'Create' type", %{user: user} do
- activity = insert(:like_activity)
- assert Visibility.entire_thread_visible_for_user?(activity, user)
- end
-
- test "returns false when invalid recipients", %{user: user} do
- author = insert(:user)
-
- activity =
- insert(:note_activity,
- note:
- insert(:note,
- user: author,
- data: %{"to" => ["test-user"]}
- )
- )
-
- refute Visibility.entire_thread_visible_for_user?(activity, user)
- end
-
- test "returns true if user following to author" do
- author = insert(:user)
- user = insert(:user)
- Pleroma.User.follow(user, author)
-
- activity =
- insert(:note_activity,
- note:
- insert(:note,
- user: author,
- data: %{"to" => [user.ap_id]}
- )
- )
-
- assert Visibility.entire_thread_visible_for_user?(activity, user)
- end
- end
-end
diff --git a/test/web/admin_api/controllers/admin_api_controller_test.exs b/test/web/admin_api/controllers/admin_api_controller_test.exs
deleted file mode 100644
index dbf478edf..000000000
--- a/test/web/admin_api/controllers/admin_api_controller_test.exs
+++ /dev/null
@@ -1,1979 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
- use Pleroma.Web.ConnCase
- use Oban.Testing, repo: Pleroma.Repo
-
- import ExUnit.CaptureLog
- import Mock
- import Pleroma.Factory
- import Swoosh.TestAssertions
-
- alias Pleroma.Activity
- alias Pleroma.Config
- alias Pleroma.HTML
- alias Pleroma.MFA
- alias Pleroma.ModerationLog
- alias Pleroma.Repo
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web
- alias Pleroma.Web.ActivityPub.Relay
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MediaProxy
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
-
- :ok
- end
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- test "with valid `admin_token` query parameter, skips OAuth scopes check" do
- clear_config([:admin_token], "password123")
-
- user = insert(:user)
-
- conn = get(build_conn(), "/api/pleroma/admin/users/#{user.nickname}?admin_token=password123")
-
- assert json_response(conn, 200)
- end
-
- describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
- setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
-
- test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
- %{admin: admin} do
- user = insert(:user)
- url = "/api/pleroma/admin/users/#{user.nickname}"
-
- good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
- good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
- good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
-
- bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
- bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
- bad_token3 = nil
-
- for good_token <- [good_token1, good_token2, good_token3] do
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, good_token)
- |> get(url)
-
- assert json_response(conn, 200)
- end
-
- for good_token <- [good_token1, good_token2, good_token3] do
- conn =
- build_conn()
- |> assign(:user, nil)
- |> assign(:token, good_token)
- |> get(url)
-
- assert json_response(conn, :forbidden)
- end
-
- for bad_token <- [bad_token1, bad_token2, bad_token3] do
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, bad_token)
- |> get(url)
-
- assert json_response(conn, :forbidden)
- end
- end
- end
-
- describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
- setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
-
- test "GET /api/pleroma/admin/users/:nickname requires " <>
- "read:accounts or admin:read:accounts or broader scope",
- %{admin: admin} do
- user = insert(:user)
- url = "/api/pleroma/admin/users/#{user.nickname}"
-
- good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
- good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
- good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
- good_token4 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
- good_token5 = insert(:oauth_token, user: admin, scopes: ["read"])
-
- good_tokens = [good_token1, good_token2, good_token3, good_token4, good_token5]
-
- bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts:partial"])
- bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
- bad_token3 = nil
-
- for good_token <- good_tokens do
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, good_token)
- |> get(url)
-
- assert json_response(conn, 200)
- end
-
- for good_token <- good_tokens do
- conn =
- build_conn()
- |> assign(:user, nil)
- |> assign(:token, good_token)
- |> get(url)
-
- assert json_response(conn, :forbidden)
- end
-
- for bad_token <- [bad_token1, bad_token2, bad_token3] do
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, bad_token)
- |> get(url)
-
- assert json_response(conn, :forbidden)
- end
- end
- end
-
- describe "DELETE /api/pleroma/admin/users" do
- test "single user", %{admin: admin, conn: conn} do
- clear_config([:instance, :federating], true)
-
- user =
- insert(:user,
- avatar: %{"url" => [%{"href" => "https://someurl"}]},
- banner: %{"url" => [%{"href" => "https://somebanner"}]},
- bio: "Hello world!",
- name: "A guy"
- )
-
- # Create some activities to check they got deleted later
- follower = insert(:user)
- {:ok, _} = CommonAPI.post(user, %{status: "test"})
- {:ok, _, _, _} = CommonAPI.follow(user, follower)
- {:ok, _, _, _} = CommonAPI.follow(follower, user)
- user = Repo.get(User, user.id)
- assert user.note_count == 1
- assert user.follower_count == 1
- assert user.following_count == 1
- refute user.deactivated
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end,
- perform: fn _, _ -> nil end do
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
-
- ObanHelpers.perform_all()
-
- assert User.get_by_nickname(user.nickname).deactivated
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} deleted users: @#{user.nickname}"
-
- assert json_response(conn, 200) == [user.nickname]
-
- user = Repo.get(User, user.id)
- assert user.deactivated
-
- assert user.avatar == %{}
- assert user.banner == %{}
- assert user.note_count == 0
- assert user.follower_count == 0
- assert user.following_count == 0
- assert user.bio == nil
- assert user.name == nil
-
- assert called(Pleroma.Web.Federator.publish(:_))
- end
- end
-
- test "multiple users", %{admin: admin, conn: conn} do
- user_one = insert(:user)
- user_two = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> delete("/api/pleroma/admin/users", %{
- nicknames: [user_one.nickname, user_two.nickname]
- })
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} deleted users: @#{user_one.nickname}, @#{user_two.nickname}"
-
- response = json_response(conn, 200)
- assert response -- [user_one.nickname, user_two.nickname] == []
- end
- end
-
- describe "/api/pleroma/admin/users" do
- test "Create", %{conn: conn} do
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users", %{
- "users" => [
- %{
- "nickname" => "lain",
- "email" => "lain@example.org",
- "password" => "test"
- },
- %{
- "nickname" => "lain2",
- "email" => "lain2@example.org",
- "password" => "test"
- }
- ]
- })
-
- response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
- assert response == ["success", "success"]
-
- log_entry = Repo.one(ModerationLog)
-
- assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
- end
-
- test "Cannot create user with existing email", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users", %{
- "users" => [
- %{
- "nickname" => "lain",
- "email" => user.email,
- "password" => "test"
- }
- ]
- })
-
- assert json_response(conn, 409) == [
- %{
- "code" => 409,
- "data" => %{
- "email" => user.email,
- "nickname" => "lain"
- },
- "error" => "email has already been taken",
- "type" => "error"
- }
- ]
- end
-
- test "Cannot create user with existing nickname", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users", %{
- "users" => [
- %{
- "nickname" => user.nickname,
- "email" => "someuser@plerama.social",
- "password" => "test"
- }
- ]
- })
-
- assert json_response(conn, 409) == [
- %{
- "code" => 409,
- "data" => %{
- "email" => "someuser@plerama.social",
- "nickname" => user.nickname
- },
- "error" => "nickname has already been taken",
- "type" => "error"
- }
- ]
- end
-
- test "Multiple user creation works in transaction", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users", %{
- "users" => [
- %{
- "nickname" => "newuser",
- "email" => "newuser@pleroma.social",
- "password" => "test"
- },
- %{
- "nickname" => "lain",
- "email" => user.email,
- "password" => "test"
- }
- ]
- })
-
- assert json_response(conn, 409) == [
- %{
- "code" => 409,
- "data" => %{
- "email" => user.email,
- "nickname" => "lain"
- },
- "error" => "email has already been taken",
- "type" => "error"
- },
- %{
- "code" => 409,
- "data" => %{
- "email" => "newuser@pleroma.social",
- "nickname" => "newuser"
- },
- "error" => "",
- "type" => "error"
- }
- ]
-
- assert User.get_by_nickname("newuser") === nil
- end
- end
-
- describe "/api/pleroma/admin/users/:nickname" do
- test "Show", %{conn: conn} do
- user = insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}")
-
- expected = %{
- "deactivated" => false,
- "id" => to_string(user.id),
- "local" => true,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
-
- assert expected == json_response(conn, 200)
- end
-
- test "when the user doesn't exist", %{conn: conn} do
- user = build(:user)
-
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}")
-
- assert %{"error" => "Not found"} == json_response(conn, 404)
- end
- end
-
- describe "/api/pleroma/admin/users/follow" do
- test "allows to force-follow another user", %{admin: admin, conn: conn} do
- user = insert(:user)
- follower = insert(:user)
-
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users/follow", %{
- "follower" => follower.nickname,
- "followed" => user.nickname
- })
-
- user = User.get_cached_by_id(user.id)
- follower = User.get_cached_by_id(follower.id)
-
- assert User.following?(follower, user)
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
- end
- end
-
- describe "/api/pleroma/admin/users/unfollow" do
- test "allows to force-unfollow another user", %{admin: admin, conn: conn} do
- user = insert(:user)
- follower = insert(:user)
-
- User.follow(follower, user)
-
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users/unfollow", %{
- "follower" => follower.nickname,
- "followed" => user.nickname
- })
-
- user = User.get_cached_by_id(user.id)
- follower = User.get_cached_by_id(follower.id)
-
- refute User.following?(follower, user)
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
- end
- end
-
- describe "PUT /api/pleroma/admin/users/tag" do
- setup %{conn: conn} do
- user1 = insert(:user, %{tags: ["x"]})
- user2 = insert(:user, %{tags: ["y"]})
- user3 = insert(:user, %{tags: ["unchanged"]})
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> put(
- "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
- "#{user2.nickname}&tags[]=foo&tags[]=bar"
- )
-
- %{conn: conn, user1: user1, user2: user2, user3: user3}
- end
-
- test "it appends specified tags to users with specified nicknames", %{
- conn: conn,
- admin: admin,
- user1: user1,
- user2: user2
- } do
- assert empty_json_response(conn)
- assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
- assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
-
- log_entry = Repo.one(ModerationLog)
-
- users =
- [user1.nickname, user2.nickname]
- |> Enum.map(&"@#{&1}")
- |> Enum.join(", ")
-
- tags = ["foo", "bar"] |> Enum.join(", ")
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} added tags: #{tags} to users: #{users}"
- end
-
- test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
- assert empty_json_response(conn)
- assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
- end
- end
-
- describe "DELETE /api/pleroma/admin/users/tag" do
- setup %{conn: conn} do
- user1 = insert(:user, %{tags: ["x"]})
- user2 = insert(:user, %{tags: ["y", "z"]})
- user3 = insert(:user, %{tags: ["unchanged"]})
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> delete(
- "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
- "#{user2.nickname}&tags[]=x&tags[]=z"
- )
-
- %{conn: conn, user1: user1, user2: user2, user3: user3}
- end
-
- test "it removes specified tags from users with specified nicknames", %{
- conn: conn,
- admin: admin,
- user1: user1,
- user2: user2
- } do
- assert empty_json_response(conn)
- assert User.get_cached_by_id(user1.id).tags == []
- assert User.get_cached_by_id(user2.id).tags == ["y"]
-
- log_entry = Repo.one(ModerationLog)
-
- users =
- [user1.nickname, user2.nickname]
- |> Enum.map(&"@#{&1}")
- |> Enum.join(", ")
-
- tags = ["x", "z"] |> Enum.join(", ")
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
- end
-
- test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
- assert empty_json_response(conn)
- assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
- end
- end
-
- describe "/api/pleroma/admin/users/:nickname/permission_group" do
- test "GET is giving user_info", %{admin: admin, conn: conn} do
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
-
- assert json_response(conn, 200) == %{
- "is_admin" => true,
- "is_moderator" => false
- }
- end
-
- test "/:right POST, can add to a permission group", %{admin: admin, conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
-
- assert json_response(conn, 200) == %{
- "is_admin" => true
- }
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} made @#{user.nickname} admin"
- end
-
- test "/:right POST, can add to a permission group (multiple)", %{admin: admin, conn: conn} do
- user_one = insert(:user)
- user_two = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> post("/api/pleroma/admin/users/permission_group/admin", %{
- nicknames: [user_one.nickname, user_two.nickname]
- })
-
- assert json_response(conn, 200) == %{"is_admin" => true}
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin"
- end
-
- test "/:right DELETE, can remove from a permission group", %{admin: admin, conn: conn} do
- user = insert(:user, is_admin: true)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
-
- assert json_response(conn, 200) == %{"is_admin" => false}
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} revoked admin role from @#{user.nickname}"
- end
-
- test "/:right DELETE, can remove from a permission group (multiple)", %{
- admin: admin,
- conn: conn
- } do
- user_one = insert(:user, is_admin: true)
- user_two = insert(:user, is_admin: true)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> delete("/api/pleroma/admin/users/permission_group/admin", %{
- nicknames: [user_one.nickname, user_two.nickname]
- })
-
- assert json_response(conn, 200) == %{"is_admin" => false}
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{
- user_two.nickname
- }"
- end
- end
-
- test "/api/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> put_req_header("accept", "application/json")
- |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
-
- resp = json_response(conn, 200)
-
- assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
- end
-
- describe "GET /api/pleroma/admin/users" do
- test "renders users array for the first page", %{conn: conn, admin: admin} do
- user = insert(:user, local: false, tags: ["foo", "bar"])
- user2 = insert(:user, approval_pending: true, registration_reason: "I'm a chill dude")
-
- conn = get(conn, "/api/pleroma/admin/users?page=1")
-
- users =
- [
- %{
- "deactivated" => admin.deactivated,
- "id" => admin.id,
- "nickname" => admin.nickname,
- "roles" => %{"admin" => true, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(admin.name || admin.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => admin.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- },
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => false,
- "tags" => ["foo", "bar"],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- },
- %{
- "deactivated" => user2.deactivated,
- "id" => user2.id,
- "nickname" => user2.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user2.name || user2.nickname),
- "confirmation_pending" => false,
- "approval_pending" => true,
- "url" => user2.ap_id,
- "registration_reason" => "I'm a chill dude",
- "actor_type" => "Person"
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 3,
- "page_size" => 50,
- "users" => users
- }
- end
-
- test "pagination works correctly with service users", %{conn: conn} do
- service1 = User.get_or_create_service_actor_by_ap_id(Web.base_url() <> "/meido", "meido")
-
- insert_list(25, :user)
-
- assert %{"count" => 26, "page_size" => 10, "users" => users1} =
- conn
- |> get("/api/pleroma/admin/users?page=1&filters=", %{page_size: "10"})
- |> json_response(200)
-
- assert Enum.count(users1) == 10
- assert service1 not in users1
-
- assert %{"count" => 26, "page_size" => 10, "users" => users2} =
- conn
- |> get("/api/pleroma/admin/users?page=2&filters=", %{page_size: "10"})
- |> json_response(200)
-
- assert Enum.count(users2) == 10
- assert service1 not in users2
-
- assert %{"count" => 26, "page_size" => 10, "users" => users3} =
- conn
- |> get("/api/pleroma/admin/users?page=3&filters=", %{page_size: "10"})
- |> json_response(200)
-
- assert Enum.count(users3) == 6
- assert service1 not in users3
- end
-
- test "renders empty array for the second page", %{conn: conn} do
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?page=2")
-
- assert json_response(conn, 200) == %{
- "count" => 2,
- "page_size" => 50,
- "users" => []
- }
- end
-
- test "regular search", %{conn: conn} do
- user = insert(:user, nickname: "bob")
-
- conn = get(conn, "/api/pleroma/admin/users?query=bo")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "search by domain", %{conn: conn} do
- user = insert(:user, nickname: "nickname@domain.com")
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "search by full nickname", %{conn: conn} do
- user = insert(:user, nickname: "nickname@domain.com")
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "search by display name", %{conn: conn} do
- user = insert(:user, name: "Display name")
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?name=display")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "search by email", %{conn: conn} do
- user = insert(:user, email: "email@example.com")
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "regular search with page size", %{conn: conn} do
- user = insert(:user, nickname: "aalice")
- user2 = insert(:user, nickname: "alice")
-
- conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
-
- assert json_response(conn1, 200) == %{
- "count" => 2,
- "page_size" => 1,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
-
- conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
-
- assert json_response(conn2, 200) == %{
- "count" => 2,
- "page_size" => 1,
- "users" => [
- %{
- "deactivated" => user2.deactivated,
- "id" => user2.id,
- "nickname" => user2.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user2.name || user2.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user2.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "only local users" do
- admin = insert(:user, is_admin: true, nickname: "john")
- token = insert(:oauth_admin_token, user: admin)
- user = insert(:user, nickname: "bob")
-
- insert(:user, nickname: "bobb", local: false)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
- |> get("/api/pleroma/admin/users?query=bo&filters=local")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "only local users with no query", %{conn: conn, admin: old_admin} do
- admin = insert(:user, is_admin: true, nickname: "john")
- user = insert(:user, nickname: "bob")
-
- insert(:user, nickname: "bobb", local: false)
-
- conn = get(conn, "/api/pleroma/admin/users?filters=local")
-
- users =
- [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- },
- %{
- "deactivated" => admin.deactivated,
- "id" => admin.id,
- "nickname" => admin.nickname,
- "roles" => %{"admin" => true, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(admin.name || admin.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => admin.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- },
- %{
- "deactivated" => false,
- "id" => old_admin.id,
- "local" => true,
- "nickname" => old_admin.nickname,
- "roles" => %{"admin" => true, "moderator" => false},
- "tags" => [],
- "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => old_admin.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 3,
- "page_size" => 50,
- "users" => users
- }
- end
-
- test "only unapproved users", %{conn: conn} do
- user =
- insert(:user,
- nickname: "sadboy",
- approval_pending: true,
- registration_reason: "Plz let me in!"
- )
-
- insert(:user, nickname: "happyboy", approval_pending: false)
-
- conn = get(conn, "/api/pleroma/admin/users?filters=need_approval")
-
- users =
- [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => true,
- "url" => user.ap_id,
- "registration_reason" => "Plz let me in!",
- "actor_type" => "Person"
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => users
- }
- end
-
- test "load only admins", %{conn: conn, admin: admin} do
- second_admin = insert(:user, is_admin: true)
- insert(:user)
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
-
- users =
- [
- %{
- "deactivated" => false,
- "id" => admin.id,
- "nickname" => admin.nickname,
- "roles" => %{"admin" => true, "moderator" => false},
- "local" => admin.local,
- "tags" => [],
- "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(admin.name || admin.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => admin.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- },
- %{
- "deactivated" => false,
- "id" => second_admin.id,
- "nickname" => second_admin.nickname,
- "roles" => %{"admin" => true, "moderator" => false},
- "local" => second_admin.local,
- "tags" => [],
- "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => second_admin.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 2,
- "page_size" => 50,
- "users" => users
- }
- end
-
- test "load only moderators", %{conn: conn} do
- moderator = insert(:user, is_moderator: true)
- insert(:user)
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => false,
- "id" => moderator.id,
- "nickname" => moderator.nickname,
- "roles" => %{"admin" => false, "moderator" => true},
- "local" => moderator.local,
- "tags" => [],
- "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(moderator.name || moderator.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => moderator.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "load users with tags list", %{conn: conn} do
- user1 = insert(:user, tags: ["first"])
- user2 = insert(:user, tags: ["second"])
- insert(:user)
- insert(:user)
-
- conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
-
- users =
- [
- %{
- "deactivated" => false,
- "id" => user1.id,
- "nickname" => user1.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => user1.local,
- "tags" => ["first"],
- "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user1.name || user1.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user1.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- },
- %{
- "deactivated" => false,
- "id" => user2.id,
- "nickname" => user2.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => user2.local,
- "tags" => ["second"],
- "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user2.name || user2.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user2.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 2,
- "page_size" => 50,
- "users" => users
- }
- end
-
- test "`active` filters out users pending approval", %{token: token} do
- insert(:user, approval_pending: true)
- %{id: user_id} = insert(:user, approval_pending: false)
- %{id: admin_id} = token.user
-
- conn =
- build_conn()
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> get("/api/pleroma/admin/users?filters=active")
-
- assert %{
- "count" => 2,
- "page_size" => 50,
- "users" => [
- %{"id" => ^admin_id},
- %{"id" => ^user_id}
- ]
- } = json_response(conn, 200)
- end
-
- test "it works with multiple filters" do
- admin = insert(:user, nickname: "john", is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
- user = insert(:user, nickname: "bob", local: false, deactivated: true)
-
- insert(:user, nickname: "ken", local: true, deactivated: true)
- insert(:user, nickname: "bobb", local: false, deactivated: false)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
- |> get("/api/pleroma/admin/users?filters=deactivated,external")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => user.local,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
-
- test "it omits relay user", %{admin: admin, conn: conn} do
- assert %User{} = Relay.get_actor()
-
- conn = get(conn, "/api/pleroma/admin/users")
-
- assert json_response(conn, 200) == %{
- "count" => 1,
- "page_size" => 50,
- "users" => [
- %{
- "deactivated" => admin.deactivated,
- "id" => admin.id,
- "nickname" => admin.nickname,
- "roles" => %{"admin" => true, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(admin.name || admin.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => admin.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
- ]
- }
- end
- end
-
- test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do
- user_one = insert(:user, deactivated: true)
- user_two = insert(:user, deactivated: true)
-
- conn =
- patch(
- conn,
- "/api/pleroma/admin/users/activate",
- %{nicknames: [user_one.nickname, user_two.nickname]}
- )
-
- response = json_response(conn, 200)
- assert Enum.map(response["users"], & &1["deactivated"]) == [false, false]
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
- end
-
- test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do
- user_one = insert(:user, deactivated: false)
- user_two = insert(:user, deactivated: false)
-
- conn =
- patch(
- conn,
- "/api/pleroma/admin/users/deactivate",
- %{nicknames: [user_one.nickname, user_two.nickname]}
- )
-
- response = json_response(conn, 200)
- assert Enum.map(response["users"], & &1["deactivated"]) == [true, true]
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
- end
-
- test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do
- user_one = insert(:user, approval_pending: true)
- user_two = insert(:user, approval_pending: true)
-
- conn =
- patch(
- conn,
- "/api/pleroma/admin/users/approve",
- %{nicknames: [user_one.nickname, user_two.nickname]}
- )
-
- response = json_response(conn, 200)
- assert Enum.map(response["users"], & &1["approval_pending"]) == [false, false]
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}"
- end
-
- test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
- user = insert(:user)
-
- conn = patch(conn, "/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
-
- assert json_response(conn, 200) ==
- %{
- "deactivated" => !user.deactivated,
- "id" => user.id,
- "nickname" => user.nickname,
- "roles" => %{"admin" => false, "moderator" => false},
- "local" => true,
- "tags" => [],
- "avatar" => User.avatar_url(user) |> MediaProxy.url(),
- "display_name" => HTML.strip_tags(user.name || user.nickname),
- "confirmation_pending" => false,
- "approval_pending" => false,
- "url" => user.ap_id,
- "registration_reason" => nil,
- "actor_type" => "Person"
- }
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} deactivated users: @#{user.nickname}"
- end
-
- describe "PUT disable_mfa" do
- test "returns 200 and disable 2fa", %{conn: conn} do
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: "otp_secret", confirmed: true}
- }
- )
-
- response =
- conn
- |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: user.nickname})
- |> json_response(200)
-
- assert response == user.nickname
- mfa_settings = refresh_record(user).multi_factor_authentication_settings
-
- refute mfa_settings.enabled
- refute mfa_settings.totp.confirmed
- end
-
- test "returns 404 if user not found", %{conn: conn} do
- response =
- conn
- |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"})
- |> json_response(404)
-
- assert response == %{"error" => "Not found"}
- end
- end
-
- describe "GET /api/pleroma/admin/restart" do
- setup do: clear_config(:configurable_from_database, true)
-
- test "pleroma restarts", %{conn: conn} do
- capture_log(fn ->
- assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{}
- end) =~ "pleroma restarted"
-
- refute Restarter.Pleroma.need_reboot?()
- end
- end
-
- test "need_reboot flag", %{conn: conn} do
- assert conn
- |> get("/api/pleroma/admin/need_reboot")
- |> json_response(200) == %{"need_reboot" => false}
-
- Restarter.Pleroma.need_reboot()
-
- assert conn
- |> get("/api/pleroma/admin/need_reboot")
- |> json_response(200) == %{"need_reboot" => true}
-
- on_exit(fn -> Restarter.Pleroma.refresh() end)
- end
-
- describe "GET /api/pleroma/admin/users/:nickname/statuses" do
- setup do
- user = insert(:user)
-
- date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
- date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
- date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
-
- insert(:note_activity, user: user, published: date1)
- insert(:note_activity, user: user, published: date2)
- insert(:note_activity, user: user, published: date3)
-
- %{user: user}
- end
-
- test "renders user's statuses", %{conn: conn, user: user} do
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
-
- assert json_response(conn, 200) |> length() == 3
- end
-
- test "renders user's statuses with a limit", %{conn: conn, user: user} do
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
-
- assert json_response(conn, 200) |> length() == 2
- end
-
- test "doesn't return private statuses by default", %{conn: conn, user: user} do
- {:ok, _private_status} = CommonAPI.post(user, %{status: "private", visibility: "private"})
-
- {:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
-
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
-
- assert json_response(conn, 200) |> length() == 4
- end
-
- test "returns private statuses with godmode on", %{conn: conn, user: user} do
- {:ok, _private_status} = CommonAPI.post(user, %{status: "private", visibility: "private"})
-
- {:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
-
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
-
- assert json_response(conn, 200) |> length() == 5
- end
-
- test "excludes reblogs by default", %{conn: conn, user: user} do
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "."})
- {:ok, %Activity{}} = CommonAPI.repeat(activity.id, other_user)
-
- conn_res = get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses")
- assert json_response(conn_res, 200) |> length() == 0
-
- conn_res =
- get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses?with_reblogs=true")
-
- assert json_response(conn_res, 200) |> length() == 1
- end
- end
-
- describe "GET /api/pleroma/admin/moderation_log" do
- setup do
- moderator = insert(:user, is_moderator: true)
-
- %{moderator: moderator}
- end
-
- test "returns the log", %{conn: conn, admin: admin} do
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_follow",
- target: "https://example.org/relay"
- },
- inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
- })
-
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_unfollow",
- target: "https://example.org/relay"
- },
- inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
- })
-
- conn = get(conn, "/api/pleroma/admin/moderation_log")
-
- response = json_response(conn, 200)
- [first_entry, second_entry] = response["items"]
-
- assert response["total"] == 2
- assert first_entry["data"]["action"] == "relay_unfollow"
-
- assert first_entry["message"] ==
- "@#{admin.nickname} unfollowed relay: https://example.org/relay"
-
- assert second_entry["data"]["action"] == "relay_follow"
-
- assert second_entry["message"] ==
- "@#{admin.nickname} followed relay: https://example.org/relay"
- end
-
- test "returns the log with pagination", %{conn: conn, admin: admin} do
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_follow",
- target: "https://example.org/relay"
- },
- inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
- })
-
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_unfollow",
- target: "https://example.org/relay"
- },
- inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
- })
-
- conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
-
- response1 = json_response(conn1, 200)
- [first_entry] = response1["items"]
-
- assert response1["total"] == 2
- assert response1["items"] |> length() == 1
- assert first_entry["data"]["action"] == "relay_unfollow"
-
- assert first_entry["message"] ==
- "@#{admin.nickname} unfollowed relay: https://example.org/relay"
-
- conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
-
- response2 = json_response(conn2, 200)
- [second_entry] = response2["items"]
-
- assert response2["total"] == 2
- assert response2["items"] |> length() == 1
- assert second_entry["data"]["action"] == "relay_follow"
-
- assert second_entry["message"] ==
- "@#{admin.nickname} followed relay: https://example.org/relay"
- end
-
- test "filters log by date", %{conn: conn, admin: admin} do
- first_date = "2017-08-15T15:47:06Z"
- second_date = "2017-08-20T15:47:06Z"
-
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_follow",
- target: "https://example.org/relay"
- },
- inserted_at: NaiveDateTime.from_iso8601!(first_date)
- })
-
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_unfollow",
- target: "https://example.org/relay"
- },
- inserted_at: NaiveDateTime.from_iso8601!(second_date)
- })
-
- conn1 =
- get(
- conn,
- "/api/pleroma/admin/moderation_log?start_date=#{second_date}"
- )
-
- response1 = json_response(conn1, 200)
- [first_entry] = response1["items"]
-
- assert response1["total"] == 1
- assert first_entry["data"]["action"] == "relay_unfollow"
-
- assert first_entry["message"] ==
- "@#{admin.nickname} unfollowed relay: https://example.org/relay"
- end
-
- test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => admin.id,
- "nickname" => admin.nickname,
- "type" => "user"
- },
- action: "relay_follow",
- target: "https://example.org/relay"
- }
- })
-
- Repo.insert(%ModerationLog{
- data: %{
- actor: %{
- "id" => moderator.id,
- "nickname" => moderator.nickname,
- "type" => "user"
- },
- action: "relay_unfollow",
- target: "https://example.org/relay"
- }
- })
-
- conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
-
- response1 = json_response(conn1, 200)
- [first_entry] = response1["items"]
-
- assert response1["total"] == 1
- assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
- end
-
- test "returns log filtered by search", %{conn: conn, moderator: moderator} do
- ModerationLog.insert_log(%{
- actor: moderator,
- action: "relay_follow",
- target: "https://example.org/relay"
- })
-
- ModerationLog.insert_log(%{
- actor: moderator,
- action: "relay_unfollow",
- target: "https://example.org/relay"
- })
-
- conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
-
- response1 = json_response(conn1, 200)
- [first_entry] = response1["items"]
-
- assert response1["total"] == 1
-
- assert get_in(first_entry, ["data", "message"]) ==
- "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
- end
- end
-
- test "gets a remote users when [:instance, :limit_to_local_content] is set to :unauthenticated",
- %{conn: conn} do
- clear_config(Pleroma.Config.get([:instance, :limit_to_local_content]), :unauthenticated)
- user = insert(:user, %{local: false, nickname: "u@peer1.com"})
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
-
- assert json_response(conn, 200)
- end
-
- describe "GET /users/:nickname/credentials" do
- test "gets the user credentials", %{conn: conn} do
- user = insert(:user)
- conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
-
- response = assert json_response(conn, 200)
- assert response["email"] == user.email
- end
-
- test "returns 403 if requested by a non-admin" do
- user = insert(:user)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> get("/api/pleroma/admin/users/#{user.nickname}/credentials")
-
- assert json_response(conn, :forbidden)
- end
- end
-
- describe "PATCH /users/:nickname/credentials" do
- setup do
- user = insert(:user)
- [user: user]
- end
-
- test "changes password and email", %{conn: conn, admin: admin, user: user} do
- assert user.password_reset_pending == false
-
- conn =
- patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
- "password" => "new_password",
- "email" => "new_email@example.com",
- "name" => "new_name"
- })
-
- assert json_response(conn, 200) == %{"status" => "success"}
-
- ObanHelpers.perform_all()
-
- updated_user = User.get_by_id(user.id)
-
- assert updated_user.email == "new_email@example.com"
- assert updated_user.name == "new_name"
- assert updated_user.password_hash != user.password_hash
- assert updated_user.password_reset_pending == true
-
- [log_entry2, log_entry1] = ModerationLog |> Repo.all() |> Enum.sort()
-
- assert ModerationLog.get_log_entry_message(log_entry1) ==
- "@#{admin.nickname} updated users: @#{user.nickname}"
-
- assert ModerationLog.get_log_entry_message(log_entry2) ==
- "@#{admin.nickname} forced password reset for users: @#{user.nickname}"
- end
-
- test "returns 403 if requested by a non-admin", %{user: user} do
- conn =
- build_conn()
- |> assign(:user, user)
- |> patch("/api/pleroma/admin/users/#{user.nickname}/credentials", %{
- "password" => "new_password",
- "email" => "new_email@example.com",
- "name" => "new_name"
- })
-
- assert json_response(conn, :forbidden)
- end
-
- test "changes actor type from permitted list", %{conn: conn, user: user} do
- assert user.actor_type == "Person"
-
- assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
- "actor_type" => "Service"
- })
- |> json_response(200) == %{"status" => "success"}
-
- updated_user = User.get_by_id(user.id)
-
- assert updated_user.actor_type == "Service"
-
- assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
- "actor_type" => "Application"
- })
- |> json_response(400) == %{"errors" => %{"actor_type" => "is invalid"}}
- end
-
- test "update non existing user", %{conn: conn} do
- assert patch(conn, "/api/pleroma/admin/users/non-existing/credentials", %{
- "password" => "new_password"
- })
- |> json_response(404) == %{"error" => "Not found"}
- end
- end
-
- describe "PATCH /users/:nickname/force_password_reset" do
- test "sets password_reset_pending to true", %{conn: conn} do
- user = insert(:user)
- assert user.password_reset_pending == false
-
- conn =
- patch(conn, "/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]})
-
- assert empty_json_response(conn) == ""
-
- ObanHelpers.perform_all()
-
- assert User.get_by_id(user.id).password_reset_pending == true
- end
- end
-
- describe "instances" do
- test "GET /instances/:instance/statuses", %{conn: conn} do
- user = insert(:user, local: false, nickname: "archaeme@archae.me")
- user2 = insert(:user, local: false, nickname: "test@test.com")
- insert_pair(:note_activity, user: user)
- activity = insert(:note_activity, user: user2)
-
- ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses")
-
- response = json_response(ret_conn, 200)
-
- assert length(response) == 2
-
- ret_conn = get(conn, "/api/pleroma/admin/instances/test.com/statuses")
-
- response = json_response(ret_conn, 200)
-
- assert length(response) == 1
-
- ret_conn = get(conn, "/api/pleroma/admin/instances/nonexistent.com/statuses")
-
- response = json_response(ret_conn, 200)
-
- assert Enum.empty?(response)
-
- CommonAPI.repeat(activity.id, user)
-
- ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses")
- response = json_response(ret_conn, 200)
- assert length(response) == 2
-
- ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses?with_reblogs=true")
- response = json_response(ret_conn, 200)
- assert length(response) == 3
- end
- end
-
- describe "PATCH /confirm_email" do
- test "it confirms emails of two users", %{conn: conn, admin: admin} do
- [first_user, second_user] = insert_pair(:user, confirmation_pending: true)
-
- assert first_user.confirmation_pending == true
- assert second_user.confirmation_pending == true
-
- ret_conn =
- patch(conn, "/api/pleroma/admin/users/confirm_email", %{
- nicknames: [
- first_user.nickname,
- second_user.nickname
- ]
- })
-
- assert ret_conn.status == 200
-
- assert first_user.confirmation_pending == true
- assert second_user.confirmation_pending == true
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{
- second_user.nickname
- }"
- end
- end
-
- describe "PATCH /resend_confirmation_email" do
- test "it resend emails for two users", %{conn: conn, admin: admin} do
- [first_user, second_user] = insert_pair(:user, confirmation_pending: true)
-
- ret_conn =
- patch(conn, "/api/pleroma/admin/users/resend_confirmation_email", %{
- nicknames: [
- first_user.nickname,
- second_user.nickname
- ]
- })
-
- assert ret_conn.status == 200
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{
- second_user.nickname
- }"
-
- ObanHelpers.perform_all()
- assert_email_sent(Pleroma.Emails.UserEmail.account_confirmation_email(first_user))
- end
- end
-
- describe "/api/pleroma/admin/stats" do
- test "status visibility count", %{conn: conn} do
- admin = insert(:user, is_admin: true)
- user = insert(:user)
- CommonAPI.post(user, %{visibility: "public", status: "hey"})
- CommonAPI.post(user, %{visibility: "unlisted", status: "hey"})
- CommonAPI.post(user, %{visibility: "unlisted", status: "hey"})
-
- response =
- conn
- |> assign(:user, admin)
- |> get("/api/pleroma/admin/stats")
- |> json_response(200)
-
- assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 2} =
- response["status_visibility"]
- end
-
- test "by instance", %{conn: conn} do
- admin = insert(:user, is_admin: true)
- user1 = insert(:user)
- instance2 = "instance2.tld"
- user2 = insert(:user, %{ap_id: "https://#{instance2}/@actor"})
-
- CommonAPI.post(user1, %{visibility: "public", status: "hey"})
- CommonAPI.post(user2, %{visibility: "unlisted", status: "hey"})
- CommonAPI.post(user2, %{visibility: "private", status: "hey"})
-
- response =
- conn
- |> assign(:user, admin)
- |> get("/api/pleroma/admin/stats", instance: instance2)
- |> json_response(200)
-
- assert %{"direct" => 0, "private" => 1, "public" => 0, "unlisted" => 1} =
- response["status_visibility"]
- end
- end
-end
-
-# Needed for testing
-defmodule Pleroma.Web.Endpoint.NotReal do
-end
-
-defmodule Pleroma.Captcha.NotReal do
-end
diff --git a/test/web/admin_api/controllers/config_controller_test.exs b/test/web/admin_api/controllers/config_controller_test.exs
deleted file mode 100644
index 4e897455f..000000000
--- a/test/web/admin_api/controllers/config_controller_test.exs
+++ /dev/null
@@ -1,1465 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
- use Pleroma.Web.ConnCase, async: true
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
-
- alias Pleroma.Config
- alias Pleroma.ConfigDB
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "GET /api/pleroma/admin/config" do
- setup do: clear_config(:configurable_from_database, true)
-
- test "when configuration from database is off", %{conn: conn} do
- Config.put(:configurable_from_database, false)
- conn = get(conn, "/api/pleroma/admin/config")
-
- assert json_response_and_validate_schema(conn, 400) ==
- %{
- "error" => "To use this endpoint you need to enable configuration from database."
- }
- end
-
- test "with settings only in db", %{conn: conn} do
- config1 = insert(:config)
- config2 = insert(:config)
-
- conn = get(conn, "/api/pleroma/admin/config?only_db=true")
-
- %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => key1,
- "value" => _
- },
- %{
- "group" => ":pleroma",
- "key" => key2,
- "value" => _
- }
- ]
- } = json_response_and_validate_schema(conn, 200)
-
- assert key1 == inspect(config1.key)
- assert key2 == inspect(config2.key)
- end
-
- test "db is added to settings that are in db", %{conn: conn} do
- _config = insert(:config, key: ":instance", value: [name: "Some name"])
-
- %{"configs" => configs} =
- conn
- |> get("/api/pleroma/admin/config")
- |> json_response_and_validate_schema(200)
-
- [instance_config] =
- Enum.filter(configs, fn %{"group" => group, "key" => key} ->
- group == ":pleroma" and key == ":instance"
- end)
-
- assert instance_config["db"] == [":name"]
- end
-
- test "merged default setting with db settings", %{conn: conn} do
- config1 = insert(:config)
- config2 = insert(:config)
-
- config3 =
- insert(:config,
- value: [k1: :v1, k2: :v2]
- )
-
- %{"configs" => configs} =
- conn
- |> get("/api/pleroma/admin/config")
- |> json_response_and_validate_schema(200)
-
- assert length(configs) > 3
-
- saved_configs = [config1, config2, config3]
- keys = Enum.map(saved_configs, &inspect(&1.key))
-
- received_configs =
- Enum.filter(configs, fn %{"group" => group, "key" => key} ->
- group == ":pleroma" and key in keys
- end)
-
- assert length(received_configs) == 3
-
- db_keys =
- config3.value
- |> Keyword.keys()
- |> ConfigDB.to_json_types()
-
- keys = Enum.map(saved_configs -- [config3], &inspect(&1.key))
-
- values = Enum.map(saved_configs, &ConfigDB.to_json_types(&1.value))
-
- mapset_keys = MapSet.new(keys ++ db_keys)
-
- Enum.each(received_configs, fn %{"value" => value, "db" => db} ->
- db = MapSet.new(db)
- assert MapSet.subset?(db, mapset_keys)
-
- assert value in values
- end)
- end
-
- test "subkeys with full update right merge", %{conn: conn} do
- insert(:config,
- key: ":emoji",
- value: [groups: [a: 1, b: 2], key: [a: 1]]
- )
-
- insert(:config,
- key: ":assets",
- value: [mascots: [a: 1, b: 2], key: [a: 1]]
- )
-
- %{"configs" => configs} =
- conn
- |> get("/api/pleroma/admin/config")
- |> json_response_and_validate_schema(200)
-
- vals =
- Enum.filter(configs, fn %{"group" => group, "key" => key} ->
- group == ":pleroma" and key in [":emoji", ":assets"]
- end)
-
- emoji = Enum.find(vals, fn %{"key" => key} -> key == ":emoji" end)
- assets = Enum.find(vals, fn %{"key" => key} -> key == ":assets" end)
-
- emoji_val = ConfigDB.to_elixir_types(emoji["value"])
- assets_val = ConfigDB.to_elixir_types(assets["value"])
-
- assert emoji_val[:groups] == [a: 1, b: 2]
- assert assets_val[:mascots] == [a: 1, b: 2]
- end
-
- test "with valid `admin_token` query parameter, skips OAuth scopes check" do
- clear_config([:admin_token], "password123")
-
- build_conn()
- |> get("/api/pleroma/admin/config?admin_token=password123")
- |> json_response_and_validate_schema(200)
- end
- end
-
- test "POST /api/pleroma/admin/config error", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{"configs" => []})
-
- assert json_response_and_validate_schema(conn, 400) ==
- %{"error" => "To use this endpoint you need to enable configuration from database."}
- end
-
- describe "POST /api/pleroma/admin/config" do
- setup do
- http = Application.get_env(:pleroma, :http)
-
- on_exit(fn ->
- Application.delete_env(:pleroma, :key1)
- Application.delete_env(:pleroma, :key2)
- Application.delete_env(:pleroma, :key3)
- Application.delete_env(:pleroma, :key4)
- Application.delete_env(:pleroma, :keyaa1)
- Application.delete_env(:pleroma, :keyaa2)
- Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
- Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
- Application.put_env(:pleroma, :http, http)
- Application.put_env(:tesla, :adapter, Tesla.Mock)
- Restarter.Pleroma.refresh()
- end)
- end
-
- setup do: clear_config(:configurable_from_database, true)
-
- @tag capture_log: true
- test "create new config setting in db", %{conn: conn} do
- ueberauth = Application.get_env(:ueberauth, Ueberauth)
- on_exit(fn -> Application.put_env(:ueberauth, Ueberauth, ueberauth) end)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":pleroma", key: ":key1", value: "value1"},
- %{
- group: ":ueberauth",
- key: "Ueberauth",
- value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
- },
- %{
- group: ":pleroma",
- key: ":key2",
- value: %{
- ":nested_1" => "nested_value1",
- ":nested_2" => [
- %{":nested_22" => "nested_value222"},
- %{":nested_33" => %{":nested_44" => "nested_444"}}
- ]
- }
- },
- %{
- group: ":pleroma",
- key: ":key3",
- value: [
- %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
- %{"nested_4" => true}
- ]
- },
- %{
- group: ":pleroma",
- key: ":key4",
- value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
- },
- %{
- group: ":idna",
- key: ":key5",
- value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => "value1",
- "db" => [":key1"]
- },
- %{
- "group" => ":ueberauth",
- "key" => "Ueberauth",
- "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}],
- "db" => [":consumer_secret"]
- },
- %{
- "group" => ":pleroma",
- "key" => ":key2",
- "value" => %{
- ":nested_1" => "nested_value1",
- ":nested_2" => [
- %{":nested_22" => "nested_value222"},
- %{":nested_33" => %{":nested_44" => "nested_444"}}
- ]
- },
- "db" => [":key2"]
- },
- %{
- "group" => ":pleroma",
- "key" => ":key3",
- "value" => [
- %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
- %{"nested_4" => true}
- ],
- "db" => [":key3"]
- },
- %{
- "group" => ":pleroma",
- "key" => ":key4",
- "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"},
- "db" => [":key4"]
- },
- %{
- "group" => ":idna",
- "key" => ":key5",
- "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]},
- "db" => [":key5"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Application.get_env(:pleroma, :key1) == "value1"
-
- assert Application.get_env(:pleroma, :key2) == %{
- nested_1: "nested_value1",
- nested_2: [
- %{nested_22: "nested_value222"},
- %{nested_33: %{nested_44: "nested_444"}}
- ]
- }
-
- assert Application.get_env(:pleroma, :key3) == [
- %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
- %{"nested_4" => true}
- ]
-
- assert Application.get_env(:pleroma, :key4) == %{
- "endpoint" => "https://example.com",
- nested_5: :upload
- }
-
- assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
- end
-
- test "save configs setting without explicit key", %{conn: conn} do
- level = Application.get_env(:quack, :level)
- meta = Application.get_env(:quack, :meta)
- webhook_url = Application.get_env(:quack, :webhook_url)
-
- on_exit(fn ->
- Application.put_env(:quack, :level, level)
- Application.put_env(:quack, :meta, meta)
- Application.put_env(:quack, :webhook_url, webhook_url)
- end)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":quack",
- key: ":level",
- value: ":info"
- },
- %{
- group: ":quack",
- key: ":meta",
- value: [":none"]
- },
- %{
- group: ":quack",
- key: ":webhook_url",
- value: "https://hooks.slack.com/services/KEY"
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":quack",
- "key" => ":level",
- "value" => ":info",
- "db" => [":level"]
- },
- %{
- "group" => ":quack",
- "key" => ":meta",
- "value" => [":none"],
- "db" => [":meta"]
- },
- %{
- "group" => ":quack",
- "key" => ":webhook_url",
- "value" => "https://hooks.slack.com/services/KEY",
- "db" => [":webhook_url"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Application.get_env(:quack, :level) == :info
- assert Application.get_env(:quack, :meta) == [:none]
- assert Application.get_env(:quack, :webhook_url) == "https://hooks.slack.com/services/KEY"
- end
-
- test "saving config with partial update", %{conn: conn} do
- insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: 2))
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":pleroma", key: ":key1", value: [%{"tuple" => [":key3", 3]}]}
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{"tuple" => [":key1", 1]},
- %{"tuple" => [":key2", 2]},
- %{"tuple" => [":key3", 3]}
- ],
- "db" => [":key1", ":key2", ":key3"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "saving config which need pleroma reboot", %{conn: conn} do
- chat = Config.get(:chat)
- on_exit(fn -> Config.put(:chat, chat) end)
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post(
- "/api/pleroma/admin/config",
- %{
- configs: [
- %{group: ":pleroma", key: ":chat", value: [%{"tuple" => [":enabled", true]}]}
- ]
- }
- )
- |> json_response_and_validate_schema(200) == %{
- "configs" => [
- %{
- "db" => [":enabled"],
- "group" => ":pleroma",
- "key" => ":chat",
- "value" => [%{"tuple" => [":enabled", true]}]
- }
- ],
- "need_reboot" => true
- }
-
- configs =
- conn
- |> get("/api/pleroma/admin/config")
- |> json_response_and_validate_schema(200)
-
- assert configs["need_reboot"]
-
- capture_log(fn ->
- assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) ==
- %{}
- end) =~ "pleroma restarted"
-
- configs =
- conn
- |> get("/api/pleroma/admin/config")
- |> json_response_and_validate_schema(200)
-
- assert configs["need_reboot"] == false
- end
-
- test "update setting which need reboot, don't change reboot flag until reboot", %{conn: conn} do
- chat = Config.get(:chat)
- on_exit(fn -> Config.put(:chat, chat) end)
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post(
- "/api/pleroma/admin/config",
- %{
- configs: [
- %{group: ":pleroma", key: ":chat", value: [%{"tuple" => [":enabled", true]}]}
- ]
- }
- )
- |> json_response_and_validate_schema(200) == %{
- "configs" => [
- %{
- "db" => [":enabled"],
- "group" => ":pleroma",
- "key" => ":chat",
- "value" => [%{"tuple" => [":enabled", true]}]
- }
- ],
- "need_reboot" => true
- }
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":pleroma", key: ":key1", value: [%{"tuple" => [":key3", 3]}]}
- ]
- })
- |> json_response_and_validate_schema(200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{"tuple" => [":key3", 3]}
- ],
- "db" => [":key3"]
- }
- ],
- "need_reboot" => true
- }
-
- capture_log(fn ->
- assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) ==
- %{}
- end) =~ "pleroma restarted"
-
- configs =
- conn
- |> get("/api/pleroma/admin/config")
- |> json_response_and_validate_schema(200)
-
- assert configs["need_reboot"] == false
- end
-
- test "saving config with nested merge", %{conn: conn} do
- insert(:config, key: :key1, value: [key1: 1, key2: [k1: 1, k2: 2]])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: ":key1",
- value: [
- %{"tuple" => [":key3", 3]},
- %{
- "tuple" => [
- ":key2",
- [
- %{"tuple" => [":k2", 1]},
- %{"tuple" => [":k3", 3]}
- ]
- ]
- }
- ]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{"tuple" => [":key1", 1]},
- %{"tuple" => [":key3", 3]},
- %{
- "tuple" => [
- ":key2",
- [
- %{"tuple" => [":k1", 1]},
- %{"tuple" => [":k2", 1]},
- %{"tuple" => [":k3", 3]}
- ]
- ]
- }
- ],
- "db" => [":key1", ":key3", ":key2"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "saving special atoms", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{
- "tuple" => [
- ":ssl_options",
- [%{"tuple" => [":versions", [":tlsv1", ":tlsv1.1", ":tlsv1.2"]]}]
- ]
- }
- ]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{
- "tuple" => [
- ":ssl_options",
- [%{"tuple" => [":versions", [":tlsv1", ":tlsv1.1", ":tlsv1.2"]]}]
- ]
- }
- ],
- "db" => [":ssl_options"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Application.get_env(:pleroma, :key1) == [
- ssl_options: [versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"]]
- ]
- end
-
- test "saving full setting if value is in full_key_update list", %{conn: conn} do
- backends = Application.get_env(:logger, :backends)
- on_exit(fn -> Application.put_env(:logger, :backends, backends) end)
-
- insert(:config,
- group: :logger,
- key: :backends,
- value: []
- )
-
- Pleroma.Config.TransferTask.load_and_update_env([], false)
-
- assert Application.get_env(:logger, :backends) == []
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":logger",
- key: ":backends",
- value: [":console"]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":logger",
- "key" => ":backends",
- "value" => [
- ":console"
- ],
- "db" => [":backends"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Application.get_env(:logger, :backends) == [
- :console
- ]
- end
-
- test "saving full setting if value is not keyword", %{conn: conn} do
- insert(:config,
- group: :tesla,
- key: :adapter,
- value: Tesla.Adapter.Hackey
- )
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":tesla", key: ":adapter", value: "Tesla.Adapter.Httpc"}
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":tesla",
- "key" => ":adapter",
- "value" => "Tesla.Adapter.Httpc",
- "db" => [":adapter"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "update config setting & delete with fallback to default value", %{
- conn: conn,
- admin: admin,
- token: token
- } do
- ueberauth = Application.get_env(:ueberauth, Ueberauth)
- insert(:config, key: :keyaa1)
- insert(:config, key: :keyaa2)
-
- config3 =
- insert(:config,
- group: :ueberauth,
- key: Ueberauth
- )
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":pleroma", key: ":keyaa1", value: "another_value"},
- %{group: ":pleroma", key: ":keyaa2", value: "another_value"}
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":keyaa1",
- "value" => "another_value",
- "db" => [":keyaa1"]
- },
- %{
- "group" => ":pleroma",
- "key" => ":keyaa2",
- "value" => "another_value",
- "db" => [":keyaa2"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Application.get_env(:pleroma, :keyaa1) == "another_value"
- assert Application.get_env(:pleroma, :keyaa2) == "another_value"
- assert Application.get_env(:ueberauth, Ueberauth) == config3.value
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":pleroma", key: ":keyaa2", delete: true},
- %{
- group: ":ueberauth",
- key: "Ueberauth",
- delete: true
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [],
- "need_reboot" => false
- }
-
- assert Application.get_env(:ueberauth, Ueberauth) == ueberauth
- refute Keyword.has_key?(Application.get_all_env(:pleroma), :keyaa2)
- end
-
- test "common config example", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- "group" => ":pleroma",
- "key" => "Pleroma.Captcha.NotReal",
- "value" => [
- %{"tuple" => [":enabled", false]},
- %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
- %{"tuple" => [":seconds_valid", 60]},
- %{"tuple" => [":path", ""]},
- %{"tuple" => [":key1", nil]},
- %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
- %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
- %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
- %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
- %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]},
- %{"tuple" => [":name", "Pleroma"]}
- ]
- }
- ]
- })
-
- assert Config.get([Pleroma.Captcha.NotReal, :name]) == "Pleroma"
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => "Pleroma.Captcha.NotReal",
- "value" => [
- %{"tuple" => [":enabled", false]},
- %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
- %{"tuple" => [":seconds_valid", 60]},
- %{"tuple" => [":path", ""]},
- %{"tuple" => [":key1", nil]},
- %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
- %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
- %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
- %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
- %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]},
- %{"tuple" => [":name", "Pleroma"]}
- ],
- "db" => [
- ":enabled",
- ":method",
- ":seconds_valid",
- ":path",
- ":key1",
- ":partial_chain",
- ":regex1",
- ":regex2",
- ":regex3",
- ":regex4",
- ":name"
- ]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "tuples with more than two values", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- "group" => ":pleroma",
- "key" => "Pleroma.Web.Endpoint.NotReal",
- "value" => [
- %{
- "tuple" => [
- ":http",
- [
- %{
- "tuple" => [
- ":key2",
- [
- %{
- "tuple" => [
- ":_",
- [
- %{
- "tuple" => [
- "/api/v1/streaming",
- "Pleroma.Web.MastodonAPI.WebsocketHandler",
- []
- ]
- },
- %{
- "tuple" => [
- "/websocket",
- "Phoenix.Endpoint.CowboyWebSocket",
- %{
- "tuple" => [
- "Phoenix.Transports.WebSocket",
- %{
- "tuple" => [
- "Pleroma.Web.Endpoint",
- "Pleroma.Web.UserSocket",
- []
- ]
- }
- ]
- }
- ]
- },
- %{
- "tuple" => [
- ":_",
- "Phoenix.Endpoint.Cowboy2Handler",
- %{"tuple" => ["Pleroma.Web.Endpoint", []]}
- ]
- }
- ]
- ]
- }
- ]
- ]
- }
- ]
- ]
- }
- ]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => "Pleroma.Web.Endpoint.NotReal",
- "value" => [
- %{
- "tuple" => [
- ":http",
- [
- %{
- "tuple" => [
- ":key2",
- [
- %{
- "tuple" => [
- ":_",
- [
- %{
- "tuple" => [
- "/api/v1/streaming",
- "Pleroma.Web.MastodonAPI.WebsocketHandler",
- []
- ]
- },
- %{
- "tuple" => [
- "/websocket",
- "Phoenix.Endpoint.CowboyWebSocket",
- %{
- "tuple" => [
- "Phoenix.Transports.WebSocket",
- %{
- "tuple" => [
- "Pleroma.Web.Endpoint",
- "Pleroma.Web.UserSocket",
- []
- ]
- }
- ]
- }
- ]
- },
- %{
- "tuple" => [
- ":_",
- "Phoenix.Endpoint.Cowboy2Handler",
- %{"tuple" => ["Pleroma.Web.Endpoint", []]}
- ]
- }
- ]
- ]
- }
- ]
- ]
- }
- ]
- ]
- }
- ],
- "db" => [":http"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "settings with nesting map", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{"tuple" => [":key2", "some_val"]},
- %{
- "tuple" => [
- ":key3",
- %{
- ":max_options" => 20,
- ":max_option_chars" => 200,
- ":min_expiration" => 0,
- ":max_expiration" => 31_536_000,
- "nested" => %{
- ":max_options" => 20,
- ":max_option_chars" => 200,
- ":min_expiration" => 0,
- ":max_expiration" => 31_536_000
- }
- }
- ]
- }
- ]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) ==
- %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => [
- %{"tuple" => [":key2", "some_val"]},
- %{
- "tuple" => [
- ":key3",
- %{
- ":max_expiration" => 31_536_000,
- ":max_option_chars" => 200,
- ":max_options" => 20,
- ":min_expiration" => 0,
- "nested" => %{
- ":max_expiration" => 31_536_000,
- ":max_option_chars" => 200,
- ":max_options" => 20,
- ":min_expiration" => 0
- }
- }
- ]
- }
- ],
- "db" => [":key2", ":key3"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "value as map", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => %{"key" => "some_val"}
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) ==
- %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":key1",
- "value" => %{"key" => "some_val"},
- "db" => [":key1"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "queues key as atom", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- "group" => ":oban",
- "key" => ":queues",
- "value" => [
- %{"tuple" => [":federator_incoming", 50]},
- %{"tuple" => [":federator_outgoing", 50]},
- %{"tuple" => [":web_push", 50]},
- %{"tuple" => [":mailer", 10]},
- %{"tuple" => [":transmogrifier", 20]},
- %{"tuple" => [":scheduled_activities", 10]},
- %{"tuple" => [":background", 5]}
- ]
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":oban",
- "key" => ":queues",
- "value" => [
- %{"tuple" => [":federator_incoming", 50]},
- %{"tuple" => [":federator_outgoing", 50]},
- %{"tuple" => [":web_push", 50]},
- %{"tuple" => [":mailer", 10]},
- %{"tuple" => [":transmogrifier", 20]},
- %{"tuple" => [":scheduled_activities", 10]},
- %{"tuple" => [":background", 5]}
- ],
- "db" => [
- ":federator_incoming",
- ":federator_outgoing",
- ":web_push",
- ":mailer",
- ":transmogrifier",
- ":scheduled_activities",
- ":background"
- ]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "delete part of settings by atom subkeys", %{conn: conn} do
- insert(:config,
- key: :keyaa1,
- value: [subkey1: "val1", subkey2: "val2", subkey3: "val3"]
- )
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: ":keyaa1",
- subkeys: [":subkey1", ":subkey3"],
- delete: true
- }
- ]
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":keyaa1",
- "value" => [%{"tuple" => [":subkey2", "val2"]}],
- "db" => [":subkey2"]
- }
- ],
- "need_reboot" => false
- }
- end
-
- test "proxy tuple localhost", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: ":http",
- value: [
- %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]}
- ]
- }
- ]
- })
-
- assert %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":http",
- "value" => value,
- "db" => db
- }
- ]
- } = json_response_and_validate_schema(conn, 200)
-
- assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]} in value
- assert ":proxy_url" in db
- end
-
- test "proxy tuple domain", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: ":http",
- value: [
- %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]}
- ]
- }
- ]
- })
-
- assert %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":http",
- "value" => value,
- "db" => db
- }
- ]
- } = json_response_and_validate_schema(conn, 200)
-
- assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]} in value
- assert ":proxy_url" in db
- end
-
- test "proxy tuple ip", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: ":http",
- value: [
- %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]}
- ]
- }
- ]
- })
-
- assert %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => ":http",
- "value" => value,
- "db" => db
- }
- ]
- } = json_response_and_validate_schema(conn, 200)
-
- assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} in value
- assert ":proxy_url" in db
- end
-
- @tag capture_log: true
- test "doesn't set keys not in the whitelist", %{conn: conn} do
- clear_config(:database_config_whitelist, [
- {:pleroma, :key1},
- {:pleroma, :key2},
- {:pleroma, Pleroma.Captcha.NotReal},
- {:not_real}
- ])
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{group: ":pleroma", key: ":key1", value: "value1"},
- %{group: ":pleroma", key: ":key2", value: "value2"},
- %{group: ":pleroma", key: ":key3", value: "value3"},
- %{group: ":pleroma", key: "Pleroma.Web.Endpoint.NotReal", value: "value4"},
- %{group: ":pleroma", key: "Pleroma.Captcha.NotReal", value: "value5"},
- %{group: ":not_real", key: ":anything", value: "value6"}
- ]
- })
-
- assert Application.get_env(:pleroma, :key1) == "value1"
- assert Application.get_env(:pleroma, :key2) == "value2"
- assert Application.get_env(:pleroma, :key3) == nil
- assert Application.get_env(:pleroma, Pleroma.Web.Endpoint.NotReal) == nil
- assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == "value5"
- assert Application.get_env(:not_real, :anything) == "value6"
- end
-
- test "args for Pleroma.Upload.Filter.Mogrify with custom tuples", %{conn: conn} do
- clear_config(Pleroma.Upload.Filter.Mogrify)
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: "Pleroma.Upload.Filter.Mogrify",
- value: [
- %{"tuple" => [":args", ["auto-orient", "strip"]]}
- ]
- }
- ]
- })
- |> json_response_and_validate_schema(200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => "Pleroma.Upload.Filter.Mogrify",
- "value" => [
- %{"tuple" => [":args", ["auto-orient", "strip"]]}
- ],
- "db" => [":args"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Config.get(Pleroma.Upload.Filter.Mogrify) == [args: ["auto-orient", "strip"]]
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{
- configs: [
- %{
- group: ":pleroma",
- key: "Pleroma.Upload.Filter.Mogrify",
- value: [
- %{
- "tuple" => [
- ":args",
- [
- "auto-orient",
- "strip",
- "{\"implode\", \"1\"}",
- "{\"resize\", \"3840x1080>\"}"
- ]
- ]
- }
- ]
- }
- ]
- })
- |> json_response(200) == %{
- "configs" => [
- %{
- "group" => ":pleroma",
- "key" => "Pleroma.Upload.Filter.Mogrify",
- "value" => [
- %{
- "tuple" => [
- ":args",
- [
- "auto-orient",
- "strip",
- "{\"implode\", \"1\"}",
- "{\"resize\", \"3840x1080>\"}"
- ]
- ]
- }
- ],
- "db" => [":args"]
- }
- ],
- "need_reboot" => false
- }
-
- assert Config.get(Pleroma.Upload.Filter.Mogrify) == [
- args: ["auto-orient", "strip", {"implode", "1"}, {"resize", "3840x1080>"}]
- ]
- end
-
- test "enables the welcome messages", %{conn: conn} do
- clear_config([:welcome])
-
- params = %{
- "group" => ":pleroma",
- "key" => ":welcome",
- "value" => [
- %{
- "tuple" => [
- ":direct_message",
- [
- %{"tuple" => [":enabled", true]},
- %{"tuple" => [":message", "Welcome to Pleroma!"]},
- %{"tuple" => [":sender_nickname", "pleroma"]}
- ]
- ]
- },
- %{
- "tuple" => [
- ":chat_message",
- [
- %{"tuple" => [":enabled", true]},
- %{"tuple" => [":message", "Welcome to Pleroma!"]},
- %{"tuple" => [":sender_nickname", "pleroma"]}
- ]
- ]
- },
- %{
- "tuple" => [
- ":email",
- [
- %{"tuple" => [":enabled", true]},
- %{"tuple" => [":sender", %{"tuple" => ["pleroma@dev.dev", "Pleroma"]}]},
- %{"tuple" => [":subject", "Welcome to <%= instance_name %>!"]},
- %{"tuple" => [":html", "Welcome to <%= instance_name %>!"]},
- %{"tuple" => [":text", "Welcome to <%= instance_name %>!"]}
- ]
- ]
- }
- ]
- }
-
- refute Pleroma.User.WelcomeEmail.enabled?()
- refute Pleroma.User.WelcomeMessage.enabled?()
- refute Pleroma.User.WelcomeChatMessage.enabled?()
-
- res =
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/config", %{"configs" => [params]})
- |> json_response_and_validate_schema(200)
-
- assert Pleroma.User.WelcomeEmail.enabled?()
- assert Pleroma.User.WelcomeMessage.enabled?()
- assert Pleroma.User.WelcomeChatMessage.enabled?()
-
- assert res == %{
- "configs" => [
- %{
- "db" => [":direct_message", ":chat_message", ":email"],
- "group" => ":pleroma",
- "key" => ":welcome",
- "value" => params["value"]
- }
- ],
- "need_reboot" => false
- }
- end
- end
-
- describe "GET /api/pleroma/admin/config/descriptions" do
- test "structure", %{conn: conn} do
- admin = insert(:user, is_admin: true)
-
- conn =
- assign(conn, :user, admin)
- |> get("/api/pleroma/admin/config/descriptions")
-
- assert [child | _others] = json_response_and_validate_schema(conn, 200)
-
- assert child["children"]
- assert child["key"]
- assert String.starts_with?(child["group"], ":")
- assert child["description"]
- end
-
- test "filters by database configuration whitelist", %{conn: conn} do
- clear_config(:database_config_whitelist, [
- {:pleroma, :instance},
- {:pleroma, :activitypub},
- {:pleroma, Pleroma.Upload},
- {:esshd}
- ])
-
- admin = insert(:user, is_admin: true)
-
- conn =
- assign(conn, :user, admin)
- |> get("/api/pleroma/admin/config/descriptions")
-
- children = json_response_and_validate_schema(conn, 200)
-
- assert length(children) == 4
-
- assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 3
-
- instance = Enum.find(children, fn c -> c["key"] == ":instance" end)
- assert instance["children"]
-
- activitypub = Enum.find(children, fn c -> c["key"] == ":activitypub" end)
- assert activitypub["children"]
-
- web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end)
- assert web_endpoint["children"]
-
- esshd = Enum.find(children, fn c -> c["group"] == ":esshd" end)
- assert esshd["children"]
- end
- end
-end
diff --git a/test/web/admin_api/controllers/invite_controller_test.exs b/test/web/admin_api/controllers/invite_controller_test.exs
deleted file mode 100644
index ab186c5e7..000000000
--- a/test/web/admin_api/controllers/invite_controller_test.exs
+++ /dev/null
@@ -1,281 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
- use Pleroma.Web.ConnCase, async: true
-
- import Pleroma.Factory
-
- alias Pleroma.Config
- alias Pleroma.Repo
- alias Pleroma.UserInviteToken
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "POST /api/pleroma/admin/users/email_invite, with valid config" do
- setup do: clear_config([:instance, :registrations_open], false)
- setup do: clear_config([:instance, :invites_enabled], true)
-
- test "sends invitation and returns 204", %{admin: admin, conn: conn} do
- recipient_email = "foo@bar.com"
- recipient_name = "J. D."
-
- conn =
- conn
- |> put_req_header("content-type", "application/json;charset=utf-8")
- |> post("/api/pleroma/admin/users/email_invite", %{
- email: recipient_email,
- name: recipient_name
- })
-
- assert json_response_and_validate_schema(conn, :no_content)
-
- token_record = List.last(Repo.all(Pleroma.UserInviteToken))
- assert token_record
- refute token_record.used
-
- notify_email = Config.get([:instance, :notify_email])
- instance_name = Config.get([:instance, :name])
-
- email =
- Pleroma.Emails.UserEmail.user_invitation_email(
- admin,
- token_record,
- recipient_email,
- recipient_name
- )
-
- Swoosh.TestAssertions.assert_email_sent(
- from: {instance_name, notify_email},
- to: {recipient_name, recipient_email},
- html_body: email.html_body
- )
- end
-
- test "it returns 403 if requested by a non-admin" do
- non_admin_user = insert(:user)
- token = insert(:oauth_token, user: non_admin_user)
-
- conn =
- build_conn()
- |> assign(:user, non_admin_user)
- |> assign(:token, token)
- |> put_req_header("content-type", "application/json;charset=utf-8")
- |> post("/api/pleroma/admin/users/email_invite", %{
- email: "foo@bar.com",
- name: "JD"
- })
-
- assert json_response(conn, :forbidden)
- end
-
- test "email with +", %{conn: conn, admin: admin} do
- recipient_email = "foo+bar@baz.com"
-
- conn
- |> put_req_header("content-type", "application/json;charset=utf-8")
- |> post("/api/pleroma/admin/users/email_invite", %{email: recipient_email})
- |> json_response_and_validate_schema(:no_content)
-
- token_record =
- Pleroma.UserInviteToken
- |> Repo.all()
- |> List.last()
-
- assert token_record
- refute token_record.used
-
- notify_email = Config.get([:instance, :notify_email])
- instance_name = Config.get([:instance, :name])
-
- email =
- Pleroma.Emails.UserEmail.user_invitation_email(
- admin,
- token_record,
- recipient_email
- )
-
- Swoosh.TestAssertions.assert_email_sent(
- from: {instance_name, notify_email},
- to: recipient_email,
- html_body: email.html_body
- )
- end
- end
-
- describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
- setup do: clear_config([:instance, :registrations_open])
- setup do: clear_config([:instance, :invites_enabled])
-
- test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
- Config.put([:instance, :registrations_open], false)
- Config.put([:instance, :invites_enabled], false)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/email_invite", %{
- email: "foo@bar.com",
- name: "JD"
- })
-
- assert json_response_and_validate_schema(conn, :bad_request) ==
- %{
- "error" =>
- "To send invites you need to set the `invites_enabled` option to true."
- }
- end
-
- test "it returns 500 if `registrations_open` is enabled", %{conn: conn} do
- Config.put([:instance, :registrations_open], true)
- Config.put([:instance, :invites_enabled], true)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/email_invite", %{
- email: "foo@bar.com",
- name: "JD"
- })
-
- assert json_response_and_validate_schema(conn, :bad_request) ==
- %{
- "error" =>
- "To send invites you need to set the `registrations_open` option to false."
- }
- end
- end
-
- describe "POST /api/pleroma/admin/users/invite_token" do
- test "without options", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/invite_token")
-
- invite_json = json_response_and_validate_schema(conn, 200)
- invite = UserInviteToken.find_by_token!(invite_json["token"])
- refute invite.used
- refute invite.expires_at
- refute invite.max_use
- assert invite.invite_type == "one_time"
- end
-
- test "with expires_at", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/invite_token", %{
- "expires_at" => Date.to_string(Date.utc_today())
- })
-
- invite_json = json_response_and_validate_schema(conn, 200)
- invite = UserInviteToken.find_by_token!(invite_json["token"])
-
- refute invite.used
- assert invite.expires_at == Date.utc_today()
- refute invite.max_use
- assert invite.invite_type == "date_limited"
- end
-
- test "with max_use", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
-
- invite_json = json_response_and_validate_schema(conn, 200)
- invite = UserInviteToken.find_by_token!(invite_json["token"])
- refute invite.used
- refute invite.expires_at
- assert invite.max_use == 150
- assert invite.invite_type == "reusable"
- end
-
- test "with max use and expires_at", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/invite_token", %{
- "max_use" => 150,
- "expires_at" => Date.to_string(Date.utc_today())
- })
-
- invite_json = json_response_and_validate_schema(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
- assert invite.invite_type == "reusable_date_limited"
- end
- end
-
- describe "GET /api/pleroma/admin/users/invites" do
- test "no invites", %{conn: conn} do
- conn = get(conn, "/api/pleroma/admin/users/invites")
-
- assert json_response_and_validate_schema(conn, 200) == %{"invites" => []}
- end
-
- test "with invite", %{conn: conn} do
- {:ok, invite} = UserInviteToken.create_invite()
-
- conn = get(conn, "/api/pleroma/admin/users/invites")
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "invites" => [
- %{
- "expires_at" => nil,
- "id" => invite.id,
- "invite_type" => "one_time",
- "max_use" => nil,
- "token" => invite.token,
- "used" => false,
- "uses" => 0
- }
- ]
- }
- end
- end
-
- describe "POST /api/pleroma/admin/users/revoke_invite" do
- test "with token", %{conn: conn} do
- {:ok, invite} = UserInviteToken.create_invite()
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "expires_at" => nil,
- "id" => invite.id,
- "invite_type" => "one_time",
- "max_use" => nil,
- "token" => invite.token,
- "used" => true,
- "uses" => 0
- }
- end
-
- test "with invalid token", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
-
- assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
- end
- end
-end
diff --git a/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs b/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs
deleted file mode 100644
index f243d1fb2..000000000
--- a/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs
+++ /dev/null
@@ -1,167 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
- import Mock
-
- alias Pleroma.Web.MediaProxy
-
- setup do: clear_config([:media_proxy])
-
- setup do
- on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
- end
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- Config.put([:media_proxy, :enabled], true)
- Config.put([:media_proxy, :invalidation, :enabled], true)
- Config.put([:media_proxy, :invalidation, :provider], MediaProxy.Invalidation.Script)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "GET /api/pleroma/admin/media_proxy_caches" do
- test "shows banned MediaProxy URLs", %{conn: conn} do
- MediaProxy.put_in_banned_urls([
- "http://localhost:4001/media/a688346.jpg",
- "http://localhost:4001/media/fb1f4d.jpg"
- ])
-
- MediaProxy.put_in_banned_urls("http://localhost:4001/media/gb1f44.jpg")
- MediaProxy.put_in_banned_urls("http://localhost:4001/media/tb13f47.jpg")
- MediaProxy.put_in_banned_urls("http://localhost:4001/media/wb1f46.jpg")
-
- response =
- conn
- |> get("/api/pleroma/admin/media_proxy_caches?page_size=2")
- |> json_response_and_validate_schema(200)
-
- assert response["page_size"] == 2
- assert response["count"] == 5
-
- assert response["urls"] == [
- "http://localhost:4001/media/fb1f4d.jpg",
- "http://localhost:4001/media/a688346.jpg"
- ]
-
- response =
- conn
- |> get("/api/pleroma/admin/media_proxy_caches?page_size=2&page=2")
- |> json_response_and_validate_schema(200)
-
- assert response["urls"] == [
- "http://localhost:4001/media/gb1f44.jpg",
- "http://localhost:4001/media/tb13f47.jpg"
- ]
-
- assert response["page_size"] == 2
- assert response["count"] == 5
-
- response =
- conn
- |> get("/api/pleroma/admin/media_proxy_caches?page_size=2&page=3")
- |> json_response_and_validate_schema(200)
-
- assert response["urls"] == ["http://localhost:4001/media/wb1f46.jpg"]
- end
-
- test "search banned MediaProxy URLs", %{conn: conn} do
- MediaProxy.put_in_banned_urls([
- "http://localhost:4001/media/a688346.jpg",
- "http://localhost:4001/media/ff44b1f4d.jpg"
- ])
-
- MediaProxy.put_in_banned_urls("http://localhost:4001/media/gb1f44.jpg")
- MediaProxy.put_in_banned_urls("http://localhost:4001/media/tb13f47.jpg")
- MediaProxy.put_in_banned_urls("http://localhost:4001/media/wb1f46.jpg")
-
- response =
- conn
- |> get("/api/pleroma/admin/media_proxy_caches?page_size=2&query=F44")
- |> json_response_and_validate_schema(200)
-
- assert response["urls"] == [
- "http://localhost:4001/media/gb1f44.jpg",
- "http://localhost:4001/media/ff44b1f4d.jpg"
- ]
-
- assert response["page_size"] == 2
- assert response["count"] == 2
- end
- end
-
- describe "POST /api/pleroma/admin/media_proxy_caches/delete" do
- test "deleted MediaProxy URLs from banned", %{conn: conn} do
- MediaProxy.put_in_banned_urls([
- "http://localhost:4001/media/a688346.jpg",
- "http://localhost:4001/media/fb1f4d.jpg"
- ])
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/media_proxy_caches/delete", %{
- urls: ["http://localhost:4001/media/a688346.jpg"]
- })
- |> json_response_and_validate_schema(200)
-
- refute MediaProxy.in_banned_urls("http://localhost:4001/media/a688346.jpg")
- assert MediaProxy.in_banned_urls("http://localhost:4001/media/fb1f4d.jpg")
- end
- end
-
- describe "POST /api/pleroma/admin/media_proxy_caches/purge" do
- test "perform invalidates cache of MediaProxy", %{conn: conn} do
- urls = [
- "http://example.com/media/a688346.jpg",
- "http://example.com/media/fb1f4d.jpg"
- ]
-
- with_mocks [
- {MediaProxy.Invalidation.Script, [],
- [
- purge: fn _, _ -> {"ok", 0} end
- ]}
- ] do
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/media_proxy_caches/purge", %{urls: urls, ban: false})
- |> json_response_and_validate_schema(200)
-
- refute MediaProxy.in_banned_urls("http://example.com/media/a688346.jpg")
- refute MediaProxy.in_banned_urls("http://example.com/media/fb1f4d.jpg")
- end
- end
-
- test "perform invalidates cache of MediaProxy and adds url to banned", %{conn: conn} do
- urls = [
- "http://example.com/media/a688346.jpg",
- "http://example.com/media/fb1f4d.jpg"
- ]
-
- with_mocks [{MediaProxy.Invalidation.Script, [], [purge: fn _, _ -> {"ok", 0} end]}] do
- conn
- |> put_req_header("content-type", "application/json")
- |> post(
- "/api/pleroma/admin/media_proxy_caches/purge",
- %{urls: urls, ban: true}
- )
- |> json_response_and_validate_schema(200)
-
- assert MediaProxy.in_banned_urls("http://example.com/media/a688346.jpg")
- assert MediaProxy.in_banned_urls("http://example.com/media/fb1f4d.jpg")
- end
- end
- end
-end
diff --git a/test/web/admin_api/controllers/oauth_app_controller_test.exs b/test/web/admin_api/controllers/oauth_app_controller_test.exs
deleted file mode 100644
index ed7c4172c..000000000
--- a/test/web/admin_api/controllers/oauth_app_controller_test.exs
+++ /dev/null
@@ -1,220 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.OAuthAppControllerTest do
- use Pleroma.Web.ConnCase, async: true
- use Oban.Testing, repo: Pleroma.Repo
-
- import Pleroma.Factory
-
- alias Pleroma.Config
- alias Pleroma.Web
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "POST /api/pleroma/admin/oauth_app" do
- test "errors", %{conn: conn} do
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/oauth_app", %{})
- |> json_response_and_validate_schema(400)
-
- assert %{
- "error" => "Missing field: name. Missing field: redirect_uris."
- } = response
- end
-
- test "success", %{conn: conn} do
- base_url = Web.base_url()
- app_name = "Trusted app"
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/oauth_app", %{
- name: app_name,
- redirect_uris: base_url
- })
- |> json_response_and_validate_schema(200)
-
- assert %{
- "client_id" => _,
- "client_secret" => _,
- "name" => ^app_name,
- "redirect_uri" => ^base_url,
- "trusted" => false
- } = response
- end
-
- test "with trusted", %{conn: conn} do
- base_url = Web.base_url()
- app_name = "Trusted app"
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/oauth_app", %{
- name: app_name,
- redirect_uris: base_url,
- trusted: true
- })
- |> json_response_and_validate_schema(200)
-
- assert %{
- "client_id" => _,
- "client_secret" => _,
- "name" => ^app_name,
- "redirect_uri" => ^base_url,
- "trusted" => true
- } = response
- end
- end
-
- describe "GET /api/pleroma/admin/oauth_app" do
- setup do
- app = insert(:oauth_app)
- {:ok, app: app}
- end
-
- test "list", %{conn: conn} do
- response =
- conn
- |> get("/api/pleroma/admin/oauth_app")
- |> json_response_and_validate_schema(200)
-
- assert %{"apps" => apps, "count" => count, "page_size" => _} = response
-
- assert length(apps) == count
- end
-
- test "with page size", %{conn: conn} do
- insert(:oauth_app)
- page_size = 1
-
- response =
- conn
- |> get("/api/pleroma/admin/oauth_app?page_size=#{page_size}")
- |> json_response_and_validate_schema(200)
-
- assert %{"apps" => apps, "count" => _, "page_size" => ^page_size} = response
-
- assert length(apps) == page_size
- end
-
- test "search by client name", %{conn: conn, app: app} do
- response =
- conn
- |> get("/api/pleroma/admin/oauth_app?name=#{app.client_name}")
- |> json_response_and_validate_schema(200)
-
- assert %{"apps" => [returned], "count" => _, "page_size" => _} = response
-
- assert returned["client_id"] == app.client_id
- assert returned["name"] == app.client_name
- end
-
- test "search by client id", %{conn: conn, app: app} do
- response =
- conn
- |> get("/api/pleroma/admin/oauth_app?client_id=#{app.client_id}")
- |> json_response_and_validate_schema(200)
-
- assert %{"apps" => [returned], "count" => _, "page_size" => _} = response
-
- assert returned["client_id"] == app.client_id
- assert returned["name"] == app.client_name
- end
-
- test "only trusted", %{conn: conn} do
- app = insert(:oauth_app, trusted: true)
-
- response =
- conn
- |> get("/api/pleroma/admin/oauth_app?trusted=true")
- |> json_response_and_validate_schema(200)
-
- assert %{"apps" => [returned], "count" => _, "page_size" => _} = response
-
- assert returned["client_id"] == app.client_id
- assert returned["name"] == app.client_name
- end
- end
-
- describe "DELETE /api/pleroma/admin/oauth_app/:id" do
- test "with id", %{conn: conn} do
- app = insert(:oauth_app)
-
- response =
- conn
- |> delete("/api/pleroma/admin/oauth_app/" <> to_string(app.id))
- |> json_response_and_validate_schema(:no_content)
-
- assert response == ""
- end
-
- test "with non existance id", %{conn: conn} do
- response =
- conn
- |> delete("/api/pleroma/admin/oauth_app/0")
- |> json_response_and_validate_schema(:bad_request)
-
- assert response == ""
- end
- end
-
- describe "PATCH /api/pleroma/admin/oauth_app/:id" do
- test "with id", %{conn: conn} do
- app = insert(:oauth_app)
-
- name = "another name"
- url = "https://example.com"
- scopes = ["admin"]
- id = app.id
- website = "http://website.com"
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/oauth_app/#{id}", %{
- name: name,
- trusted: true,
- redirect_uris: url,
- scopes: scopes,
- website: website
- })
- |> json_response_and_validate_schema(200)
-
- assert %{
- "client_id" => _,
- "client_secret" => _,
- "id" => ^id,
- "name" => ^name,
- "redirect_uri" => ^url,
- "trusted" => true,
- "website" => ^website
- } = response
- end
-
- test "without id", %{conn: conn} do
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/oauth_app/0")
- |> json_response_and_validate_schema(:bad_request)
-
- assert response == ""
- end
- end
-end
diff --git a/test/web/admin_api/controllers/relay_controller_test.exs b/test/web/admin_api/controllers/relay_controller_test.exs
deleted file mode 100644
index adadf2b5c..000000000
--- a/test/web/admin_api/controllers/relay_controller_test.exs
+++ /dev/null
@@ -1,99 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.RelayControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Config
- alias Pleroma.ModerationLog
- alias Pleroma.Repo
- alias Pleroma.User
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
-
- :ok
- end
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "relays" do
- test "POST /relay", %{conn: conn, admin: admin} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/relay", %{
- relay_url: "http://mastodon.example.org/users/admin"
- })
-
- assert json_response_and_validate_schema(conn, 200) == %{
- "actor" => "http://mastodon.example.org/users/admin",
- "followed_back" => false
- }
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
- end
-
- test "GET /relay", %{conn: conn} do
- relay_user = Pleroma.Web.ActivityPub.Relay.get_actor()
-
- ["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
- |> Enum.each(fn ap_id ->
- {:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
- User.follow(relay_user, user)
- end)
-
- conn = get(conn, "/api/pleroma/admin/relay")
-
- assert json_response_and_validate_schema(conn, 200)["relays"] == [
- %{
- "actor" => "http://mastodon.example.org/users/admin",
- "followed_back" => true
- },
- %{"actor" => "https://mstdn.io/users/mayuutann", "followed_back" => true}
- ]
- end
-
- test "DELETE /relay", %{conn: conn, admin: admin} do
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/relay", %{
- relay_url: "http://mastodon.example.org/users/admin"
- })
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> delete("/api/pleroma/admin/relay", %{
- relay_url: "http://mastodon.example.org/users/admin"
- })
-
- assert json_response_and_validate_schema(conn, 200) ==
- "http://mastodon.example.org/users/admin"
-
- [log_entry_one, log_entry_two] = Repo.all(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry_one) ==
- "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
-
- assert ModerationLog.get_log_entry_message(log_entry_two) ==
- "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
- end
- end
-end
diff --git a/test/web/admin_api/controllers/report_controller_test.exs b/test/web/admin_api/controllers/report_controller_test.exs
deleted file mode 100644
index 57946e6bb..000000000
--- a/test/web/admin_api/controllers/report_controller_test.exs
+++ /dev/null
@@ -1,372 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Activity
- alias Pleroma.Config
- alias Pleroma.ModerationLog
- alias Pleroma.Repo
- alias Pleroma.ReportNote
- alias Pleroma.Web.CommonAPI
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "GET /api/pleroma/admin/reports/:id" do
- test "returns report by its id", %{conn: conn} do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %{id: report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- response =
- conn
- |> get("/api/pleroma/admin/reports/#{report_id}")
- |> json_response_and_validate_schema(:ok)
-
- assert response["id"] == report_id
- end
-
- test "returns 404 when report id is invalid", %{conn: conn} do
- conn = get(conn, "/api/pleroma/admin/reports/test")
-
- assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
- end
- end
-
- describe "PATCH /api/pleroma/admin/reports" do
- setup do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %{id: report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- {:ok, %{id: second_report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel very offended",
- status_ids: [activity.id]
- })
-
- %{
- id: report_id,
- second_report_id: second_report_id
- }
- end
-
- test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
- read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
- write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
-
- response =
- conn
- |> assign(:token, read_token)
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [%{"state" => "resolved", "id" => id}]
- })
- |> json_response_and_validate_schema(403)
-
- assert response == %{
- "error" => "Insufficient permissions: admin:write:reports."
- }
-
- conn
- |> assign(:token, write_token)
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [%{"state" => "resolved", "id" => id}]
- })
- |> json_response_and_validate_schema(:no_content)
- end
-
- test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [
- %{"state" => "resolved", "id" => id}
- ]
- })
- |> json_response_and_validate_schema(:no_content)
-
- activity = Activity.get_by_id(id)
- assert activity.data["state"] == "resolved"
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} updated report ##{id} with 'resolved' state"
- end
-
- test "closes report", %{conn: conn, id: id, admin: admin} do
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [
- %{"state" => "closed", "id" => id}
- ]
- })
- |> json_response_and_validate_schema(:no_content)
-
- activity = Activity.get_by_id(id)
- assert activity.data["state"] == "closed"
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} updated report ##{id} with 'closed' state"
- end
-
- test "returns 400 when state is unknown", %{conn: conn, id: id} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [
- %{"state" => "test", "id" => id}
- ]
- })
-
- assert "Unsupported state" =
- hd(json_response_and_validate_schema(conn, :bad_request))["error"]
- end
-
- test "returns 404 when report is not exist", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [
- %{"state" => "closed", "id" => "test"}
- ]
- })
-
- assert hd(json_response_and_validate_schema(conn, :bad_request))["error"] == "not_found"
- end
-
- test "updates state of multiple reports", %{
- conn: conn,
- id: id,
- admin: admin,
- second_report_id: second_report_id
- } do
- conn
- |> put_req_header("content-type", "application/json")
- |> patch("/api/pleroma/admin/reports", %{
- "reports" => [
- %{"state" => "resolved", "id" => id},
- %{"state" => "closed", "id" => second_report_id}
- ]
- })
- |> json_response_and_validate_schema(:no_content)
-
- activity = Activity.get_by_id(id)
- second_activity = Activity.get_by_id(second_report_id)
- assert activity.data["state"] == "resolved"
- assert second_activity.data["state"] == "closed"
-
- [first_log_entry, second_log_entry] = Repo.all(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(first_log_entry) ==
- "@#{admin.nickname} updated report ##{id} with 'resolved' state"
-
- assert ModerationLog.get_log_entry_message(second_log_entry) ==
- "@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"
- end
- end
-
- describe "GET /api/pleroma/admin/reports" do
- test "returns empty response when no reports created", %{conn: conn} do
- response =
- conn
- |> get(report_path(conn, :index))
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response["reports"])
- assert response["total"] == 0
- end
-
- test "returns reports", %{conn: conn} do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %{id: report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- response =
- conn
- |> get(report_path(conn, :index))
- |> json_response_and_validate_schema(:ok)
-
- [report] = response["reports"]
-
- assert length(response["reports"]) == 1
- assert report["id"] == report_id
-
- assert response["total"] == 1
- end
-
- test "returns reports with specified state", %{conn: conn} do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %{id: first_report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- {:ok, %{id: second_report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I don't like this user"
- })
-
- CommonAPI.update_report_state(second_report_id, "closed")
-
- response =
- conn
- |> get(report_path(conn, :index, %{state: "open"}))
- |> json_response_and_validate_schema(:ok)
-
- assert [open_report] = response["reports"]
-
- assert length(response["reports"]) == 1
- assert open_report["id"] == first_report_id
-
- assert response["total"] == 1
-
- response =
- conn
- |> get(report_path(conn, :index, %{state: "closed"}))
- |> json_response_and_validate_schema(:ok)
-
- assert [closed_report] = response["reports"]
-
- assert length(response["reports"]) == 1
- assert closed_report["id"] == second_report_id
-
- assert response["total"] == 1
-
- assert %{"total" => 0, "reports" => []} ==
- conn
- |> get(report_path(conn, :index, %{state: "resolved"}))
- |> json_response_and_validate_schema(:ok)
- end
-
- test "returns 403 when requested by a non-admin" do
- user = insert(:user)
- token = insert(:oauth_token, user: user)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> assign(:token, token)
- |> get("/api/pleroma/admin/reports")
-
- assert json_response(conn, :forbidden) ==
- %{"error" => "User is not an admin."}
- end
-
- test "returns 403 when requested by anonymous" do
- conn = get(build_conn(), "/api/pleroma/admin/reports")
-
- assert json_response(conn, :forbidden) == %{
- "error" => "Invalid credentials."
- }
- end
- end
-
- describe "POST /api/pleroma/admin/reports/:id/notes" do
- setup %{conn: conn, admin: admin} do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %{id: report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
- content: "this is disgusting!"
- })
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
- content: "this is disgusting2!"
- })
-
- %{
- admin_id: admin.id,
- report_id: report_id
- }
- end
-
- test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
- assert [note, _] = Repo.all(ReportNote)
-
- assert %{
- activity_id: ^report_id,
- content: "this is disgusting!",
- user_id: ^admin_id
- } = note
- end
-
- test "it returns reports with notes", %{conn: conn, admin: admin} do
- conn = get(conn, "/api/pleroma/admin/reports")
-
- response = json_response_and_validate_schema(conn, 200)
- notes = hd(response["reports"])["notes"]
- [note, _] = notes
-
- assert note["user"]["nickname"] == admin.nickname
- assert note["content"] == "this is disgusting!"
- assert note["created_at"]
- assert response["total"] == 1
- end
-
- test "it deletes the note", %{conn: conn, report_id: report_id} do
- assert ReportNote |> Repo.all() |> length() == 2
- assert [note, _] = Repo.all(ReportNote)
-
- delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}")
-
- assert ReportNote |> Repo.all() |> length() == 1
- end
- end
-end
diff --git a/test/web/admin_api/controllers/status_controller_test.exs b/test/web/admin_api/controllers/status_controller_test.exs
deleted file mode 100644
index eff78fb0a..000000000
--- a/test/web/admin_api/controllers/status_controller_test.exs
+++ /dev/null
@@ -1,202 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Activity
- alias Pleroma.Config
- alias Pleroma.ModerationLog
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- {:ok, %{admin: admin, token: token, conn: conn}}
- end
-
- describe "GET /api/pleroma/admin/statuses/:id" do
- test "not found", %{conn: conn} do
- assert conn
- |> get("/api/pleroma/admin/statuses/not_found")
- |> json_response_and_validate_schema(:not_found)
- end
-
- test "shows activity", %{conn: conn} do
- activity = insert(:note_activity)
-
- response =
- conn
- |> get("/api/pleroma/admin/statuses/#{activity.id}")
- |> json_response_and_validate_schema(200)
-
- assert response["id"] == activity.id
-
- account = response["account"]
- actor = User.get_by_ap_id(activity.actor)
-
- assert account["id"] == actor.id
- assert account["nickname"] == actor.nickname
- assert account["deactivated"] == actor.deactivated
- assert account["confirmation_pending"] == actor.confirmation_pending
- end
- end
-
- describe "PUT /api/pleroma/admin/statuses/:id" do
- setup do
- activity = insert(:note_activity)
-
- %{id: activity.id}
- end
-
- test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
- |> json_response_and_validate_schema(:ok)
-
- assert response["sensitive"]
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
- |> json_response_and_validate_schema(:ok)
-
- refute response["sensitive"]
- end
-
- test "change visibility flag", %{conn: conn, id: id, admin: admin} do
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "public"})
- |> json_response_and_validate_schema(:ok)
-
- assert response["visibility"] == "public"
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "private"})
- |> json_response_and_validate_schema(:ok)
-
- assert response["visibility"] == "private"
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "unlisted"})
- |> json_response_and_validate_schema(:ok)
-
- assert response["visibility"] == "unlisted"
- end
-
- test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "test"})
-
- assert %{"error" => "test - Invalid value for enum."} =
- json_response_and_validate_schema(conn, :bad_request)
- end
- end
-
- describe "DELETE /api/pleroma/admin/statuses/:id" do
- setup do
- activity = insert(:note_activity)
-
- %{id: activity.id}
- end
-
- test "deletes status", %{conn: conn, id: id, admin: admin} do
- conn
- |> delete("/api/pleroma/admin/statuses/#{id}")
- |> json_response_and_validate_schema(:ok)
-
- refute Activity.get_by_id(id)
-
- log_entry = Repo.one(ModerationLog)
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} deleted status ##{id}"
- end
-
- test "returns 404 when the status does not exist", %{conn: conn} do
- conn = delete(conn, "/api/pleroma/admin/statuses/test")
-
- assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
- end
- end
-
- describe "GET /api/pleroma/admin/statuses" do
- test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do
- blocked = insert(:user)
- user = insert(:user)
- User.block(admin, blocked)
-
- {:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"})
-
- {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
- {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"})
- {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"})
- {:ok, _} = CommonAPI.post(blocked, %{status: ".", visibility: "public"})
-
- response =
- conn
- |> get("/api/pleroma/admin/statuses")
- |> json_response_and_validate_schema(200)
-
- refute "private" in Enum.map(response, & &1["visibility"])
- assert length(response) == 3
- end
-
- test "returns only local statuses with local_only on", %{conn: conn} do
- user = insert(:user)
- remote_user = insert(:user, local: false, nickname: "archaeme@archae.me")
- insert(:note_activity, user: user, local: true)
- insert(:note_activity, user: remote_user, local: false)
-
- response =
- conn
- |> get("/api/pleroma/admin/statuses?local_only=true")
- |> json_response_and_validate_schema(200)
-
- assert length(response) == 1
- end
-
- test "returns private and direct statuses with godmode on", %{conn: conn, admin: admin} do
- user = insert(:user)
-
- {:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"})
-
- {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"})
- {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"})
- conn = get(conn, "/api/pleroma/admin/statuses?godmode=true")
- assert json_response_and_validate_schema(conn, 200) |> length() == 3
- end
- end
-end
diff --git a/test/web/admin_api/search_test.exs b/test/web/admin_api/search_test.exs
deleted file mode 100644
index b974cedd5..000000000
--- a/test/web/admin_api/search_test.exs
+++ /dev/null
@@ -1,181 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.SearchTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Web.AdminAPI.Search
-
- import Pleroma.Factory
-
- describe "search for admin" do
- test "it ignores case" do
- insert(:user, nickname: "papercoach")
- insert(:user, nickname: "CanadaPaperCoach")
-
- {:ok, _results, count} =
- Search.user(%{
- query: "paper",
- local: false,
- page: 1,
- page_size: 50
- })
-
- assert count == 2
- end
-
- test "it returns local/external users" do
- insert(:user, local: true)
- insert(:user, local: false)
- insert(:user, local: false)
-
- {:ok, _results, local_count} =
- Search.user(%{
- query: "",
- local: true
- })
-
- {:ok, _results, external_count} =
- Search.user(%{
- query: "",
- external: true
- })
-
- assert local_count == 1
- assert external_count == 2
- end
-
- test "it returns active/deactivated users" do
- insert(:user, deactivated: true)
- insert(:user, deactivated: true)
- insert(:user, deactivated: false)
-
- {:ok, _results, active_count} =
- Search.user(%{
- query: "",
- active: true
- })
-
- {:ok, _results, deactivated_count} =
- Search.user(%{
- query: "",
- deactivated: true
- })
-
- assert active_count == 1
- assert deactivated_count == 2
- end
-
- test "it returns specific user" do
- insert(:user)
- insert(:user)
- user = insert(:user, nickname: "bob", local: true, deactivated: false)
-
- {:ok, _results, total_count} = Search.user(%{query: ""})
-
- {:ok, [^user], count} =
- Search.user(%{
- query: "Bo",
- active: true,
- local: true
- })
-
- assert total_count == 3
- assert count == 1
- end
-
- test "it returns user by domain" do
- insert(:user)
- insert(:user)
- user = insert(:user, nickname: "some@domain.com")
-
- {:ok, _results, total} = Search.user()
- {:ok, [^user], count} = Search.user(%{query: "domain.com"})
- assert total == 3
- assert count == 1
- end
-
- test "it return user by full nickname" do
- insert(:user)
- insert(:user)
- user = insert(:user, nickname: "some@domain.com")
-
- {:ok, _results, total} = Search.user()
- {:ok, [^user], count} = Search.user(%{query: "some@domain.com"})
- assert total == 3
- assert count == 1
- end
-
- test "it returns admin user" do
- admin = insert(:user, is_admin: true)
- insert(:user)
- insert(:user)
-
- {:ok, _results, total} = Search.user()
- {:ok, [^admin], count} = Search.user(%{is_admin: true})
- assert total == 3
- assert count == 1
- end
-
- test "it returns moderator user" do
- moderator = insert(:user, is_moderator: true)
- insert(:user)
- insert(:user)
-
- {:ok, _results, total} = Search.user()
- {:ok, [^moderator], count} = Search.user(%{is_moderator: true})
- assert total == 3
- assert count == 1
- end
-
- test "it returns users with tags" do
- user1 = insert(:user, tags: ["first"])
- user2 = insert(:user, tags: ["second"])
- insert(:user)
- insert(:user)
-
- {:ok, _results, total} = Search.user()
- {:ok, users, count} = Search.user(%{tags: ["first", "second"]})
- assert total == 4
- assert count == 2
- assert user1 in users
- assert user2 in users
- end
-
- test "it returns user by display name" do
- user = insert(:user, name: "Display name")
- insert(:user)
- insert(:user)
-
- {:ok, _results, total} = Search.user()
- {:ok, [^user], count} = Search.user(%{name: "display"})
-
- assert total == 3
- assert count == 1
- end
-
- test "it returns user by email" do
- user = insert(:user, email: "some@example.com")
- insert(:user)
- insert(:user)
-
- {:ok, _results, total} = Search.user()
- {:ok, [^user], count} = Search.user(%{email: "some@example.com"})
-
- assert total == 3
- assert count == 1
- end
-
- test "it returns unapproved user" do
- unapproved = insert(:user, approval_pending: true)
- insert(:user)
- insert(:user)
-
- {:ok, _results, total} = Search.user()
- {:ok, [^unapproved], count} = Search.user(%{need_approval: true})
- assert total == 3
- assert count == 1
- end
- end
-end
diff --git a/test/web/admin_api/views/report_view_test.exs b/test/web/admin_api/views/report_view_test.exs
deleted file mode 100644
index 5a02292be..000000000
--- a/test/web/admin_api/views/report_view_test.exs
+++ /dev/null
@@ -1,146 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.AdminAPI.ReportViewTest do
- use Pleroma.DataCase
-
- import Pleroma.Factory
-
- alias Pleroma.Web.AdminAPI
- alias Pleroma.Web.AdminAPI.Report
- alias Pleroma.Web.AdminAPI.ReportView
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI
- alias Pleroma.Web.MastodonAPI.StatusView
-
- test "renders a report" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.report(user, %{account_id: other_user.id})
-
- expected = %{
- content: nil,
- actor:
- Map.merge(
- MastodonAPI.AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
- AdminAPI.AccountView.render("show.json", %{user: user})
- ),
- account:
- Map.merge(
- MastodonAPI.AccountView.render("show.json", %{
- user: other_user,
- skip_visibility_check: true
- }),
- AdminAPI.AccountView.render("show.json", %{user: other_user})
- ),
- statuses: [],
- notes: [],
- state: "open",
- id: activity.id
- }
-
- result =
- ReportView.render("show.json", Report.extract_report_info(activity))
- |> Map.delete(:created_at)
-
- assert result == expected
- end
-
- test "includes reported statuses" do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "toot"})
-
- {:ok, report_activity} =
- CommonAPI.report(user, %{account_id: other_user.id, status_ids: [activity.id]})
-
- other_user = Pleroma.User.get_by_id(other_user.id)
-
- expected = %{
- content: nil,
- actor:
- Map.merge(
- MastodonAPI.AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
- AdminAPI.AccountView.render("show.json", %{user: user})
- ),
- account:
- Map.merge(
- MastodonAPI.AccountView.render("show.json", %{
- user: other_user,
- skip_visibility_check: true
- }),
- AdminAPI.AccountView.render("show.json", %{user: other_user})
- ),
- statuses: [StatusView.render("show.json", %{activity: activity})],
- state: "open",
- notes: [],
- id: report_activity.id
- }
-
- result =
- ReportView.render("show.json", Report.extract_report_info(report_activity))
- |> Map.delete(:created_at)
-
- assert result == expected
- end
-
- test "renders report's state" do
- user = insert(:user)
- other_user = insert(:user)
-
- {: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.extract_report_info(activity))
- end
-
- test "renders report description" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.report(user, %{
- account_id: other_user.id,
- comment: "posts are too good for this instance"
- })
-
- assert %{content: "posts are too good for this instance"} =
- ReportView.render("show.json", Report.extract_report_info(activity))
- end
-
- test "sanitizes report description" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.report(user, %{
- account_id: other_user.id,
- comment: ""
- })
-
- data = Map.put(activity.data, "content", "<script> alert('hecked :D:D:D:D:D:D:D') </script>")
- activity = Map.put(activity, :data, data)
-
- refute "<script> alert('hecked :D:D:D:D:D:D:D') </script>" ==
- ReportView.render("show.json", Report.extract_report_info(activity))[:content]
- end
-
- test "doesn't error out when the user doesn't exists" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.report(user, %{
- account_id: other_user.id,
- comment: ""
- })
-
- Pleroma.User.delete(other_user)
- Pleroma.User.invalidate_cache(other_user)
-
- assert %{} = ReportView.render("show.json", Report.extract_report_info(activity))
- end
-end
diff --git a/test/web/api_spec/schema_examples_test.exs b/test/web/api_spec/schema_examples_test.exs
deleted file mode 100644
index f00e834fc..000000000
--- a/test/web/api_spec/schema_examples_test.exs
+++ /dev/null
@@ -1,43 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ApiSpec.SchemaExamplesTest do
- use ExUnit.Case, async: true
- import Pleroma.Tests.ApiSpecHelpers
-
- @content_type "application/json"
-
- for operation <- api_operations() do
- describe operation.operationId <> " Request Body" do
- if operation.requestBody do
- @media_type operation.requestBody.content[@content_type]
- @schema resolve_schema(@media_type.schema)
-
- if @media_type.example do
- test "request body media type example matches schema" do
- assert_schema(@media_type.example, @schema)
- end
- end
-
- if @schema.example do
- test "request body schema example matches schema" do
- assert_schema(@schema.example, @schema)
- end
- end
- end
- end
-
- for {status, response} <- operation.responses, is_map(response.content[@content_type]) do
- describe "#{operation.operationId} - #{status} Response" do
- @schema resolve_schema(response.content[@content_type].schema)
-
- if @schema.example do
- test "example matches schema" do
- assert_schema(@schema.example, @schema)
- end
- end
- end
- end
- end
-end
diff --git a/test/web/auth/auth_test_controller_test.exs b/test/web/auth/auth_test_controller_test.exs
deleted file mode 100644
index fed52b7f3..000000000
--- a/test/web/auth/auth_test_controller_test.exs
+++ /dev/null
@@ -1,242 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Tests.AuthTestControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- describe "do_oauth_check" do
- test "serves with proper OAuth token (fulfilling requested scopes)" do
- %{conn: good_token_conn, user: user} = oauth_access(["read"])
-
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/authenticated_api/do_oauth_check")
- |> json_response(200)
-
- # Unintended usage (:api) — use with :authenticated_api instead
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/api/do_oauth_check")
- |> json_response(200)
- end
-
- test "fails on no token / missing scope(s)" do
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- bad_token_conn
- |> get("/test/authenticated_api/do_oauth_check")
- |> json_response(403)
-
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/do_oauth_check")
- |> json_response(403)
- end
- end
-
- describe "fallback_oauth_check" do
- test "serves with proper OAuth token (fulfilling requested scopes)" do
- %{conn: good_token_conn, user: user} = oauth_access(["read"])
-
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/api/fallback_oauth_check")
- |> json_response(200)
-
- # Unintended usage (:authenticated_api) — use with :api instead
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/authenticated_api/fallback_oauth_check")
- |> json_response(200)
- end
-
- test "for :api on public instance, drops :user and renders on no token / missing scope(s)" do
- clear_config([:instance, :public], true)
-
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> get("/test/api/fallback_oauth_check")
- |> json_response(200)
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/fallback_oauth_check")
- |> json_response(200)
- end
-
- test "for :api on private instance, fails on no token / missing scope(s)" do
- clear_config([:instance, :public], false)
-
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- bad_token_conn
- |> get("/test/api/fallback_oauth_check")
- |> json_response(403)
-
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/fallback_oauth_check")
- |> json_response(403)
- end
- end
-
- describe "skip_oauth_check" do
- test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
- user = insert(:user)
-
- assert %{"user_id" => user.id} ==
- build_conn()
- |> assign(:user, user)
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(200)
-
- %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
-
- assert %{"user_id" => user.id} ==
- bad_token_conn
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(200)
- end
-
- test "serves via :api on public instance if :user is not set" do
- clear_config([:instance, :public], true)
-
- assert %{"user_id" => nil} ==
- build_conn()
- |> get("/test/api/skip_oauth_check")
- |> json_response(200)
-
- build_conn()
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(403)
- end
-
- test "fails on private instance if :user is not set" do
- clear_config([:instance, :public], false)
-
- build_conn()
- |> get("/test/api/skip_oauth_check")
- |> json_response(403)
-
- build_conn()
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(403)
- end
- end
-
- describe "fallback_oauth_skip_publicity_check" do
- test "serves with proper OAuth token (fulfilling requested scopes)" do
- %{conn: good_token_conn, user: user} = oauth_access(["read"])
-
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
-
- # Unintended usage (:authenticated_api)
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/authenticated_api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
- end
-
- test "for :api on private / public instance, drops :user and renders on token issue" do
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- for is_public <- [true, false] do
- clear_config([:instance, :public], is_public)
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> get("/test/api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
- end
- end
- end
-
- describe "skip_oauth_skip_publicity_check" do
- test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
- user = insert(:user)
-
- assert %{"user_id" => user.id} ==
- build_conn()
- |> assign(:user, user)
- |> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
- |> json_response(200)
-
- %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
-
- assert %{"user_id" => user.id} ==
- bad_token_conn
- |> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
- |> json_response(200)
- end
-
- test "for :api, serves on private and public instances regardless of whether :user is set" do
- user = insert(:user)
-
- for is_public <- [true, false] do
- clear_config([:instance, :public], is_public)
-
- assert %{"user_id" => nil} ==
- build_conn()
- |> get("/test/api/skip_oauth_skip_publicity_check")
- |> json_response(200)
-
- assert %{"user_id" => user.id} ==
- build_conn()
- |> assign(:user, user)
- |> get("/test/api/skip_oauth_skip_publicity_check")
- |> json_response(200)
- end
- end
- end
-
- describe "missing_oauth_check_definition" do
- def test_missing_oauth_check_definition_failure(endpoint, expected_error) do
- %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
-
- assert %{"error" => expected_error} ==
- conn
- |> get(endpoint)
- |> json_response(403)
- end
-
- test "fails if served via :authenticated_api" do
- test_missing_oauth_check_definition_failure(
- "/test/authenticated_api/missing_oauth_check_definition",
- "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
- )
- end
-
- test "fails if served via :api and the instance is private" do
- clear_config([:instance, :public], false)
-
- test_missing_oauth_check_definition_failure(
- "/test/api/missing_oauth_check_definition",
- "This resource requires authentication."
- )
- end
-
- test "succeeds with dropped :user if served via :api on public instance" do
- %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
-
- assert %{"user_id" => nil} ==
- conn
- |> get("/test/api/missing_oauth_check_definition")
- |> json_response(200)
- end
- end
-end
diff --git a/test/web/auth/authenticator_test.exs b/test/web/auth/authenticator_test.exs
deleted file mode 100644
index d54253343..000000000
--- a/test/web/auth/authenticator_test.exs
+++ /dev/null
@@ -1,42 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Auth.AuthenticatorTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Web.Auth.Authenticator
- import Pleroma.Factory
-
- describe "fetch_user/1" do
- test "returns user by name" do
- user = insert(:user)
- assert Authenticator.fetch_user(user.nickname) == user
- end
-
- test "returns user by email" do
- user = insert(:user)
- assert Authenticator.fetch_user(user.email) == user
- end
-
- test "returns nil" do
- assert Authenticator.fetch_user("email") == nil
- end
- end
-
- describe "fetch_credentials/1" do
- test "returns name and password from authorization params" do
- params = %{"authorization" => %{"name" => "test", "password" => "test-pass"}}
- assert Authenticator.fetch_credentials(params) == {:ok, {"test", "test-pass"}}
- end
-
- test "returns name and password with grant_type 'password'" do
- params = %{"grant_type" => "password", "username" => "test", "password" => "test-pass"}
- assert Authenticator.fetch_credentials(params) == {:ok, {"test", "test-pass"}}
- end
-
- test "returns error" do
- assert Authenticator.fetch_credentials(%{}) == {:error, :invalid_credentials}
- end
- end
-end
diff --git a/test/web/auth/basic_auth_test.exs b/test/web/auth/basic_auth_test.exs
deleted file mode 100644
index bf6e3d2fc..000000000
--- a/test/web/auth/basic_auth_test.exs
+++ /dev/null
@@ -1,46 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Auth.BasicAuthTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- test "with HTTP Basic Auth used, grants access to OAuth scope-restricted endpoints", %{
- conn: conn
- } do
- user = insert(:user)
- assert Pbkdf2.verify_pass("test", user.password_hash)
-
- basic_auth_contents =
- (URI.encode_www_form(user.nickname) <> ":" <> URI.encode_www_form("test"))
- |> Base.encode64()
-
- # Succeeds with HTTP Basic Auth
- response =
- conn
- |> put_req_header("authorization", "Basic " <> basic_auth_contents)
- |> get("/api/v1/accounts/verify_credentials")
- |> json_response(200)
-
- user_nickname = user.nickname
- assert %{"username" => ^user_nickname} = response
-
- # Succeeds with a properly scoped OAuth token
- valid_token = insert(:oauth_token, scopes: ["read:accounts"])
-
- conn
- |> put_req_header("authorization", "Bearer #{valid_token.token}")
- |> get("/api/v1/accounts/verify_credentials")
- |> json_response(200)
-
- # Fails with a wrong-scoped OAuth token (proof of restriction)
- invalid_token = insert(:oauth_token, scopes: ["read:something"])
-
- conn
- |> put_req_header("authorization", "Bearer #{invalid_token.token}")
- |> get("/api/v1/accounts/verify_credentials")
- |> json_response(403)
- end
-end
diff --git a/test/web/auth/pleroma_authenticator_test.exs b/test/web/auth/pleroma_authenticator_test.exs
deleted file mode 100644
index 1ba0dfecc..000000000
--- a/test/web/auth/pleroma_authenticator_test.exs
+++ /dev/null
@@ -1,48 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Web.Auth.PleromaAuthenticator
- import Pleroma.Factory
-
- setup do
- password = "testpassword"
- name = "AgentSmith"
- user = insert(:user, nickname: name, password_hash: Pbkdf2.hash_pwd_salt(password))
- {:ok, [user: user, name: name, password: password]}
- end
-
- test "get_user/authorization", %{name: name, password: password} do
- name = name <> "1"
- user = insert(:user, nickname: name, password_hash: Bcrypt.hash_pwd_salt(password))
-
- params = %{"authorization" => %{"name" => name, "password" => password}}
- res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
-
- assert {:ok, returned_user} = res
- assert returned_user.id == user.id
- assert "$pbkdf2" <> _ = returned_user.password_hash
- end
-
- test "get_user/authorization with invalid password", %{name: name} do
- params = %{"authorization" => %{"name" => name, "password" => "password"}}
- res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
-
- assert {:error, {:checkpw, false}} == res
- end
-
- test "get_user/grant_type_password", %{user: user, name: name, password: password} do
- params = %{"grant_type" => "password", "username" => name, "password" => password}
- res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
-
- assert {:ok, user} == res
- end
-
- test "error credintails" do
- res = PleromaAuthenticator.get_user(%Plug.Conn{params: %{}})
- assert {:error, :invalid_credentials} == res
- end
-end
diff --git a/test/web/auth/totp_authenticator_test.exs b/test/web/auth/totp_authenticator_test.exs
deleted file mode 100644
index 84d4cd840..000000000
--- a/test/web/auth/totp_authenticator_test.exs
+++ /dev/null
@@ -1,51 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Auth.TOTPAuthenticatorTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.MFA
- alias Pleroma.MFA.BackupCodes
- alias Pleroma.MFA.TOTP
- alias Pleroma.Web.Auth.TOTPAuthenticator
-
- import Pleroma.Factory
-
- test "verify token" do
- otp_secret = TOTP.generate_secret()
- otp_token = TOTP.generate_token(otp_secret)
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- assert TOTPAuthenticator.verify(otp_token, user) == {:ok, :pass}
- assert TOTPAuthenticator.verify(nil, user) == {:error, :invalid_token}
- assert TOTPAuthenticator.verify("", user) == {:error, :invalid_token}
- end
-
- test "checks backup codes" do
- [code | _] = backup_codes = BackupCodes.generate()
-
- hashed_codes =
- backup_codes
- |> Enum.map(&Pbkdf2.hash_pwd_salt(&1))
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- backup_codes: hashed_codes,
- totp: %MFA.Settings.TOTP{secret: "otp_secret", confirmed: true}
- }
- )
-
- assert TOTPAuthenticator.verify_recovery_code(user, code) == {:ok, :pass}
- refute TOTPAuthenticator.verify_recovery_code(code, refresh_record(user)) == {:ok, :pass}
- end
-end
diff --git a/test/web/chat_channel_test.exs b/test/web/chat_channel_test.exs
deleted file mode 100644
index f18f3a212..000000000
--- a/test/web/chat_channel_test.exs
+++ /dev/null
@@ -1,37 +0,0 @@
-defmodule Pleroma.Web.ChatChannelTest do
- use Pleroma.Web.ChannelCase
- alias Pleroma.Web.ChatChannel
- alias Pleroma.Web.UserSocket
-
- import Pleroma.Factory
-
- setup do
- user = insert(:user)
-
- {:ok, _, socket} =
- socket(UserSocket, "", %{user_name: user.nickname})
- |> subscribe_and_join(ChatChannel, "chat:public")
-
- {:ok, socket: socket}
- end
-
- test "it broadcasts a message", %{socket: socket} do
- push(socket, "new_msg", %{"text" => "why is tenshi eating a corndog so cute?"})
- assert_broadcast("new_msg", %{text: "why is tenshi eating a corndog so cute?"})
- end
-
- describe "message lengths" do
- setup do: clear_config([:instance, :chat_limit])
-
- test "it ignores messages of length zero", %{socket: socket} do
- push(socket, "new_msg", %{"text" => ""})
- refute_broadcast("new_msg", %{text: ""})
- end
-
- test "it ignores messages above a certain length", %{socket: socket} do
- Pleroma.Config.put([:instance, :chat_limit], 2)
- push(socket, "new_msg", %{"text" => "123"})
- refute_broadcast("new_msg", %{text: "123"})
- end
- end
-end
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
deleted file mode 100644
index 28bb6db30..000000000
--- a/test/web/common_api/common_api_test.exs
+++ /dev/null
@@ -1,1140 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.CommonAPITest do
- use Pleroma.DataCase
- alias Pleroma.Activity
- alias Pleroma.Chat
- alias Pleroma.Conversation.Participation
- alias Pleroma.Notification
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.ActivityPub.Visibility
- alias Pleroma.Web.AdminAPI.AccountView
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
- import Mock
-
- require Pleroma.Constants
-
- setup do: clear_config([:instance, :safe_dm_mentions])
- setup do: clear_config([:instance, :limit])
- setup do: clear_config([:instance, :max_pinned_statuses])
-
- describe "blocking" do
- setup do
- blocker = insert(:user)
- blocked = insert(:user)
- User.follow(blocker, blocked)
- User.follow(blocked, blocker)
- %{blocker: blocker, blocked: blocked}
- end
-
- test "it blocks and federates", %{blocker: blocker, blocked: blocked} do
- clear_config([:instance, :federating], true)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end do
- assert {:ok, block} = CommonAPI.block(blocker, blocked)
-
- assert block.local
- assert User.blocks?(blocker, blocked)
- refute User.following?(blocker, blocked)
- refute User.following?(blocked, blocker)
-
- assert called(Pleroma.Web.Federator.publish(block))
- end
- end
-
- test "it blocks and does not federate if outgoing blocks are disabled", %{
- blocker: blocker,
- blocked: blocked
- } do
- clear_config([:instance, :federating], true)
- clear_config([:activitypub, :outgoing_blocks], false)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end do
- assert {:ok, block} = CommonAPI.block(blocker, blocked)
-
- assert block.local
- assert User.blocks?(blocker, blocked)
- refute User.following?(blocker, blocked)
- refute User.following?(blocked, blocker)
-
- refute called(Pleroma.Web.Federator.publish(block))
- end
- end
- end
-
- describe "posting chat messages" do
- setup do: clear_config([:instance, :chat_limit])
-
- test "it posts a chat message without content but with an attachment" do
- author = insert(:user)
- recipient = 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: author.ap_id)
-
- with_mocks([
- {
- Pleroma.Web.Streamer,
- [],
- [
- stream: fn _, _ ->
- nil
- end
- ]
- },
- {
- Pleroma.Web.Push,
- [],
- [
- send: fn _ -> nil end
- ]
- }
- ]) do
- {:ok, activity} =
- CommonAPI.post_chat_message(
- author,
- recipient,
- nil,
- media_id: upload.id
- )
-
- notification =
- Notification.for_user_and_activity(recipient, activity)
- |> Repo.preload(:activity)
-
- assert called(Pleroma.Web.Push.send(notification))
- assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
- assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
-
- assert activity
- end
- end
-
- test "it adds html newlines" do
- author = insert(:user)
- recipient = insert(:user)
-
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post_chat_message(
- author,
- recipient,
- "uguu\nuguuu"
- )
-
- assert other_user.ap_id not in activity.recipients
-
- object = Object.normalize(activity, false)
-
- assert object.data["content"] == "uguu<br/>uguuu"
- end
-
- test "it linkifies" do
- author = insert(:user)
- recipient = insert(:user)
-
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post_chat_message(
- author,
- recipient,
- "https://example.org is the site of @#{other_user.nickname} #2hu"
- )
-
- assert other_user.ap_id not in activity.recipients
-
- object = Object.normalize(activity, false)
-
- assert object.data["content"] ==
- "<a href=\"https://example.org\" rel=\"ugc\">https://example.org</a> is the site of <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{
- other_user.id
- }\" href=\"#{other_user.ap_id}\" rel=\"ugc\">@<span>#{other_user.nickname}</span></a></span> <a class=\"hashtag\" data-tag=\"2hu\" href=\"http://localhost:4001/tag/2hu\">#2hu</a>"
- end
-
- test "it posts a chat message" do
- author = insert(:user)
- recipient = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post_chat_message(
- author,
- recipient,
- "a test message <script>alert('uuu')</script> :firefox:"
- )
-
- assert activity.data["type"] == "Create"
- assert activity.local
- object = Object.normalize(activity)
-
- assert object.data["type"] == "ChatMessage"
- assert object.data["to"] == [recipient.ap_id]
-
- assert object.data["content"] ==
- "a test message &lt;script&gt;alert(&#39;uuu&#39;)&lt;/script&gt; :firefox:"
-
- assert object.data["emoji"] == %{
- "firefox" => "http://localhost:4001/emoji/Firefox.gif"
- }
-
- assert Chat.get(author.id, recipient.ap_id)
- assert Chat.get(recipient.id, author.ap_id)
-
- assert :ok == Pleroma.Web.Federator.perform(:publish, activity)
- end
-
- test "it reject messages over the local limit" do
- Pleroma.Config.put([:instance, :chat_limit], 2)
-
- author = insert(:user)
- recipient = insert(:user)
-
- {:error, message} =
- CommonAPI.post_chat_message(
- author,
- recipient,
- "123"
- )
-
- assert message == :content_too_long
- end
-
- test "it reject messages via MRF" do
- clear_config([:mrf_keyword, :reject], ["GNO"])
- clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
-
- author = insert(:user)
- recipient = insert(:user)
-
- assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
- CommonAPI.post_chat_message(author, recipient, "GNO/Linux")
- end
- end
-
- describe "unblocking" do
- test "it works even without an existing block activity" do
- blocked = insert(:user)
- blocker = insert(:user)
- User.block(blocker, blocked)
-
- assert User.blocks?(blocker, blocked)
- assert {:ok, :no_activity} == CommonAPI.unblock(blocker, blocked)
- refute User.blocks?(blocker, blocked)
- end
- end
-
- describe "deletion" do
- test "it works with pruned objects" do
- user = insert(:user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
-
- clear_config([:instance, :federating], true)
-
- Object.normalize(post, false)
- |> Object.prune()
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end do
- assert {:ok, delete} = CommonAPI.delete(post.id, user)
- assert delete.local
- assert called(Pleroma.Web.Federator.publish(delete))
- end
-
- refute Activity.get_by_id(post.id)
- end
-
- test "it allows users to delete their posts" do
- user = insert(:user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
-
- clear_config([:instance, :federating], true)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end do
- assert {:ok, delete} = CommonAPI.delete(post.id, user)
- assert delete.local
- assert called(Pleroma.Web.Federator.publish(delete))
- end
-
- refute Activity.get_by_id(post.id)
- end
-
- test "it does not allow a user to delete their posts" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
-
- assert {:error, "Could not delete"} = CommonAPI.delete(post.id, other_user)
- assert Activity.get_by_id(post.id)
- end
-
- test "it allows moderators to delete other user's posts" do
- user = insert(:user)
- moderator = insert(:user, is_moderator: true)
-
- {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
-
- assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
- assert delete.local
-
- refute Activity.get_by_id(post.id)
- end
-
- test "it allows admins to delete other user's posts" do
- user = insert(:user)
- moderator = insert(:user, is_admin: true)
-
- {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
-
- assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
- assert delete.local
-
- refute Activity.get_by_id(post.id)
- end
-
- test "superusers deleting non-local posts won't federate the delete" do
- # This is the user of the ingested activity
- _user =
- insert(:user,
- local: false,
- ap_id: "http://mastodon.example.org/users/admin",
- last_refreshed_at: NaiveDateTime.utc_now()
- )
-
- moderator = insert(:user, is_admin: true)
-
- data =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Jason.decode!()
-
- {:ok, post} = Transmogrifier.handle_incoming(data)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end do
- assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
- assert delete.local
- refute called(Pleroma.Web.Federator.publish(:_))
- end
-
- refute Activity.get_by_id(post.id)
- end
- end
-
- test "favoriting race condition" do
- user = insert(:user)
- users_serial = insert_list(10, :user)
- users = insert_list(10, :user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "."})
-
- users_serial
- |> Enum.map(fn user ->
- CommonAPI.favorite(user, activity.id)
- end)
-
- object = Object.get_by_ap_id(activity.data["object"])
- assert object.data["like_count"] == 10
-
- users
- |> Enum.map(fn user ->
- Task.async(fn ->
- CommonAPI.favorite(user, activity.id)
- end)
- end)
- |> Enum.map(&Task.await/1)
-
- object = Object.get_by_ap_id(activity.data["object"])
- assert object.data["like_count"] == 20
- end
-
- test "repeating race condition" do
- user = insert(:user)
- users_serial = insert_list(10, :user)
- users = insert_list(10, :user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "."})
-
- users_serial
- |> Enum.map(fn user ->
- CommonAPI.repeat(activity.id, user)
- end)
-
- object = Object.get_by_ap_id(activity.data["object"])
- assert object.data["announcement_count"] == 10
-
- users
- |> Enum.map(fn user ->
- Task.async(fn ->
- CommonAPI.repeat(activity.id, user)
- end)
- end)
- |> Enum.map(&Task.await/1)
-
- object = Object.get_by_ap_id(activity.data["object"])
- assert object.data["announcement_count"] == 20
- end
-
- test "when replying to a conversation / participation, it will set the correct context id even if no explicit reply_to is given" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
-
- [participation] = Participation.for_user(user)
-
- {:ok, convo_reply} =
- CommonAPI.post(user, %{status: ".", in_reply_to_conversation_id: participation.id})
-
- assert Visibility.is_direct?(convo_reply)
-
- assert activity.data["context"] == convo_reply.data["context"]
- end
-
- test "when replying to a conversation / participation, it only mentions the recipients explicitly declared in the participation" do
- har = insert(:user)
- jafnhar = insert(:user)
- tridi = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(har, %{
- status: "@#{jafnhar.nickname} hey",
- visibility: "direct"
- })
-
- assert har.ap_id in activity.recipients
- assert jafnhar.ap_id in activity.recipients
-
- [participation] = Participation.for_user(har)
-
- {:ok, activity} =
- CommonAPI.post(har, %{
- status: "I don't really like @#{tridi.nickname}",
- visibility: "direct",
- in_reply_to_status_id: activity.id,
- in_reply_to_conversation_id: participation.id
- })
-
- assert har.ap_id in activity.recipients
- assert jafnhar.ap_id in activity.recipients
- refute tridi.ap_id in activity.recipients
- end
-
- test "with the safe_dm_mention option set, it does not mention people beyond the initial tags" do
- har = insert(:user)
- jafnhar = insert(:user)
- tridi = insert(:user)
-
- Pleroma.Config.put([:instance, :safe_dm_mentions], true)
-
- {:ok, activity} =
- CommonAPI.post(har, %{
- status: "@#{jafnhar.nickname} hey, i never want to see @#{tridi.nickname} again",
- visibility: "direct"
- })
-
- refute tridi.ap_id in activity.recipients
- assert jafnhar.ap_id in activity.recipients
- end
-
- test "it de-duplicates tags" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU"})
-
- object = Object.normalize(activity)
-
- assert object.data["tag"] == ["2hu"]
- end
-
- test "it adds emoji in the object" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"})
-
- assert Object.normalize(activity).data["emoji"]["firefox"]
- end
-
- describe "posting" do
- test "deactivated users can't post" do
- user = insert(:user, deactivated: true)
- assert {:error, _} = CommonAPI.post(user, %{status: "ye"})
- end
-
- test "it supports explicit addressing" do
- user = insert(:user)
- user_two = insert(:user)
- user_three = insert(:user)
- user_four = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status:
- "Hey, I think @#{user_three.nickname} is ugly. @#{user_four.nickname} is alright though.",
- to: [user_two.nickname, user_four.nickname, "nonexistent"]
- })
-
- assert user.ap_id in activity.recipients
- assert user_two.ap_id in activity.recipients
- assert user_four.ap_id in activity.recipients
- refute user_three.ap_id in activity.recipients
- end
-
- test "it filters out obviously bad tags when accepting a post as HTML" do
- user = insert(:user)
-
- post = "<p><b>2hu</b></p><script>alert('xss')</script>"
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: post,
- content_type: "text/html"
- })
-
- object = Object.normalize(activity)
-
- assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
- assert object.data["source"] == post
- end
-
- test "it filters out obviously bad tags when accepting a post as Markdown" do
- user = insert(:user)
-
- post = "<p><b>2hu</b></p><script>alert('xss')</script>"
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: post,
- content_type: "text/markdown"
- })
-
- object = Object.normalize(activity)
-
- assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
- assert object.data["source"] == post
- end
-
- test "it does not allow replies to direct messages that are not direct messages themselves" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "suya..", visibility: "direct"})
-
- assert {:ok, _} =
- CommonAPI.post(user, %{
- status: "suya..",
- visibility: "direct",
- in_reply_to_status_id: activity.id
- })
-
- Enum.each(["public", "private", "unlisted"], fn visibility ->
- assert {:error, "The message visibility must be direct"} =
- CommonAPI.post(user, %{
- status: "suya..",
- visibility: visibility,
- in_reply_to_status_id: activity.id
- })
- end)
- end
-
- test "replying with a direct message will NOT auto-add the author of the reply to the recipient list" do
- user = insert(:user)
- other_user = insert(:user)
- third_user = insert(:user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "I'm stupid"})
-
- {:ok, open_answer} =
- CommonAPI.post(other_user, %{status: "No ur smart", in_reply_to_status_id: post.id})
-
- # The OP is implicitly added
- assert user.ap_id in open_answer.recipients
-
- {:ok, secret_answer} =
- CommonAPI.post(other_user, %{
- status: "lol, that guy really is stupid, right, @#{third_user.nickname}?",
- in_reply_to_status_id: post.id,
- visibility: "direct"
- })
-
- assert third_user.ap_id in secret_answer.recipients
-
- # The OP is not added
- refute user.ap_id in secret_answer.recipients
- end
-
- test "it allows to address a list" do
- user = insert(:user)
- {:ok, list} = Pleroma.List.create("foo", user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
-
- assert activity.data["bcc"] == [list.ap_id]
- assert activity.recipients == [list.ap_id, user.ap_id]
- assert activity.data["listMessage"] == list.ap_id
- end
-
- test "it returns error when status is empty and no attachments" do
- user = insert(:user)
-
- assert {:error, "Cannot post an empty status without attachments"} =
- CommonAPI.post(user, %{status: ""})
- end
-
- test "it validates character limits are correctly enforced" do
- Pleroma.Config.put([:instance, :limit], 5)
-
- user = insert(:user)
-
- assert {:error, "The status is over the character limit"} =
- CommonAPI.post(user, %{status: "foobar"})
-
- assert {:ok, activity} = CommonAPI.post(user, %{status: "12345"})
- end
-
- test "it can handle activities that expire" do
- user = insert(:user)
-
- expires_at =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.truncate(:second)
- |> NaiveDateTime.add(1_000_000, :second)
-
- assert {:ok, activity} = CommonAPI.post(user, %{status: "chai", expires_in: 1_000_000})
-
- assert expiration = Pleroma.ActivityExpiration.get_by_activity_id(activity.id)
- assert expiration.scheduled_at == expires_at
- end
- end
-
- describe "reactions" do
- test "reacting to a status with an emoji" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
-
- {:ok, reaction} = CommonAPI.react_with_emoji(activity.id, user, "👍")
-
- assert reaction.data["actor"] == user.ap_id
- assert reaction.data["content"] == "👍"
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
-
- {:error, _} = CommonAPI.react_with_emoji(activity.id, user, ".")
- end
-
- test "unreacting to a status with an emoji" do
- user = insert(:user)
- other_user = insert(:user)
-
- clear_config([:instance, :federating], true)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _ -> nil end do
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
- {:ok, reaction} = CommonAPI.react_with_emoji(activity.id, user, "👍")
-
- {:ok, unreaction} = CommonAPI.unreact_with_emoji(activity.id, user, "👍")
-
- assert unreaction.data["type"] == "Undo"
- assert unreaction.data["object"] == reaction.data["id"]
- assert unreaction.local
-
- # On federation, it contains the undone (and deleted) object
- unreaction_with_object = %{
- unreaction
- | data: Map.put(unreaction.data, "object", reaction.data)
- }
-
- assert called(Pleroma.Web.Federator.publish(unreaction_with_object))
- end
- end
-
- test "repeating a status" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
-
- {:ok, %Activity{} = announce_activity} = CommonAPI.repeat(activity.id, user)
- assert Visibility.is_public?(announce_activity)
- end
-
- test "can't repeat a repeat" do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
-
- {:ok, %Activity{} = announce} = CommonAPI.repeat(activity.id, other_user)
-
- refute match?({:ok, %Activity{}}, CommonAPI.repeat(announce.id, user))
- end
-
- test "repeating a status privately" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
-
- {:ok, %Activity{} = announce_activity} =
- CommonAPI.repeat(activity.id, user, %{visibility: "private"})
-
- assert Visibility.is_private?(announce_activity)
- refute Visibility.visible_for_user?(announce_activity, nil)
- end
-
- test "favoriting a status" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, post_activity} = CommonAPI.post(other_user, %{status: "cofe"})
-
- {:ok, %Activity{data: data}} = CommonAPI.favorite(user, post_activity.id)
- assert data["type"] == "Like"
- assert data["actor"] == user.ap_id
- assert data["object"] == post_activity.data["object"]
- end
-
- test "retweeting a status twice returns the status" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
- {:ok, %Activity{} = announce} = CommonAPI.repeat(activity.id, user)
- {:ok, ^announce} = CommonAPI.repeat(activity.id, user)
- end
-
- test "favoriting a status twice returns ok, but without the like activity" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
- {:ok, %Activity{}} = CommonAPI.favorite(user, activity.id)
- assert {:ok, :already_liked} = CommonAPI.favorite(user, activity.id)
- end
- end
-
- describe "pinned statuses" do
- setup do
- Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
-
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "HI!!!"})
-
- [user: user, activity: activity]
- end
-
- test "pin status", %{user: user, activity: activity} do
- assert {:ok, ^activity} = CommonAPI.pin(activity.id, user)
-
- id = activity.id
- user = refresh_record(user)
-
- assert %User{pinned_activities: [^id]} = user
- end
-
- test "pin poll", %{user: user} do
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "How is fediverse today?",
- poll: %{options: ["Absolutely outstanding", "Not good"], expires_in: 20}
- })
-
- assert {:ok, ^activity} = CommonAPI.pin(activity.id, user)
-
- id = activity.id
- user = refresh_record(user)
-
- assert %User{pinned_activities: [^id]} = user
- end
-
- test "unlisted statuses can be pinned", %{user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "HI!!!", visibility: "unlisted"})
- assert {:ok, ^activity} = CommonAPI.pin(activity.id, user)
- end
-
- test "only self-authored can be pinned", %{activity: activity} do
- user = insert(:user)
-
- assert {:error, "Could not pin"} = CommonAPI.pin(activity.id, user)
- end
-
- test "max pinned statuses", %{user: user, activity: activity_one} do
- {:ok, activity_two} = CommonAPI.post(user, %{status: "HI!!!"})
-
- assert {:ok, ^activity_one} = CommonAPI.pin(activity_one.id, user)
-
- user = refresh_record(user)
-
- assert {:error, "You have already pinned the maximum number of statuses"} =
- CommonAPI.pin(activity_two.id, user)
- end
-
- test "unpin status", %{user: user, activity: activity} do
- {:ok, activity} = CommonAPI.pin(activity.id, user)
-
- user = refresh_record(user)
-
- id = activity.id
-
- assert match?({:ok, %{id: ^id}}, CommonAPI.unpin(activity.id, user))
-
- user = refresh_record(user)
-
- assert %User{pinned_activities: []} = user
- end
-
- test "should unpin when deleting a status", %{user: user, activity: activity} do
- {:ok, activity} = CommonAPI.pin(activity.id, user)
-
- user = refresh_record(user)
-
- assert {:ok, _} = CommonAPI.delete(activity.id, user)
-
- user = refresh_record(user)
-
- assert %User{pinned_activities: []} = user
- end
- end
-
- describe "mute tests" do
- setup do
- user = insert(:user)
-
- activity = insert(:note_activity)
-
- [user: user, activity: activity]
- end
-
- test "add mute", %{user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
- assert CommonAPI.thread_muted?(user, activity)
- end
-
- test "remove mute", %{user: user, activity: activity} do
- CommonAPI.add_mute(user, activity)
- {:ok, _} = CommonAPI.remove_mute(user, activity)
- refute CommonAPI.thread_muted?(user, activity)
- end
-
- test "check that mutes can't be duplicate", %{user: user, activity: activity} do
- CommonAPI.add_mute(user, activity)
- {:error, _} = CommonAPI.add_mute(user, activity)
- end
- end
-
- describe "reports" do
- test "creates a report" do
- reporter = insert(:user)
- target_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"})
-
- reporter_ap_id = reporter.ap_id
- target_ap_id = target_user.ap_id
- activity_ap_id = activity.data["id"]
- comment = "foobar"
-
- report_data = %{
- account_id: target_user.id,
- comment: comment,
- status_ids: [activity.id]
- }
-
- note_obj = %{
- "type" => "Note",
- "id" => activity_ap_id,
- "content" => "foobar",
- "published" => activity.object.data["published"],
- "actor" => AccountView.render("show.json", %{user: target_user})
- }
-
- assert {:ok, flag_activity} = CommonAPI.report(reporter, report_data)
-
- assert %Activity{
- actor: ^reporter_ap_id,
- data: %{
- "type" => "Flag",
- "content" => ^comment,
- "object" => [^target_ap_id, ^note_obj],
- "state" => "open"
- }
- } = flag_activity
- end
-
- test "updates report state" do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %Activity{id: report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- {:ok, report} = CommonAPI.update_report_state(report_id, "resolved")
-
- assert report.data["state"] == "resolved"
-
- [reported_user, activity_id] = report.data["object"]
-
- assert reported_user == target_user.ap_id
- assert activity_id == activity.data["id"]
- end
-
- test "does not update report state when state is unsupported" do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %Activity{id: report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- assert CommonAPI.update_report_state(report_id, "test") == {:error, "Unsupported state"}
- end
-
- test "updates state of multiple reports" do
- [reporter, target_user] = insert_pair(:user)
- activity = insert(:note_activity, user: target_user)
-
- {:ok, %Activity{id: first_report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel offended",
- status_ids: [activity.id]
- })
-
- {:ok, %Activity{id: second_report_id}} =
- CommonAPI.report(reporter, %{
- account_id: target_user.id,
- comment: "I feel very offended!",
- status_ids: [activity.id]
- })
-
- {:ok, report_ids} =
- CommonAPI.update_report_state([first_report_id, second_report_id], "resolved")
-
- first_report = Activity.get_by_id(first_report_id)
- second_report = Activity.get_by_id(second_report_id)
-
- assert report_ids -- [first_report_id, second_report_id] == []
- assert first_report.data["state"] == "resolved"
- assert second_report.data["state"] == "resolved"
- end
- end
-
- describe "reblog muting" do
- setup do
- muter = insert(:user)
-
- muted = insert(:user)
-
- [muter: muter, muted: muted]
- end
-
- test "add a reblog mute", %{muter: muter, muted: muted} do
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muter, muted)
-
- assert User.showing_reblogs?(muter, muted) == false
- end
-
- test "remove a reblog mute", %{muter: muter, muted: muted} do
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muter, muted)
- {:ok, _reblog_mute} = CommonAPI.show_reblogs(muter, muted)
-
- assert User.showing_reblogs?(muter, muted) == true
- end
- end
-
- describe "follow/2" do
- test "directly follows a non-locked local user" do
- [follower, followed] = insert_pair(:user)
- {:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
-
- assert User.following?(follower, followed)
- end
- end
-
- describe "unfollow/2" do
- test "also unsubscribes a user" do
- [follower, followed] = insert_pair(:user)
- {:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
- {:ok, _subscription} = User.subscribe(follower, followed)
-
- assert User.subscribed_to?(follower, followed)
-
- {:ok, follower} = CommonAPI.unfollow(follower, followed)
-
- refute User.subscribed_to?(follower, followed)
- end
-
- test "cancels a pending follow for a local user" do
- follower = insert(:user)
- followed = insert(:user, locked: true)
-
- assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
- CommonAPI.follow(follower, followed)
-
- assert User.get_follow_state(follower, followed) == :follow_pending
- assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
- assert User.get_follow_state(follower, followed) == nil
-
- assert %{id: ^activity_id, data: %{"state" => "cancelled"}} =
- Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(follower, followed)
-
- assert %{
- data: %{
- "type" => "Undo",
- "object" => %{"type" => "Follow", "state" => "cancelled"}
- }
- } = Pleroma.Web.ActivityPub.Utils.fetch_latest_undo(follower)
- end
-
- test "cancels a pending follow for a remote user" do
- follower = insert(:user)
- followed = insert(:user, locked: true, local: false, ap_enabled: true)
-
- assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
- CommonAPI.follow(follower, followed)
-
- assert User.get_follow_state(follower, followed) == :follow_pending
- assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
- assert User.get_follow_state(follower, followed) == nil
-
- assert %{id: ^activity_id, data: %{"state" => "cancelled"}} =
- Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(follower, followed)
-
- assert %{
- data: %{
- "type" => "Undo",
- "object" => %{"type" => "Follow", "state" => "cancelled"}
- }
- } = Pleroma.Web.ActivityPub.Utils.fetch_latest_undo(follower)
- end
- end
-
- describe "accept_follow_request/2" do
- test "after acceptance, it sets all existing pending follow request states to 'accept'" do
- user = insert(:user, locked: true)
- follower = insert(:user)
- follower_two = insert(:user)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_three} = CommonAPI.follow(follower_two, user)
-
- assert follow_activity.data["state"] == "pending"
- assert follow_activity_two.data["state"] == "pending"
- assert follow_activity_three.data["state"] == "pending"
-
- {:ok, _follower} = CommonAPI.accept_follow_request(follower, user)
-
- assert Repo.get(Activity, follow_activity.id).data["state"] == "accept"
- assert Repo.get(Activity, follow_activity_two.id).data["state"] == "accept"
- assert Repo.get(Activity, follow_activity_three.id).data["state"] == "pending"
- end
-
- test "after rejection, it sets all existing pending follow request states to 'reject'" do
- user = insert(:user, locked: true)
- follower = insert(:user)
- follower_two = insert(:user)
-
- {:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
- {:ok, _, _, follow_activity_three} = CommonAPI.follow(follower_two, user)
-
- assert follow_activity.data["state"] == "pending"
- assert follow_activity_two.data["state"] == "pending"
- assert follow_activity_three.data["state"] == "pending"
-
- {:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
-
- assert Repo.get(Activity, follow_activity.id).data["state"] == "reject"
- assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject"
- assert Repo.get(Activity, follow_activity_three.id).data["state"] == "pending"
- end
-
- test "doesn't create a following relationship if the corresponding follow request doesn't exist" do
- user = insert(:user, locked: true)
- not_follower = insert(:user)
- CommonAPI.accept_follow_request(not_follower, user)
-
- assert Pleroma.FollowingRelationship.following?(not_follower, user) == false
- end
- end
-
- describe "vote/3" do
- test "does not allow to vote twice" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Am I cute?",
- poll: %{options: ["Yes", "No"], expires_in: 20}
- })
-
- object = Object.normalize(activity)
-
- {:ok, _, object} = CommonAPI.vote(other_user, object, [0])
-
- 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
deleted file mode 100644
index e67c10b93..000000000
--- a/test/web/common_api/common_api_utils_test.exs
+++ /dev/null
@@ -1,593 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.CommonAPI.UtilsTest do
- alias Pleroma.Builders.UserBuilder
- alias Pleroma.Object
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.CommonAPI.Utils
- use Pleroma.DataCase
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
-
- @public_address "https://www.w3.org/ns/activitystreams#Public"
-
- describe "add_attachments/2" do
- setup do
- name =
- "Sakura Mana – Turned on by a Senior OL with a Temptating Tight Skirt-s Full Hipline and Panty Shot- Beautiful Thick Thighs- and Erotic Ass- -2015- -- Oppaitime 8-28-2017 6-50-33 PM.png"
-
- attachment = %{
- "url" => [%{"href" => URI.encode(name)}]
- }
-
- %{name: name, attachment: attachment}
- end
-
- test "it adds attachment links to a given text and attachment set", %{
- name: name,
- attachment: attachment
- } do
- len = 10
- clear_config([Pleroma.Upload, :filename_display_max_length], len)
-
- expected =
- "<br><a href=\"#{URI.encode(name)}\" class='attachment'>#{String.slice(name, 0..len)}…</a>"
-
- assert Utils.add_attachments("", [attachment]) == expected
- end
-
- test "doesn't truncate file name if config for truncate is set to 0", %{
- name: name,
- attachment: attachment
- } do
- clear_config([Pleroma.Upload, :filename_display_max_length], 0)
-
- expected = "<br><a href=\"#{URI.encode(name)}\" class='attachment'>#{name}</a>"
-
- assert Utils.add_attachments("", [attachment]) == expected
- end
- end
-
- describe "it confirms the password given is the current users password" do
- test "incorrect password given" do
- {:ok, user} = UserBuilder.insert()
-
- assert Utils.confirm_current_password(user, "") == {:error, "Invalid password."}
- end
-
- test "correct password given" do
- {:ok, user} = UserBuilder.insert()
- assert Utils.confirm_current_password(user, "test") == {:ok, user}
- end
- end
-
- describe "format_input/3" do
- test "works for bare text/plain" do
- text = "hello world!"
- expected = "hello world!"
-
- {output, [], []} = Utils.format_input(text, "text/plain")
-
- assert output == expected
-
- text = "hello world!\n\nsecond paragraph!"
- expected = "hello world!<br><br>second paragraph!"
-
- {output, [], []} = Utils.format_input(text, "text/plain")
-
- assert output == expected
- end
-
- test "works for bare text/html" do
- text = "<p>hello world!</p>"
- expected = "<p>hello world!</p>"
-
- {output, [], []} = Utils.format_input(text, "text/html")
-
- assert output == expected
-
- text = "<p>hello world!</p><br/>\n<p>second paragraph</p>"
- expected = "<p>hello world!</p><br/>\n<p>second paragraph</p>"
-
- {output, [], []} = Utils.format_input(text, "text/html")
-
- assert output == expected
- end
-
- test "works for bare text/markdown" do
- text = "**hello world**"
- expected = "<p><strong>hello world</strong></p>"
-
- {output, [], []} = Utils.format_input(text, "text/markdown")
-
- assert output == expected
-
- text = "**hello world**\n\n*another paragraph*"
- expected = "<p><strong>hello world</strong></p><p><em>another paragraph</em></p>"
-
- {output, [], []} = Utils.format_input(text, "text/markdown")
-
- assert output == expected
-
- text = """
- > cool quote
-
- by someone
- """
-
- expected = "<blockquote><p>cool quote</p></blockquote><p>by someone</p>"
-
- {output, [], []} = Utils.format_input(text, "text/markdown")
-
- assert output == expected
- end
-
- test "works for bare text/bbcode" do
- text = "[b]hello world[/b]"
- expected = "<strong>hello world</strong>"
-
- {output, [], []} = Utils.format_input(text, "text/bbcode")
-
- assert output == expected
-
- text = "[b]hello world![/b]\n\nsecond paragraph!"
- expected = "<strong>hello world!</strong><br><br>second paragraph!"
-
- {output, [], []} = Utils.format_input(text, "text/bbcode")
-
- assert output == expected
-
- text = "[b]hello world![/b]\n\n<strong>second paragraph!</strong>"
-
- expected =
- "<strong>hello world!</strong><br><br>&lt;strong&gt;second paragraph!&lt;/strong&gt;"
-
- {output, [], []} = Utils.format_input(text, "text/bbcode")
-
- assert output == expected
- end
-
- test "works for text/markdown with mentions" do
- {:ok, user} =
- UserBuilder.insert(%{nickname: "user__test", ap_id: "http://foo.com/user__test"})
-
- text = "**hello world**\n\n*another @user__test and @user__test google.com paragraph*"
-
- {output, _, _} = Utils.format_input(text, "text/markdown")
-
- assert output ==
- ~s(<p><strong>hello world</strong></p><p><em>another <span class="h-card"><a class="u-url mention" data-user="#{
- user.id
- }" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> and <span class="h-card"><a class="u-url mention" data-user="#{
- user.id
- }" 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>)
- end
- end
-
- describe "context_to_conversation_id" do
- test "creates a mapping object" do
- conversation_id = Utils.context_to_conversation_id("random context")
- object = Object.get_by_ap_id("random context")
-
- assert conversation_id == object.id
- end
-
- test "returns an existing mapping for an existing object" do
- {:ok, object} = Object.context_mapping("random context") |> Repo.insert()
- conversation_id = Utils.context_to_conversation_id("random context")
-
- assert conversation_id == object.id
- end
- end
-
- describe "formats date to asctime" do
- test "when date is in ISO 8601 format" do
- date = DateTime.utc_now() |> DateTime.to_iso8601()
-
- expected =
- date
- |> DateTime.from_iso8601()
- |> elem(1)
- |> Calendar.Strftime.strftime!("%a %b %d %H:%M:%S %z %Y")
-
- assert Utils.date_to_asctime(date) == expected
- end
-
- test "when date is a binary in wrong format" do
- date = DateTime.utc_now()
-
- expected = ""
-
- assert capture_log(fn ->
- assert Utils.date_to_asctime(date) == expected
- end) =~ "[warn] Date #{date} in wrong format, must be ISO 8601"
- end
-
- test "when date is a Unix timestamp" do
- date = DateTime.utc_now() |> DateTime.to_unix()
-
- expected = ""
-
- assert capture_log(fn ->
- assert Utils.date_to_asctime(date) == expected
- end) =~ "[warn] Date #{date} in wrong format, must be ISO 8601"
- end
-
- test "when date is nil" do
- expected = ""
-
- assert capture_log(fn ->
- assert Utils.date_to_asctime(nil) == expected
- end) =~ "[warn] Date in wrong format, must be ISO 8601"
- end
-
- test "when date is a random string" do
- assert capture_log(fn ->
- assert Utils.date_to_asctime("foo") == ""
- end) =~ "[warn] Date foo in wrong format, must be ISO 8601"
- end
- end
-
- describe "get_to_and_cc" do
- test "for public posts, not a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "public", nil)
-
- assert length(to) == 2
- assert length(cc) == 1
-
- assert @public_address in to
- assert mentioned_user.ap_id in to
- assert user.follower_address in cc
- end
-
- test "for public posts, a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- third_user = insert(:user)
- {:ok, activity} = CommonAPI.post(third_user, %{status: "uguu"})
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "public", nil)
-
- assert length(to) == 3
- assert length(cc) == 1
-
- assert @public_address in to
- assert mentioned_user.ap_id in to
- assert third_user.ap_id in to
- assert user.follower_address in cc
- end
-
- test "for unlisted posts, not a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "unlisted", nil)
-
- assert length(to) == 2
- assert length(cc) == 1
-
- assert @public_address in cc
- assert mentioned_user.ap_id in to
- assert user.follower_address in to
- end
-
- test "for unlisted posts, a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- third_user = insert(:user)
- {:ok, activity} = CommonAPI.post(third_user, %{status: "uguu"})
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "unlisted", nil)
-
- assert length(to) == 3
- assert length(cc) == 1
-
- assert @public_address in cc
- assert mentioned_user.ap_id in to
- assert third_user.ap_id in to
- assert user.follower_address in to
- end
-
- test "for private posts, not a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private", nil)
- assert length(to) == 2
- assert Enum.empty?(cc)
-
- assert mentioned_user.ap_id in to
- assert user.follower_address in to
- end
-
- test "for private posts, a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- third_user = insert(:user)
- {:ok, activity} = CommonAPI.post(third_user, %{status: "uguu"})
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil)
-
- assert length(to) == 2
- assert Enum.empty?(cc)
-
- assert mentioned_user.ap_id in to
- assert user.follower_address in to
- end
-
- test "for direct posts, not a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct", nil)
-
- assert length(to) == 1
- assert Enum.empty?(cc)
-
- assert mentioned_user.ap_id in to
- end
-
- test "for direct posts, a reply" do
- user = insert(:user)
- mentioned_user = insert(:user)
- third_user = insert(:user)
- {:ok, activity} = CommonAPI.post(third_user, %{status: "uguu"})
- mentions = [mentioned_user.ap_id]
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil)
-
- assert length(to) == 1
- assert Enum.empty?(cc)
-
- assert mentioned_user.ap_id in to
-
- {:ok, direct_activity} = CommonAPI.post(third_user, %{status: "uguu", visibility: "direct"})
-
- {to, cc} = Utils.get_to_and_cc(user, mentions, direct_activity, "direct", nil)
-
- assert length(to) == 2
- assert Enum.empty?(cc)
-
- assert mentioned_user.ap_id in to
- assert third_user.ap_id in to
- end
- end
-
- describe "to_master_date/1" do
- test "removes microseconds from date (NaiveDateTime)" do
- assert Utils.to_masto_date(~N[2015-01-23 23:50:07.123]) == "2015-01-23T23:50:07.000Z"
- end
-
- test "removes microseconds from date (String)" do
- assert Utils.to_masto_date("2015-01-23T23:50:07.123Z") == "2015-01-23T23:50:07.000Z"
- end
-
- test "returns empty string when date invalid" do
- assert Utils.to_masto_date("2015-01?23T23:50:07.123Z") == ""
- end
- end
-
- describe "conversation_id_to_context/1" do
- test "returns id" do
- object = insert(:note)
- assert Utils.conversation_id_to_context(object.id) == object.data["id"]
- end
-
- test "returns error if object not found" do
- assert Utils.conversation_id_to_context("123") == {:error, "No such conversation"}
- end
- end
-
- describe "maybe_notify_mentioned_recipients/2" do
- test "returns recipients when activity is not `Create`" do
- activity = insert(:like_activity)
- assert Utils.maybe_notify_mentioned_recipients(["test"], activity) == ["test"]
- end
-
- test "returns recipients from tag" do
- user = insert(:user)
-
- object =
- insert(:note,
- user: user,
- data: %{
- "tag" => [
- %{"type" => "Hashtag"},
- "",
- %{"type" => "Mention", "href" => "https://testing.pleroma.lol/users/lain"},
- %{"type" => "Mention", "href" => "https://shitposter.club/user/5381"},
- %{"type" => "Mention", "href" => "https://shitposter.club/user/5381"}
- ]
- }
- )
-
- activity = insert(:note_activity, user: user, note: object)
-
- assert Utils.maybe_notify_mentioned_recipients(["test"], activity) == [
- "test",
- "https://testing.pleroma.lol/users/lain",
- "https://shitposter.club/user/5381"
- ]
- end
-
- test "returns recipients when object is map" do
- user = insert(:user)
- object = insert(:note, user: user)
-
- activity =
- insert(:note_activity,
- user: user,
- note: object,
- data_attrs: %{
- "object" => %{
- "tag" => [
- %{"type" => "Hashtag"},
- "",
- %{"type" => "Mention", "href" => "https://testing.pleroma.lol/users/lain"},
- %{"type" => "Mention", "href" => "https://shitposter.club/user/5381"},
- %{"type" => "Mention", "href" => "https://shitposter.club/user/5381"}
- ]
- }
- }
- )
-
- Pleroma.Repo.delete(object)
-
- assert Utils.maybe_notify_mentioned_recipients(["test"], activity) == [
- "test",
- "https://testing.pleroma.lol/users/lain",
- "https://shitposter.club/user/5381"
- ]
- end
-
- test "returns recipients when object not found" do
- user = insert(:user)
- object = insert(:note, user: user)
-
- activity = insert(:note_activity, user: user, note: object)
- Pleroma.Repo.delete(object)
-
- obj_url = activity.data["object"]
-
- Tesla.Mock.mock(fn
- %{method: :get, url: ^obj_url} ->
- %Tesla.Env{status: 404, body: ""}
- end)
-
- assert Utils.maybe_notify_mentioned_recipients(["test-test"], activity) == [
- "test-test"
- ]
- end
- end
-
- describe "attachments_from_ids_descs/2" do
- test "returns [] when attachment ids is empty" do
- assert Utils.attachments_from_ids_descs([], "{}") == []
- end
-
- test "returns list attachments with desc" do
- object = insert(:note)
- desc = Jason.encode!(%{object.id => "test-desc"})
-
- assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc) == [
- Map.merge(object.data, %{"name" => "test-desc"})
- ]
- end
- end
-
- describe "attachments_from_ids/1" do
- test "returns attachments with descs" do
- object = insert(:note)
- desc = Jason.encode!(%{object.id => "test-desc"})
-
- assert Utils.attachments_from_ids(%{
- media_ids: ["#{object.id}"],
- descriptions: desc
- }) == [
- Map.merge(object.data, %{"name" => "test-desc"})
- ]
- end
-
- test "returns attachments without descs" do
- object = insert(:note)
- assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}) == [object.data]
- end
-
- test "returns [] when not pass media_ids" do
- assert Utils.attachments_from_ids(%{}) == []
- end
- end
-
- describe "maybe_add_list_data/3" do
- test "adds list params when found user list" do
- user = insert(:user)
- {:ok, %Pleroma.List{} = list} = Pleroma.List.create("title", user)
-
- assert Utils.maybe_add_list_data(%{additional: %{}, object: %{}}, user, {:list, list.id}) ==
- %{
- additional: %{"bcc" => [list.ap_id], "listMessage" => list.ap_id},
- object: %{"listMessage" => list.ap_id}
- }
- end
-
- test "returns original params when list not found" do
- user = insert(:user)
- {:ok, %Pleroma.List{} = list} = Pleroma.List.create("title", insert(:user))
-
- assert Utils.maybe_add_list_data(%{additional: %{}, object: %{}}, user, {:list, list.id}) ==
- %{additional: %{}, object: %{}}
- end
- end
-
- describe "make_note_data/11" do
- test "returns note data" do
- user = insert(:user)
- note = insert(:note)
- user2 = insert(:user)
- user3 = insert(:user)
-
- assert Utils.make_note_data(
- user.ap_id,
- [user2.ap_id],
- "2hu",
- "<h1>This is :moominmamma: note</h1>",
- [],
- note.id,
- [name: "jimm"],
- "test summary",
- [user3.ap_id],
- false,
- %{"custom_tag" => "test"}
- ) == %{
- "actor" => user.ap_id,
- "attachment" => [],
- "cc" => [user3.ap_id],
- "content" => "<h1>This is :moominmamma: note</h1>",
- "context" => "2hu",
- "sensitive" => false,
- "summary" => "test summary",
- "tag" => ["jimm"],
- "to" => [user2.ap_id],
- "type" => "Note",
- "custom_tag" => "test"
- }
- end
- end
-
- describe "maybe_add_attachments/3" do
- test "returns parsed results when attachment_links is false" do
- assert Utils.maybe_add_attachments(
- {"test", [], ["tags"]},
- [],
- false
- ) == {"test", [], ["tags"]}
- end
-
- test "adds attachments to parsed results" do
- attachment = %{"url" => [%{"href" => "SakuraPM.png"}]}
-
- assert Utils.maybe_add_attachments(
- {"test", [], ["tags"]},
- [attachment],
- true
- ) == {
- "test<br><a href=\"SakuraPM.png\" class='attachment'>SakuraPM.png</a>",
- [],
- ["tags"]
- }
- end
- end
-end
diff --git a/test/web/fallback_test.exs b/test/web/fallback_test.exs
deleted file mode 100644
index a65865860..000000000
--- a/test/web/fallback_test.exs
+++ /dev/null
@@ -1,80 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.FallbackTest do
- use Pleroma.Web.ConnCase
- import Pleroma.Factory
-
- describe "neither preloaded data nor metadata attached to" do
- test "GET /registration/:token", %{conn: conn} do
- response = get(conn, "/registration/foo")
-
- assert html_response(response, 200) =~ "<!--server-generated-meta-->"
- end
-
- test "GET /*path", %{conn: conn} do
- assert conn
- |> get("/foo")
- |> html_response(200) =~ "<!--server-generated-meta-->"
- end
- end
-
- describe "preloaded data and metadata attached to" do
- test "GET /:maybe_nickname_or_id", %{conn: conn} do
- user = insert(:user)
- user_missing = get(conn, "/foo")
- user_present = get(conn, "/#{user.nickname}")
-
- assert(html_response(user_missing, 200) =~ "<!--server-generated-meta-->")
- refute html_response(user_present, 200) =~ "<!--server-generated-meta-->"
- assert html_response(user_present, 200) =~ "initial-results"
- end
-
- test "GET /*path", %{conn: conn} do
- assert conn
- |> get("/foo")
- |> html_response(200) =~ "<!--server-generated-meta-->"
-
- refute conn
- |> get("/foo/bar")
- |> html_response(200) =~ "<!--server-generated-meta-->"
- end
- end
-
- describe "preloaded data is attached to" do
- test "GET /main/public", %{conn: conn} do
- public_page = get(conn, "/main/public")
-
- refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
- assert html_response(public_page, 200) =~ "initial-results"
- end
-
- test "GET /main/all", %{conn: conn} do
- public_page = get(conn, "/main/all")
-
- refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
- assert html_response(public_page, 200) =~ "initial-results"
- end
- end
-
- test "GET /api*path", %{conn: conn} do
- assert conn
- |> get("/api/foo")
- |> json_response(404) == %{"error" => "Not implemented"}
- end
-
- test "GET /pleroma/admin -> /pleroma/admin/", %{conn: conn} do
- assert redirected_to(get(conn, "/pleroma/admin")) =~ "/pleroma/admin/"
- end
-
- test "OPTIONS /*path", %{conn: conn} do
- assert conn
- |> options("/foo")
- |> response(204) == ""
-
- assert conn
- |> options("/foo/bar")
- |> response(204) == ""
- end
-end
diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs
deleted file mode 100644
index 592fdccd1..000000000
--- a/test/web/federator_test.exs
+++ /dev/null
@@ -1,173 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.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
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
-
- :ok
- end
-
- setup_all do: clear_config([:instance, :federating], true)
- setup do: clear_config([:instance, :allow_relay])
- setup do: clear_config([:mrf, :policies])
- setup do: clear_config([:mrf_keyword])
-
- describe "Publish an activity" do
- setup do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "HI"})
-
- relay_mock = {
- Pleroma.Web.ActivityPub.Relay,
- [],
- [publish: fn _activity -> send(self(), :relay_publish) end]
- }
-
- %{activity: activity, relay_mock: relay_mock}
- end
-
- test "with relays active, it publishes to the relay", %{
- activity: activity,
- relay_mock: relay_mock
- } do
- with_mocks([relay_mock]) do
- Federator.publish(activity)
- ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
- end
-
- assert_received :relay_publish
- end
-
- test "with relays deactivated, it does not publish to the relay", %{
- activity: activity,
- relay_mock: relay_mock
- } do
- Pleroma.Config.put([:instance, :allow_relay], false)
-
- with_mocks([relay_mock]) do
- Federator.publish(activity)
- ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
- end
-
- refute_received :relay_publish
- end
- end
-
- describe "Targets reachability filtering in `publish`" do
- test "it federates only to reachable instances via AP" do
- user = insert(:user)
-
- {inbox1, inbox2} =
- {"https://domain.com/users/nick1/inbox", "https://domain2.com/users/nick2/inbox"}
-
- insert(:user, %{
- local: false,
- nickname: "nick1@domain.com",
- ap_id: "https://domain.com/users/nick1",
- inbox: inbox1,
- ap_enabled: true
- })
-
- insert(:user, %{
- local: false,
- nickname: "nick2@domain2.com",
- ap_id: "https://domain2.com/users/nick2",
- inbox: inbox2,
- ap_enabled: true
- })
-
- dt = NaiveDateTime.utc_now()
- Instances.set_unreachable(inbox1, dt)
-
- Instances.set_consistently_unreachable(URI.parse(inbox2).host)
-
- {:ok, _activity} =
- CommonAPI.post(user, %{status: "HI @nick1@domain.com, @nick2@domain2.com!"})
-
- expected_dt = NaiveDateTime.to_iso8601(dt)
-
- ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
-
- assert ObanHelpers.member?(
- %{
- "op" => "publish_one",
- "params" => %{"inbox" => inbox1, "unreachable_since" => expected_dt}
- },
- all_enqueued(worker: PublisherWorker)
- )
- end
- end
-
- describe "Receive an activity" do
- test "successfully processes incoming AP docs with correct origin" do
- params = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "actor" => "http://mastodon.example.org/users/admin",
- "type" => "Create",
- "id" => "http://mastodon.example.org/users/admin/activities/1",
- "object" => %{
- "type" => "Note",
- "content" => "hi world!",
- "id" => "http://mastodon.example.org/users/admin/objects/1",
- "attributedTo" => "http://mastodon.example.org/users/admin"
- },
- "to" => ["https://www.w3.org/ns/activitystreams#Public"]
- }
-
- assert {:ok, job} = Federator.incoming_ap_doc(params)
- assert {:ok, _activity} = ObanHelpers.perform(job)
-
- assert {:ok, job} = Federator.incoming_ap_doc(params)
- assert {:error, :already_present} = ObanHelpers.perform(job)
- end
-
- test "rejects incoming AP docs with incorrect origin" do
- params = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "actor" => "https://niu.moe/users/rye",
- "type" => "Create",
- "id" => "http://mastodon.example.org/users/admin/activities/1",
- "object" => %{
- "type" => "Note",
- "content" => "hi world!",
- "id" => "http://mastodon.example.org/users/admin/objects/1",
- "attributedTo" => "http://mastodon.example.org/users/admin"
- },
- "to" => ["https://www.w3.org/ns/activitystreams#Public"]
- }
-
- assert {:ok, job} = Federator.incoming_ap_doc(params)
- assert {:error, :origin_containment_failed} = ObanHelpers.perform(job)
- end
-
- test "it does not crash if MRF rejects the post" do
- Pleroma.Config.put([:mrf_keyword, :reject], ["lain"])
-
- Pleroma.Config.put(
- [:mrf, :policies],
- Pleroma.Web.ActivityPub.MRF.KeywordPolicy
- )
-
- params =
- File.read!("test/fixtures/mastodon-post-activity.json")
- |> Poison.decode!()
-
- assert {:ok, job} = Federator.incoming_ap_doc(params)
- assert {:error, _} = ObanHelpers.perform(job)
- end
- end
-end
diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs
deleted file mode 100644
index 868e40965..000000000
--- a/test/web/feed/tag_controller_test.exs
+++ /dev/null
@@ -1,197 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Feed.TagControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
- import SweetXml
-
- alias Pleroma.Object
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.Feed.FeedView
-
- setup do: clear_config([:feed])
-
- test "gets a feed (ATOM)", %{conn: conn} do
- Pleroma.Config.put(
- [:feed, :post_title],
- %{max_length: 25, omission: "..."}
- )
-
- user = insert(:user)
- {:ok, activity1} = CommonAPI.post(user, %{status: "yeah #PleromaArt"})
-
- object = Object.normalize(activity1)
-
- object_data =
- Map.put(object.data, "attachment", [
- %{
- "url" => [
- %{
- "href" =>
- "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
- "mediaType" => "video/mp4",
- "type" => "Link"
- }
- ]
- }
- ])
-
- object
- |> Ecto.Changeset.change(data: object_data)
- |> Pleroma.Repo.update()
-
- {:ok, activity2} = CommonAPI.post(user, %{status: "42 This is :moominmamma #PleromaArt"})
-
- {:ok, _activity3} = CommonAPI.post(user, %{status: "This is :moominmamma"})
-
- response =
- conn
- |> put_req_header("accept", "application/atom+xml")
- |> get(tag_feed_path(conn, :feed, "pleromaart.atom"))
- |> response(200)
-
- xml = parse(response)
-
- assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart'
-
- assert xpath(xml, ~x"//feed/entry/title/text()"l) == [
- '42 This is :moominmamm...',
- 'yeah #PleromaArt'
- ]
-
- assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
- assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id]
-
- conn =
- conn
- |> put_req_header("accept", "application/atom+xml")
- |> get("/tags/pleromaart.atom", %{"max_id" => activity2.id})
-
- assert get_resp_header(conn, "content-type") == ["application/atom+xml; charset=utf-8"]
- resp = response(conn, 200)
- xml = parse(resp)
-
- assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart'
-
- assert xpath(xml, ~x"//feed/entry/title/text()"l) == [
- 'yeah #PleromaArt'
- ]
- end
-
- test "gets a feed (RSS)", %{conn: conn} do
- Pleroma.Config.put(
- [:feed, :post_title],
- %{max_length: 25, omission: "..."}
- )
-
- user = insert(:user)
- {:ok, activity1} = CommonAPI.post(user, %{status: "yeah #PleromaArt"})
-
- object = Object.normalize(activity1)
-
- object_data =
- Map.put(object.data, "attachment", [
- %{
- "url" => [
- %{
- "href" =>
- "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
- "mediaType" => "video/mp4",
- "type" => "Link"
- }
- ]
- }
- ])
-
- object
- |> Ecto.Changeset.change(data: object_data)
- |> Pleroma.Repo.update()
-
- {:ok, activity2} = CommonAPI.post(user, %{status: "42 This is :moominmamma #PleromaArt"})
-
- {:ok, _activity3} = CommonAPI.post(user, %{status: "This is :moominmamma"})
-
- response =
- conn
- |> put_req_header("accept", "application/rss+xml")
- |> get(tag_feed_path(conn, :feed, "pleromaart.rss"))
- |> response(200)
-
- xml = parse(response)
- assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
-
- assert xpath(xml, ~x"//channel/description/text()"s) ==
- "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
-
- assert xpath(xml, ~x"//channel/link/text()") ==
- '#{Pleroma.Web.base_url()}/tags/pleromaart.rss'
-
- assert xpath(xml, ~x"//channel/webfeeds:logo/text()") ==
- '#{Pleroma.Web.base_url()}/static/logo.png'
-
- assert xpath(xml, ~x"//channel/item/title/text()"l) == [
- '42 This is :moominmamm...',
- 'yeah #PleromaArt'
- ]
-
- assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [
- FeedView.pub_date(activity2.data["published"]),
- FeedView.pub_date(activity1.data["published"])
- ]
-
- assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [
- "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4"
- ]
-
- obj1 = Object.normalize(activity1)
- obj2 = Object.normalize(activity2)
-
- assert xpath(xml, ~x"//channel/item/description/text()"sl) == [
- HtmlEntities.decode(FeedView.activity_content(obj2.data)),
- HtmlEntities.decode(FeedView.activity_content(obj1.data))
- ]
-
- response =
- conn
- |> put_req_header("accept", "application/rss+xml")
- |> get(tag_feed_path(conn, :feed, "pleromaart"))
- |> response(200)
-
- xml = parse(response)
- assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
-
- assert xpath(xml, ~x"//channel/description/text()"s) ==
- "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse."
-
- conn =
- conn
- |> put_req_header("accept", "application/rss+xml")
- |> get("/tags/pleromaart.rss", %{"max_id" => activity2.id})
-
- assert get_resp_header(conn, "content-type") == ["application/rss+xml; charset=utf-8"]
- resp = response(conn, 200)
- xml = parse(resp)
-
- assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart'
-
- assert xpath(xml, ~x"//channel/item/title/text()"l) == [
- 'yeah #PleromaArt'
- ]
- end
-
- describe "private instance" do
- setup do: clear_config([:instance, :public])
-
- test "returns 404 for tags feed", %{conn: conn} do
- Config.put([:instance, :public], false)
-
- conn
- |> put_req_header("accept", "application/rss+xml")
- |> get(tag_feed_path(conn, :feed, "pleromaart"))
- |> response(404)
- end
- end
-end
diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs
deleted file mode 100644
index 9a5610baa..000000000
--- a/test/web/feed/user_controller_test.exs
+++ /dev/null
@@ -1,265 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Feed.UserControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
- import SweetXml
-
- alias Pleroma.Config
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- setup do: clear_config([:instance, :federating], true)
-
- describe "feed" do
- setup do: clear_config([:feed])
-
- test "gets an atom feed", %{conn: conn} do
- Config.put(
- [:feed, :post_title],
- %{max_length: 10, omission: "..."}
- )
-
- activity = insert(:note_activity)
-
- note =
- insert(:note,
- data: %{
- "content" => "This is :moominmamma: note ",
- "attachment" => [
- %{
- "url" => [
- %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
- ]
- }
- ],
- "inReplyTo" => activity.data["id"]
- }
- )
-
- note_activity = insert(:note_activity, note: note)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- note2 =
- insert(:note,
- user: user,
- data: %{
- "content" => "42 This is :moominmamma: note ",
- "inReplyTo" => activity.data["id"]
- }
- )
-
- note_activity2 = insert(:note_activity, note: note2)
- object = Object.normalize(note_activity)
-
- resp =
- conn
- |> put_req_header("accept", "application/atom+xml")
- |> get(user_feed_path(conn, :feed, user.nickname))
- |> response(200)
-
- activity_titles =
- resp
- |> SweetXml.parse()
- |> SweetXml.xpath(~x"//entry/title/text()"l)
-
- assert activity_titles == ['42 This...', 'This is...']
- assert resp =~ object.data["content"]
-
- resp =
- conn
- |> put_req_header("accept", "application/atom+xml")
- |> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id})
- |> response(200)
-
- activity_titles =
- resp
- |> SweetXml.parse()
- |> SweetXml.xpath(~x"//entry/title/text()"l)
-
- assert activity_titles == ['This is...']
- end
-
- test "gets a rss feed", %{conn: conn} do
- Pleroma.Config.put(
- [:feed, :post_title],
- %{max_length: 10, omission: "..."}
- )
-
- activity = insert(:note_activity)
-
- note =
- insert(:note,
- data: %{
- "content" => "This is :moominmamma: note ",
- "attachment" => [
- %{
- "url" => [
- %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
- ]
- }
- ],
- "inReplyTo" => activity.data["id"]
- }
- )
-
- note_activity = insert(:note_activity, note: note)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- note2 =
- insert(:note,
- user: user,
- data: %{
- "content" => "42 This is :moominmamma: note ",
- "inReplyTo" => activity.data["id"]
- }
- )
-
- note_activity2 = insert(:note_activity, note: note2)
- object = Object.normalize(note_activity)
-
- resp =
- conn
- |> put_req_header("accept", "application/rss+xml")
- |> get("/users/#{user.nickname}/feed.rss")
- |> response(200)
-
- activity_titles =
- resp
- |> SweetXml.parse()
- |> SweetXml.xpath(~x"//item/title/text()"l)
-
- assert activity_titles == ['42 This...', 'This is...']
- assert resp =~ object.data["content"]
-
- resp =
- conn
- |> put_req_header("accept", "application/rss+xml")
- |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id})
- |> response(200)
-
- activity_titles =
- resp
- |> SweetXml.parse()
- |> SweetXml.xpath(~x"//item/title/text()"l)
-
- assert activity_titles == ['This is...']
- end
-
- test "returns 404 for a missing feed", %{conn: conn} do
- conn =
- conn
- |> put_req_header("accept", "application/atom+xml")
- |> get(user_feed_path(conn, :feed, "nonexisting"))
-
- assert response(conn, 404)
- end
-
- test "returns feed with public and unlisted activities", %{conn: conn} do
- user = insert(:user)
-
- {:ok, _} = CommonAPI.post(user, %{status: "public", visibility: "public"})
- {:ok, _} = CommonAPI.post(user, %{status: "direct", visibility: "direct"})
- {:ok, _} = CommonAPI.post(user, %{status: "unlisted", visibility: "unlisted"})
- {:ok, _} = CommonAPI.post(user, %{status: "private", visibility: "private"})
-
- resp =
- conn
- |> put_req_header("accept", "application/atom+xml")
- |> get(user_feed_path(conn, :feed, user.nickname))
- |> response(200)
-
- activity_titles =
- resp
- |> SweetXml.parse()
- |> SweetXml.xpath(~x"//entry/title/text()"l)
- |> Enum.sort()
-
- assert activity_titles == ['public', 'unlisted']
- end
-
- test "returns 404 when the user is remote", %{conn: conn} do
- user = insert(:user, local: false)
-
- {:ok, _} = CommonAPI.post(user, %{status: "test"})
-
- assert conn
- |> put_req_header("accept", "application/atom+xml")
- |> get(user_feed_path(conn, :feed, user.nickname))
- |> response(404)
- end
- end
-
- # Note: see ActivityPubControllerTest for JSON format tests
- describe "feed_redirect" do
- test "with html format, it redirects to user feed", %{conn: conn} do
- note_activity = insert(:note_activity)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- response =
- conn
- |> get("/users/#{user.nickname}")
- |> response(200)
-
- assert response ==
- Fallback.RedirectController.redirector_with_meta(
- conn,
- %{user: user}
- ).resp_body
- end
-
- test "with html format, it returns error when user is not found", %{conn: conn} do
- response =
- conn
- |> get("/users/jimm")
- |> json_response(404)
-
- assert response == %{"error" => "Not found"}
- end
-
- test "with non-html / non-json format, it redirects to user feed in atom format", %{
- conn: conn
- } do
- note_activity = insert(:note_activity)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- conn =
- conn
- |> put_req_header("accept", "application/xml")
- |> get("/users/#{user.nickname}")
-
- assert conn.status == 302
- assert redirected_to(conn) == "#{Pleroma.Web.base_url()}/users/#{user.nickname}/feed.atom"
- end
-
- test "with non-html / non-json format, it returns error when user is not found", %{conn: conn} do
- response =
- conn
- |> put_req_header("accept", "application/xml")
- |> get(user_feed_path(conn, :feed, "jimm"))
- |> response(404)
-
- assert response == ~S({"error":"Not found"})
- end
- end
-
- describe "private instance" do
- setup do: clear_config([:instance, :public])
-
- test "returns 404 for user feed", %{conn: conn} do
- Config.put([:instance, :public], false)
- user = insert(:user)
-
- {:ok, _} = CommonAPI.post(user, %{status: "test"})
-
- assert conn
- |> put_req_header("accept", "application/atom+xml")
- |> get(user_feed_path(conn, :feed, user.nickname))
- |> response(404)
- end
- end
-end
diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs
deleted file mode 100644
index 5d4efcebe..000000000
--- a/test/web/instances/instance_test.exs
+++ /dev/null
@@ -1,135 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Instances.InstanceTest do
- alias Pleroma.Instances.Instance
- alias Pleroma.Repo
-
- use Pleroma.DataCase
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
-
- setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1)
-
- describe "set_reachable/1" do
- test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do
- 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
- end
-
- test "keeps nil `unreachable_since` of existing matching Instance record having nil `unreachable_since`" do
- instance = insert(:instance, unreachable_since: nil)
-
- assert {:ok, instance} = Instance.set_reachable(instance.host)
- refute instance.unreachable_since
- end
-
- test "does NOT create an Instance record in case of no existing matching record" do
- host = "domain.org"
- assert nil == Instance.set_reachable(host)
-
- assert [] = Repo.all(Ecto.Query.from(i in Instance))
- assert Instance.reachable?(host)
- end
- end
-
- describe "set_unreachable/1" do
- test "creates new record having `unreachable_since` to current time if record does not exist" do
- assert {:ok, instance} = Instance.set_unreachable("https://domain.com/path")
-
- instance = Repo.get(Instance, instance.id)
- assert instance.unreachable_since
- assert "domain.com" == instance.host
- end
-
- test "sets `unreachable_since` of existing record having nil `unreachable_since`" do
- instance = insert(:instance, unreachable_since: nil)
- refute instance.unreachable_since
-
- assert {:ok, _} = Instance.set_unreachable(instance.host)
-
- instance = Repo.get(Instance, instance.id)
- assert instance.unreachable_since
- end
-
- test "does NOT modify `unreachable_since` value of existing record in case it's present" do
- instance =
- insert(:instance, unreachable_since: NaiveDateTime.add(NaiveDateTime.utc_now(), -10))
-
- assert instance.unreachable_since
- initial_value = instance.unreachable_since
-
- assert {:ok, _} = Instance.set_unreachable(instance.host)
-
- instance = Repo.get(Instance, instance.id)
- assert initial_value == instance.unreachable_since
- end
- end
-
- describe "set_unreachable/2" do
- test "sets `unreachable_since` value of existing record in case it's newer than supplied value" do
- instance =
- insert(:instance, unreachable_since: NaiveDateTime.add(NaiveDateTime.utc_now(), -10))
-
- assert instance.unreachable_since
-
- past_value = NaiveDateTime.add(NaiveDateTime.utc_now(), -100)
- assert {:ok, _} = Instance.set_unreachable(instance.host, past_value)
-
- instance = Repo.get(Instance, instance.id)
- assert past_value == instance.unreachable_since
- end
-
- test "does NOT modify `unreachable_since` value of existing record in case it's equal to or older than supplied value" do
- instance =
- insert(:instance, unreachable_since: NaiveDateTime.add(NaiveDateTime.utc_now(), -10))
-
- assert instance.unreachable_since
- initial_value = instance.unreachable_since
-
- assert {:ok, _} = Instance.set_unreachable(instance.host, NaiveDateTime.utc_now())
-
- instance = Repo.get(Instance, instance.id)
- assert initial_value == instance.unreachable_since
- end
- end
-
- test "Scrapes favicon URLs" do
- Tesla.Mock.mock(fn %{url: "https://favicon.example.org/"} ->
- %Tesla.Env{
- status: 200,
- body: ~s[<html><head><link rel="icon" href="/favicon.png"></head></html>]
- }
- end)
-
- assert "https://favicon.example.org/favicon.png" ==
- Instance.get_or_update_favicon(URI.parse("https://favicon.example.org/"))
- end
-
- test "Returns nil on too long favicon URLs" do
- clear_config([:instances_favicons, :enabled], true)
-
- long_favicon_url =
- "https://Lorem.ipsum.dolor.sit.amet/consecteturadipiscingelit/Praesentpharetrapurusutaliquamtempus/Mauriseulaoreetarcu/atfacilisisorci/Nullamporttitor/nequesedfeugiatmollis/dolormagnaefficiturlorem/nonpretiumsapienorcieurisus/Nullamveleratsem/Maecenassedaccumsanexnam/favicon.png"
-
- Tesla.Mock.mock(fn %{url: "https://long-favicon.example.org/"} ->
- %Tesla.Env{
- status: 200,
- body: ~s[<html><head><link rel="icon" href="] <> long_favicon_url <> ~s["></head></html>]
- }
- end)
-
- assert capture_log(fn ->
- assert nil ==
- Instance.get_or_update_favicon(
- URI.parse("https://long-favicon.example.org/")
- )
- end) =~
- "Instance.get_or_update_favicon(\"long-favicon.example.org\") error: %Postgrex.Error{"
- end
-end
diff --git a/test/web/instances/instances_test.exs b/test/web/instances/instances_test.exs
deleted file mode 100644
index d2618025c..000000000
--- a/test/web/instances/instances_test.exs
+++ /dev/null
@@ -1,124 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.InstancesTest do
- alias Pleroma.Instances
-
- use Pleroma.DataCase
-
- setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1)
-
- describe "reachable?/1" do
- test "returns `true` for host / url with unknown reachability status" do
- assert Instances.reachable?("unknown.site")
- assert Instances.reachable?("http://unknown.site")
- end
-
- test "returns `false` for host / url marked unreachable for at least `reachability_datetime_threshold()`" do
- host = "consistently-unreachable.name"
- Instances.set_consistently_unreachable(host)
-
- refute Instances.reachable?(host)
- refute Instances.reachable?("http://#{host}/path")
- end
-
- test "returns `true` for host / url marked unreachable for less than `reachability_datetime_threshold()`" do
- url = "http://eventually-unreachable.name/path"
-
- Instances.set_unreachable(url)
-
- assert Instances.reachable?(url)
- assert Instances.reachable?(URI.parse(url).host)
- end
-
- test "returns true on non-binary input" do
- assert Instances.reachable?(nil)
- assert Instances.reachable?(1)
- end
- end
-
- describe "filter_reachable/1" do
- setup do
- host = "consistently-unreachable.name"
- url1 = "http://eventually-unreachable.com/path"
- url2 = "http://domain.com/path"
-
- Instances.set_consistently_unreachable(host)
- Instances.set_unreachable(url1)
-
- result = Instances.filter_reachable([host, url1, url2, nil])
- %{result: result, url1: url1, url2: url2}
- end
-
- test "returns a map with keys containing 'not marked consistently unreachable' elements of supplied list",
- %{result: result, url1: url1, url2: url2} do
- assert is_map(result)
- assert Enum.sort([url1, url2]) == result |> Map.keys() |> Enum.sort()
- end
-
- test "returns a map with `unreachable_since` values for keys",
- %{result: result, url1: url1, url2: url2} do
- assert is_map(result)
- assert %NaiveDateTime{} = result[url1]
- assert is_nil(result[url2])
- end
-
- test "returns an empty map for empty list or list containing no hosts / url" do
- assert %{} == Instances.filter_reachable([])
- assert %{} == Instances.filter_reachable([nil])
- end
- end
-
- describe "set_reachable/1" do
- test "sets unreachable url or host reachable" do
- host = "domain.com"
- Instances.set_consistently_unreachable(host)
- refute Instances.reachable?(host)
-
- Instances.set_reachable(host)
- assert Instances.reachable?(host)
- end
-
- test "keeps reachable url or host reachable" do
- url = "https://site.name?q="
- assert Instances.reachable?(url)
-
- Instances.set_reachable(url)
- assert Instances.reachable?(url)
- end
-
- test "returns error status on non-binary input" do
- assert {:error, _} = Instances.set_reachable(nil)
- assert {:error, _} = Instances.set_reachable(1)
- end
- end
-
- # Note: implementation-specific (e.g. Instance) details of set_unreachable/1
- # should be tested in implementation-specific tests
- describe "set_unreachable/1" do
- test "returns error status on non-binary input" do
- assert {:error, _} = Instances.set_unreachable(nil)
- assert {:error, _} = Instances.set_unreachable(1)
- end
- end
-
- describe "set_consistently_unreachable/1" do
- test "sets reachable url or host unreachable" do
- url = "http://domain.com?q="
- assert Instances.reachable?(url)
-
- Instances.set_consistently_unreachable(url)
- refute Instances.reachable?(url)
- end
-
- test "keeps unreachable url or host unreachable" do
- host = "site.name"
- Instances.set_consistently_unreachable(host)
- refute Instances.reachable?(host)
-
- Instances.set_consistently_unreachable(host)
- refute Instances.reachable?(host)
- end
- end
-end
diff --git a/test/web/masto_fe_controller_test.exs b/test/web/masto_fe_controller_test.exs
deleted file mode 100644
index f3b54b5f2..000000000
--- a/test/web/masto_fe_controller_test.exs
+++ /dev/null
@@ -1,85 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MastoFEController do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Config
- alias Pleroma.User
-
- import Pleroma.Factory
-
- setup do: clear_config([:instance, :public])
-
- test "put settings", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"]))
- |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
-
- assert _result = json_response(conn, 200)
-
- user = User.get_cached_by_ap_id(user.ap_id)
- assert user.mastofe_settings == %{"programming" => "socks"}
- end
-
- describe "index/2 redirections" do
- setup %{conn: conn} do
- session_opts = [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session()
-
- test_path = "/web/statuses/test"
- %{conn: conn, path: test_path}
- end
-
- test "redirects not logged-in users to the login page", %{conn: conn, path: path} do
- conn = get(conn, path)
-
- assert conn.status == 302
- assert redirected_to(conn) == "/web/login"
- end
-
- test "redirects not logged-in users to the login page on private instances", %{
- conn: conn,
- path: path
- } do
- Config.put([:instance, :public], false)
-
- conn = get(conn, path)
-
- assert conn.status == 302
- assert redirected_to(conn) == "/web/login"
- end
-
- test "does not redirect logged in users to the login page", %{conn: conn, path: path} do
- token = insert(:oauth_token, scopes: ["read"])
-
- conn =
- conn
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> get(path)
-
- assert conn.status == 200
- end
-
- test "saves referer path to session", %{conn: conn, path: path} do
- conn = get(conn, path)
- return_to = Plug.Conn.get_session(conn, :return_to)
-
- assert return_to == path
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
deleted file mode 100644
index 2e6704726..000000000
--- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
+++ /dev/null
@@ -1,529 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
- alias Pleroma.Repo
- alias Pleroma.User
-
- use Pleroma.Web.ConnCase
-
- import Mock
- import Pleroma.Factory
-
- setup do: clear_config([:instance, :max_account_fields])
-
- describe "updating credentials" do
- setup do: oauth_access(["write:accounts"])
- setup :request_content_type
-
- test "sets user settings in a generic way", %{conn: conn} do
- res_conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- "pleroma_settings_store" => %{
- pleroma_fe: %{
- theme: "bla"
- }
- }
- })
-
- assert user_data = json_response_and_validate_schema(res_conn, 200)
- assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}}
-
- user = Repo.get(User, user_data["id"])
-
- res_conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/accounts/update_credentials", %{
- "pleroma_settings_store" => %{
- masto_fe: %{
- theme: "bla"
- }
- }
- })
-
- assert user_data = json_response_and_validate_schema(res_conn, 200)
-
- assert user_data["pleroma"]["settings_store"] ==
- %{
- "pleroma_fe" => %{"theme" => "bla"},
- "masto_fe" => %{"theme" => "bla"}
- }
-
- user = Repo.get(User, user_data["id"])
-
- clear_config([:instance, :federating], true)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _activity -> :ok end do
- res_conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/accounts/update_credentials", %{
- "pleroma_settings_store" => %{
- masto_fe: %{
- theme: "blub"
- }
- }
- })
-
- assert user_data = json_response_and_validate_schema(res_conn, 200)
-
- assert user_data["pleroma"]["settings_store"] ==
- %{
- "pleroma_fe" => %{"theme" => "bla"},
- "masto_fe" => %{"theme" => "blub"}
- }
-
- assert_called(Pleroma.Web.Federator.publish(:_))
- end
- end
-
- test "updates the user's bio", %{conn: conn} do
- user2 = insert(:user)
-
- raw_bio = "I drink #cofe with @#{user2.nickname}\n\nsuya.."
-
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
-
- assert user_data["note"] ==
- ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{
- user2.id
- }" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
-
- assert user_data["source"]["note"] == raw_bio
-
- user = Repo.get(User, user_data["id"])
-
- assert user.raw_bio == raw_bio
- end
-
- test "updates the user's locking status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["locked"] == true
- end
-
- test "updates the user's chat acceptance status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_chat_messages: "false"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["accepts_chat_messages"] == false
- end
-
- test "updates the user's allow_following_move", %{user: user, conn: conn} do
- assert user.allow_following_move == true
-
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"})
-
- assert refresh_record(user).allow_following_move == false
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["allow_following_move"] == false
- end
-
- test "updates the user's default scope", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "unlisted"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["privacy"] == "unlisted"
- end
-
- test "updates the user's privacy", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{source: %{privacy: "unlisted"}})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["privacy"] == "unlisted"
- end
-
- test "updates the user's hide_followers status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_followers"] == true
- end
-
- test "updates the user's discoverable status", %{conn: conn} do
- assert %{"source" => %{"pleroma" => %{"discoverable" => true}}} =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{discoverable: "true"})
- |> json_response_and_validate_schema(:ok)
-
- assert %{"source" => %{"pleroma" => %{"discoverable" => false}}} =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{discoverable: "false"})
- |> json_response_and_validate_schema(:ok)
- end
-
- test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do
- conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- hide_followers_count: "true",
- hide_follows_count: "true"
- })
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_followers_count"] == true
- assert user_data["pleroma"]["hide_follows_count"] == true
- end
-
- test "updates the user's skip_thread_containment option", %{user: user, conn: conn} do
- response =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"})
- |> json_response_and_validate_schema(200)
-
- assert response["pleroma"]["skip_thread_containment"] == true
- assert refresh_record(user).skip_thread_containment
- end
-
- test "updates the user's hide_follows status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_follows"] == true
- end
-
- test "updates the user's hide_favorites status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_favorites"] == true
- end
-
- test "updates the user's show_role status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["pleroma"]["show_role"] == false
- end
-
- test "updates the user's no_rich_text status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["pleroma"]["no_rich_text"] == true
- end
-
- test "updates the user's name", %{conn: conn} do
- conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["display_name"] == "markorepairs"
-
- update_activity = Repo.one(Pleroma.Activity)
- assert update_activity.data["type"] == "Update"
- assert update_activity.data["object"]["name"] == "markorepairs"
- end
-
- test "updates the user's avatar", %{user: user, conn: conn} do
- new_avatar = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- assert user.avatar == %{}
-
- res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
-
- assert user_response = json_response_and_validate_schema(res, 200)
- assert user_response["avatar"] != User.avatar_url(user)
-
- user = User.get_by_id(user.id)
- refute user.avatar == %{}
-
- # Also resets it
- _res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => ""})
-
- user = User.get_by_id(user.id)
- assert user.avatar == nil
- end
-
- test "updates the user's banner", %{user: user, conn: conn} do
- new_header = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
-
- assert user_response = json_response_and_validate_schema(res, 200)
- assert user_response["header"] != User.banner_url(user)
-
- # Also resets it
- _res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => ""})
-
- user = User.get_by_id(user.id)
- assert user.banner == nil
- end
-
- test "updates the user's background", %{conn: conn, user: user} do
- new_header = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- res =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- "pleroma_background_image" => new_header
- })
-
- assert user_response = json_response_and_validate_schema(res, 200)
- assert user_response["pleroma"]["background_image"]
- #
- # Also resets it
- _res =
- patch(conn, "/api/v1/accounts/update_credentials", %{"pleroma_background_image" => ""})
-
- user = User.get_by_id(user.id)
- assert user.background == nil
- end
-
- test "requires 'write:accounts' permission" do
- token1 = insert(:oauth_token, scopes: ["read"])
- token2 = insert(:oauth_token, scopes: ["write", "follow"])
-
- for token <- [token1, token2] do
- conn =
- build_conn()
- |> put_req_header("content-type", "multipart/form-data")
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> patch("/api/v1/accounts/update_credentials", %{})
-
- if token == token1 do
- assert %{"error" => "Insufficient permissions: write:accounts."} ==
- json_response_and_validate_schema(conn, 403)
- else
- assert json_response_and_validate_schema(conn, 200)
- end
- end
- end
-
- test "updates profile emojos", %{user: user, conn: conn} do
- note = "*sips :blank:*"
- name = "I am :firefox:"
-
- ret_conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- "note" => note,
- "display_name" => name
- })
-
- assert json_response_and_validate_schema(ret_conn, 200)
-
- conn = get(conn, "/api/v1/accounts/#{user.id}")
-
- assert user_data = json_response_and_validate_schema(conn, 200)
-
- assert user_data["note"] == note
- assert user_data["display_name"] == name
- assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user_data["emojis"]
- end
-
- test "update fields", %{conn: conn} do
- fields = [
- %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>"},
- %{"name" => "link.io", "value" => "cofe.io"}
- ]
-
- account_data =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(200)
-
- assert account_data["fields"] == [
- %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"},
- %{
- "name" => "link.io",
- "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)
- }
- ]
-
- assert account_data["source"]["fields"] == [
- %{
- "name" => "<a href=\"http://google.com\">foo</a>",
- "value" => "<script>bar</script>"
- },
- %{"name" => "link.io", "value" => "cofe.io"}
- ]
- end
-
- test "emojis in fields labels", %{conn: conn} do
- fields = [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
- ]
-
- account_data =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(200)
-
- assert account_data["fields"] == [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
- ]
-
- assert account_data["source"]["fields"] == [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
- ]
-
- assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = account_data["emojis"]
- end
-
- test "update fields via x-www-form-urlencoded", %{conn: conn} do
- fields =
- [
- "fields_attributes[1][name]=link",
- "fields_attributes[1][value]=http://cofe.io",
- "fields_attributes[0][name]=foo",
- "fields_attributes[0][value]=bar"
- ]
- |> Enum.join("&")
-
- account =
- conn
- |> put_req_header("content-type", "application/x-www-form-urlencoded")
- |> patch("/api/v1/accounts/update_credentials", fields)
- |> json_response_and_validate_schema(200)
-
- assert account["fields"] == [
- %{"name" => "foo", "value" => "bar"},
- %{
- "name" => "link",
- "value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>)
- }
- ]
-
- assert account["source"]["fields"] == [
- %{"name" => "foo", "value" => "bar"},
- %{"name" => "link", "value" => "http://cofe.io"}
- ]
- end
-
- test "update fields with empty name", %{conn: conn} do
- fields = [
- %{"name" => "foo", "value" => ""},
- %{"name" => "", "value" => "bar"}
- ]
-
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(200)
-
- assert account["fields"] == [
- %{"name" => "foo", "value" => ""}
- ]
- end
-
- test "update fields when invalid request", %{conn: conn} do
- name_limit = Pleroma.Config.get([:instance, :account_field_name_length])
- value_limit = Pleroma.Config.get([:instance, :account_field_value_length])
-
- long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join()
- long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join()
-
- fields = [%{"name" => "foo", "value" => long_value}]
-
- assert %{"error" => "Invalid request"} ==
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
-
- fields = [%{"name" => long_name, "value" => "bar"}]
-
- assert %{"error" => "Invalid request"} ==
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
-
- Pleroma.Config.put([:instance, :max_account_fields], 1)
-
- fields = [
- %{"name" => "foo", "value" => "bar"},
- %{"name" => "link", "value" => "cofe.io"}
- ]
-
- assert %{"error" => "Invalid request"} ==
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
- end
- end
-
- describe "Mark account as bot" do
- setup do: oauth_access(["write:accounts"])
- setup :request_content_type
-
- test "changing actor_type to Service makes account a bot", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Service"})
- |> json_response_and_validate_schema(200)
-
- assert account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Service"
- end
-
- test "changing actor_type to Person makes account a human", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Person"})
- |> json_response_and_validate_schema(200)
-
- refute account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Person"
- end
-
- test "changing actor_type to Application causes error", %{conn: conn} do
- response =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Application"})
- |> json_response_and_validate_schema(403)
-
- assert %{"error" => "Invalid request"} == response
- end
-
- test "changing bot field to true changes actor_type to Service", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{bot: "true"})
- |> json_response_and_validate_schema(200)
-
- assert account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Service"
- end
-
- test "changing bot field to false changes actor_type to Person", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{bot: "false"})
- |> json_response_and_validate_schema(200)
-
- refute account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Person"
- end
-
- test "actor_type field has a higher priority than bot", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{
- actor_type: "Person",
- bot: "true"
- })
- |> json_response_and_validate_schema(200)
-
- refute account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Person"
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs
deleted file mode 100644
index 17a1e7d66..000000000
--- a/test/web/mastodon_api/controllers/account_controller_test.exs
+++ /dev/null
@@ -1,1533 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.ActivityPub.InternalFetchActor
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.OAuth.Token
-
- import Pleroma.Factory
-
- describe "account fetching" do
- test "works by id" do
- %User{id: user_id} = insert(:user)
-
- assert %{"id" => ^user_id} =
- build_conn()
- |> get("/api/v1/accounts/#{user_id}")
- |> json_response_and_validate_schema(200)
-
- assert %{"error" => "Can't find user"} =
- build_conn()
- |> get("/api/v1/accounts/-1")
- |> json_response_and_validate_schema(404)
- end
-
- test "works by nickname" do
- user = insert(:user)
-
- assert %{"id" => user_id} =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
- |> json_response_and_validate_schema(200)
- end
-
- test "works by nickname for remote users" do
- clear_config([:instance, :limit_to_local_content], false)
-
- user = insert(:user, nickname: "user@example.com", local: false)
-
- assert %{"id" => user_id} =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
- |> json_response_and_validate_schema(200)
- end
-
- test "respects limit_to_local_content == :all for remote user nicknames" do
- clear_config([:instance, :limit_to_local_content], :all)
-
- user = insert(:user, nickname: "user@example.com", local: false)
-
- assert build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
- |> json_response_and_validate_schema(404)
- end
-
- test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
- clear_config([:instance, :limit_to_local_content], :unauthenticated)
-
- user = insert(:user, nickname: "user@example.com", local: false)
- reading_user = insert(:user)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
-
- assert json_response_and_validate_schema(conn, 404)
-
- conn =
- build_conn()
- |> assign(:user, reading_user)
- |> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"]))
- |> get("/api/v1/accounts/#{user.nickname}")
-
- assert %{"id" => id} = json_response_and_validate_schema(conn, 200)
- assert id == user.id
- end
-
- test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
- # Need to set an old-style integer ID to reproduce the problem
- # (these are no longer assigned to new accounts but were preserved
- # for existing accounts during the migration to flakeIDs)
- user_one = insert(:user, %{id: 1212})
- user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
-
- acc_one =
- conn
- |> get("/api/v1/accounts/#{user_one.id}")
- |> json_response_and_validate_schema(:ok)
-
- acc_two =
- conn
- |> get("/api/v1/accounts/#{user_two.nickname}")
- |> json_response_and_validate_schema(:ok)
-
- acc_three =
- conn
- |> get("/api/v1/accounts/#{user_two.id}")
- |> json_response_and_validate_schema(:ok)
-
- refute acc_one == acc_two
- assert acc_two == acc_three
- end
-
- test "returns 404 when user is invisible", %{conn: conn} do
- user = insert(:user, %{invisible: true})
-
- assert %{"error" => "Can't find user"} =
- conn
- |> get("/api/v1/accounts/#{user.nickname}")
- |> json_response_and_validate_schema(404)
- end
-
- test "returns 404 for internal.fetch actor", %{conn: conn} do
- %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor()
-
- assert %{"error" => "Can't find user"} =
- conn
- |> get("/api/v1/accounts/internal.fetch")
- |> json_response_and_validate_schema(404)
- end
-
- test "returns 404 for deactivated user", %{conn: conn} do
- user = insert(:user, deactivated: true)
-
- assert %{"error" => "Can't find user"} =
- conn
- |> get("/api/v1/accounts/#{user.id}")
- |> json_response_and_validate_schema(:not_found)
- end
- end
-
- defp local_and_remote_users do
- local = insert(:user)
- remote = insert(:user, local: false)
- {:ok, local: local, remote: remote}
- end
-
- describe "user fetching with restrict unauthenticated profiles for local and remote" do
- setup do: local_and_remote_users()
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- assert %{"error" => "This API requires an authenticated user"} ==
- conn
- |> get("/api/v1/accounts/#{local.id}")
- |> json_response_and_validate_schema(:unauthorized)
-
- assert %{"error" => "This API requires an authenticated user"} ==
- conn
- |> get("/api/v1/accounts/#{remote.id}")
- |> json_response_and_validate_schema(:unauthorized)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/accounts/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
- end
-
- describe "user fetching with restrict unauthenticated profiles for local" do
- setup do: local_and_remote_users()
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/accounts/#{local.id}")
-
- assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
- "error" => "This API requires an authenticated user"
- }
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/accounts/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
- end
-
- describe "user fetching with restrict unauthenticated profiles for remote" do
- setup do: local_and_remote_users()
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/accounts/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
-
- assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
- "error" => "This API requires an authenticated user"
- }
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/accounts/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
- end
-
- describe "user timelines" do
- setup do: oauth_access(["read:statuses"])
-
- test "works with announces that are just addressed to public", %{conn: conn} do
- user = insert(:user, ap_id: "https://honktest/u/test", local: false)
- other_user = insert(:user)
-
- {:ok, post} = CommonAPI.post(other_user, %{status: "bonkeronk"})
-
- {:ok, announce, _} =
- %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "actor" => "https://honktest/u/test",
- "id" => "https://honktest/u/test/bonk/1793M7B9MQ48847vdx",
- "object" => post.data["object"],
- "published" => "2019-06-25T19:33:58Z",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "type" => "Announce"
- }
- |> ActivityPub.persist(local: false)
-
- assert resp =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id}] = resp
- assert id == announce.id
- end
-
- test "deactivated user", %{conn: conn} do
- user = insert(:user, deactivated: true)
-
- assert %{"error" => "Can't find user"} ==
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses")
- |> json_response_and_validate_schema(:not_found)
- end
-
- test "returns 404 when user is invisible", %{conn: conn} do
- user = insert(:user, %{invisible: true})
-
- assert %{"error" => "Can't find user"} =
- conn
- |> get("/api/v1/accounts/#{user.id}")
- |> json_response_and_validate_schema(404)
- end
-
- test "respects blocks", %{user: user_one, conn: conn} do
- user_two = insert(:user)
- user_three = insert(:user)
-
- User.block(user_one, user_two)
-
- {:ok, activity} = CommonAPI.post(user_two, %{status: "User one sux0rz"})
- {:ok, repeat} = CommonAPI.repeat(activity.id, user_three)
-
- assert resp =
- conn
- |> get("/api/v1/accounts/#{user_two.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id}] = resp
- assert id == activity.id
-
- # Even a blocked user will deliver the full user timeline, there would be
- # no point in looking at a blocked users timeline otherwise
- assert resp =
- conn
- |> get("/api/v1/accounts/#{user_two.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id}] = resp
- assert id == activity.id
-
- # Third user's timeline includes the repeat when viewed by unauthenticated user
- resp =
- build_conn()
- |> get("/api/v1/accounts/#{user_three.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id}] = resp
- assert id == repeat.id
-
- # When viewing a third user's timeline, the blocked users' statuses will NOT be shown
- resp = get(conn, "/api/v1/accounts/#{user_three.id}/statuses")
-
- assert [] == json_response_and_validate_schema(resp, 200)
- end
-
- test "gets users statuses", %{conn: conn} do
- user_one = insert(:user)
- user_two = insert(:user)
- user_three = insert(:user)
-
- {:ok, _user_three} = User.follow(user_three, user_one)
-
- {:ok, activity} = CommonAPI.post(user_one, %{status: "HI!!!"})
-
- {:ok, direct_activity} =
- CommonAPI.post(user_one, %{
- status: "Hi, @#{user_two.nickname}.",
- visibility: "direct"
- })
-
- {:ok, private_activity} =
- CommonAPI.post(user_one, %{status: "private", visibility: "private"})
-
- # TODO!!!
- resp =
- conn
- |> get("/api/v1/accounts/#{user_one.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id}] = resp
- assert id == to_string(activity.id)
-
- resp =
- conn
- |> assign(:user, user_two)
- |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"]))
- |> get("/api/v1/accounts/#{user_one.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id_one}, %{"id" => id_two}] = resp
- assert id_one == to_string(direct_activity.id)
- assert id_two == to_string(activity.id)
-
- resp =
- conn
- |> assign(:user, user_three)
- |> assign(:token, insert(:oauth_token, user: user_three, scopes: ["read:statuses"]))
- |> get("/api/v1/accounts/#{user_one.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => id_one}, %{"id" => id_two}] = resp
- assert id_one == to_string(private_activity.id)
- assert id_two == to_string(activity.id)
- end
-
- test "unimplemented pinned statuses feature", %{conn: conn} do
- note = insert(:note_activity)
- user = User.get_cached_by_ap_id(note.data["actor"])
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?pinned=true")
-
- assert json_response_and_validate_schema(conn, 200) == []
- end
-
- test "gets an users media, excludes reblogs", %{conn: conn} do
- note = insert(:note_activity)
- user = User.get_cached_by_ap_id(note.data["actor"])
- other_user = insert(:user)
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id)
-
- {:ok, %{id: image_post_id}} = CommonAPI.post(user, %{status: "cofe", media_ids: [media_id]})
-
- {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: other_user.ap_id)
-
- {:ok, %{id: other_image_post_id}} =
- CommonAPI.post(other_user, %{status: "cofe2", media_ids: [media_id]})
-
- {:ok, _announce} = CommonAPI.repeat(other_image_post_id, user)
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?only_media=true")
-
- assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200)
-
- conn = get(build_conn(), "/api/v1/accounts/#{user.id}/statuses?only_media=1")
-
- assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200)
- end
-
- test "gets a user's statuses without reblogs", %{user: user, conn: conn} do
- {:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "HI!!!"})
- {:ok, _} = CommonAPI.repeat(post_id, user)
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=true")
- assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200)
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=1")
- assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200)
- end
-
- test "filters user's statuses by a hashtag", %{user: user, conn: conn} do
- {:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "#hashtag"})
- {:ok, _post} = CommonAPI.post(user, %{status: "hashtag"})
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?tagged=hashtag")
- assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200)
- end
-
- test "the user views their own timelines and excludes direct messages", %{
- user: user,
- conn: conn
- } do
- {:ok, %{id: public_activity_id}} =
- CommonAPI.post(user, %{status: ".", visibility: "public"})
-
- {:ok, _direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_visibilities[]=direct")
- assert [%{"id" => ^public_activity_id}] = json_response_and_validate_schema(conn, 200)
- end
- end
-
- defp local_and_remote_activities(%{local: local, remote: remote}) do
- insert(:note_activity, user: local)
- insert(:note_activity, user: remote, local: false)
-
- :ok
- end
-
- describe "statuses with restrict unauthenticated profiles for local and remote" do
- setup do: local_and_remote_users()
- setup :local_and_remote_activities
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- assert %{"error" => "This API requires an authenticated user"} ==
- conn
- |> get("/api/v1/accounts/#{local.id}/statuses")
- |> json_response_and_validate_schema(:unauthorized)
-
- assert %{"error" => "This API requires an authenticated user"} ==
- conn
- |> get("/api/v1/accounts/#{remote.id}/statuses")
- |> json_response_and_validate_schema(:unauthorized)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
- end
- end
-
- describe "statuses with restrict unauthenticated profiles for local" do
- setup do: local_and_remote_users()
- setup :local_and_remote_activities
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- assert %{"error" => "This API requires an authenticated user"} ==
- conn
- |> get("/api/v1/accounts/#{local.id}/statuses")
- |> json_response_and_validate_schema(:unauthorized)
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
- end
- end
-
- describe "statuses with restrict unauthenticated profiles for remote" do
- setup do: local_and_remote_users()
- setup :local_and_remote_activities
-
- setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- assert %{"error" => "This API requires an authenticated user"} ==
- conn
- |> get("/api/v1/accounts/#{remote.id}/statuses")
- |> json_response_and_validate_schema(:unauthorized)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
- end
- end
-
- describe "followers" do
- setup do: oauth_access(["read:accounts"])
-
- test "getting followers", %{user: user, conn: conn} do
- other_user = insert(:user)
- {:ok, %{id: user_id}} = User.follow(user, other_user)
-
- conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers")
-
- assert [%{"id" => ^user_id}] = json_response_and_validate_schema(conn, 200)
- end
-
- test "getting followers, hide_followers", %{user: user, conn: conn} do
- other_user = insert(:user, hide_followers: true)
- {:ok, _user} = User.follow(user, other_user)
-
- conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers")
-
- assert [] == json_response_and_validate_schema(conn, 200)
- end
-
- test "getting followers, hide_followers, same user requesting" do
- user = insert(:user)
- other_user = insert(:user, hide_followers: true)
- {:ok, _user} = User.follow(user, other_user)
-
- conn =
- build_conn()
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"]))
- |> get("/api/v1/accounts/#{other_user.id}/followers")
-
- refute [] == json_response_and_validate_schema(conn, 200)
- end
-
- test "getting followers, pagination", %{user: user, conn: conn} do
- {:ok, %User{id: follower1_id}} = :user |> insert() |> User.follow(user)
- {:ok, %User{id: follower2_id}} = :user |> insert() |> User.follow(user)
- {:ok, %User{id: follower3_id}} = :user |> insert() |> User.follow(user)
-
- assert [%{"id" => ^follower3_id}, %{"id" => ^follower2_id}] =
- conn
- |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1_id}")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => ^follower2_id}, %{"id" => ^follower1_id}] =
- conn
- |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3_id}")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => ^follower2_id}, %{"id" => ^follower1_id}] =
- conn
- |> get(
- "/api/v1/accounts/#{user.id}/followers?id=#{user.id}&limit=20&max_id=#{
- follower3_id
- }"
- )
- |> json_response_and_validate_schema(200)
-
- res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3_id}")
-
- assert [%{"id" => ^follower2_id}] = json_response_and_validate_schema(res_conn, 200)
-
- assert [link_header] = get_resp_header(res_conn, "link")
- assert link_header =~ ~r/min_id=#{follower2_id}/
- assert link_header =~ ~r/max_id=#{follower2_id}/
- end
- end
-
- describe "following" do
- setup do: oauth_access(["read:accounts"])
-
- test "getting following", %{user: user, conn: conn} do
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn = get(conn, "/api/v1/accounts/#{user.id}/following")
-
- assert [%{"id" => id}] = json_response_and_validate_schema(conn, 200)
- assert id == to_string(other_user.id)
- end
-
- test "getting following, hide_follows, other user requesting" do
- user = insert(:user, hide_follows: true)
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- build_conn()
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"]))
- |> get("/api/v1/accounts/#{user.id}/following")
-
- assert [] == json_response_and_validate_schema(conn, 200)
- end
-
- test "getting following, hide_follows, same user requesting" do
- user = insert(:user, hide_follows: true)
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["read:accounts"]))
- |> get("/api/v1/accounts/#{user.id}/following")
-
- refute [] == json_response_and_validate_schema(conn, 200)
- end
-
- test "getting following, pagination", %{user: user, conn: conn} do
- following1 = insert(:user)
- following2 = insert(:user)
- following3 = insert(:user)
- {:ok, _} = User.follow(user, following1)
- {:ok, _} = User.follow(user, following2)
- {:ok, _} = User.follow(user, following3)
-
- res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}")
-
- assert [%{"id" => id3}, %{"id" => id2}] = json_response_and_validate_schema(res_conn, 200)
- assert id3 == following3.id
- assert id2 == following2.id
-
- res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}")
-
- assert [%{"id" => id2}, %{"id" => id1}] = json_response_and_validate_schema(res_conn, 200)
- assert id2 == following2.id
- assert id1 == following1.id
-
- res_conn =
- get(
- conn,
- "/api/v1/accounts/#{user.id}/following?id=#{user.id}&limit=20&max_id=#{following3.id}"
- )
-
- assert [%{"id" => id2}, %{"id" => id1}] = json_response_and_validate_schema(res_conn, 200)
- assert id2 == following2.id
- assert id1 == following1.id
-
- res_conn =
- get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
-
- assert [%{"id" => id2}] = json_response_and_validate_schema(res_conn, 200)
- assert id2 == following2.id
-
- assert [link_header] = get_resp_header(res_conn, "link")
- assert link_header =~ ~r/min_id=#{following2.id}/
- assert link_header =~ ~r/max_id=#{following2.id}/
- end
- end
-
- describe "follow/unfollow" do
- setup do: oauth_access(["follow"])
-
- test "following / unfollowing a user", %{conn: conn} do
- %{id: other_user_id, nickname: other_user_nickname} = insert(:user)
-
- assert %{"id" => _id, "following" => true} =
- conn
- |> post("/api/v1/accounts/#{other_user_id}/follow")
- |> json_response_and_validate_schema(200)
-
- assert %{"id" => _id, "following" => false} =
- conn
- |> post("/api/v1/accounts/#{other_user_id}/unfollow")
- |> json_response_and_validate_schema(200)
-
- assert %{"id" => ^other_user_id} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/follows", %{"uri" => other_user_nickname})
- |> json_response_and_validate_schema(200)
- end
-
- test "cancelling follow request", %{conn: conn} do
- %{id: other_user_id} = insert(:user, %{locked: true})
-
- assert %{"id" => ^other_user_id, "following" => false, "requested" => true} =
- conn
- |> post("/api/v1/accounts/#{other_user_id}/follow")
- |> json_response_and_validate_schema(:ok)
-
- assert %{"id" => ^other_user_id, "following" => false, "requested" => false} =
- conn
- |> post("/api/v1/accounts/#{other_user_id}/unfollow")
- |> json_response_and_validate_schema(:ok)
- end
-
- test "following without reblogs" do
- %{conn: conn} = oauth_access(["follow", "read:statuses"])
- followed = insert(:user)
- other_user = insert(:user)
-
- ret_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false})
-
- assert %{"showing_reblogs" => false} = json_response_and_validate_schema(ret_conn, 200)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
- {:ok, %{id: reblog_id}} = CommonAPI.repeat(activity.id, followed)
-
- assert [] ==
- conn
- |> get("/api/v1/timelines/home")
- |> json_response(200)
-
- assert %{"showing_reblogs" => true} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: true})
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => ^reblog_id}] =
- conn
- |> get("/api/v1/timelines/home")
- |> json_response(200)
- end
-
- test "following with reblogs" do
- %{conn: conn} = oauth_access(["follow", "read:statuses"])
- followed = insert(:user)
- other_user = insert(:user)
-
- ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow")
-
- assert %{"showing_reblogs" => true} = json_response_and_validate_schema(ret_conn, 200)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
- {:ok, %{id: reblog_id}} = CommonAPI.repeat(activity.id, followed)
-
- assert [%{"id" => ^reblog_id}] =
- conn
- |> get("/api/v1/timelines/home")
- |> json_response(200)
-
- assert %{"showing_reblogs" => false} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false})
- |> json_response_and_validate_schema(200)
-
- assert [] ==
- conn
- |> get("/api/v1/timelines/home")
- |> json_response(200)
- end
-
- test "following / unfollowing errors", %{user: user, conn: conn} do
- # self follow
- conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
-
- assert %{"error" => "Can not follow yourself"} =
- json_response_and_validate_schema(conn_res, 400)
-
- # self unfollow
- user = User.get_cached_by_id(user.id)
- conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow")
-
- assert %{"error" => "Can not unfollow yourself"} =
- json_response_and_validate_schema(conn_res, 400)
-
- # self follow via uri
- user = User.get_cached_by_id(user.id)
-
- assert %{"error" => "Can not follow yourself"} =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v1/follows", %{"uri" => user.nickname})
- |> json_response_and_validate_schema(400)
-
- # follow non existing user
- conn_res = post(conn, "/api/v1/accounts/doesntexist/follow")
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404)
-
- # follow non existing user via uri
- conn_res =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v1/follows", %{"uri" => "doesntexist"})
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404)
-
- # unfollow non existing user
- conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow")
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404)
- end
- end
-
- describe "mute/unmute" do
- setup do: oauth_access(["write:mutes"])
-
- test "with notifications", %{conn: conn} do
- other_user = insert(:user)
-
- assert %{"id" => _id, "muting" => true, "muting_notifications" => true} =
- conn
- |> post("/api/v1/accounts/#{other_user.id}/mute")
- |> json_response_and_validate_schema(200)
-
- conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute")
-
- assert %{"id" => _id, "muting" => false, "muting_notifications" => false} =
- json_response_and_validate_schema(conn, 200)
- end
-
- test "without notifications", %{conn: conn} do
- other_user = insert(:user)
-
- ret_conn =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"})
-
- assert %{"id" => _id, "muting" => true, "muting_notifications" => false} =
- json_response_and_validate_schema(ret_conn, 200)
-
- conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute")
-
- assert %{"id" => _id, "muting" => false, "muting_notifications" => false} =
- json_response_and_validate_schema(conn, 200)
- end
- end
-
- describe "pinned statuses" do
- setup do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "HI!!!"})
- %{conn: conn} = oauth_access(["read:statuses"], user: user)
-
- [conn: conn, user: user, activity: activity]
- end
-
- test "returns pinned statuses", %{conn: conn, user: user, activity: %{id: activity_id}} do
- {:ok, _} = CommonAPI.pin(activity_id, user)
-
- assert [%{"id" => ^activity_id, "pinned" => true}] =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
- |> json_response_and_validate_schema(200)
- end
- end
-
- test "blocking / unblocking a user" do
- %{conn: conn} = oauth_access(["follow"])
- other_user = insert(:user)
-
- ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/block")
-
- assert %{"id" => _id, "blocking" => true} = json_response_and_validate_schema(ret_conn, 200)
-
- conn = post(conn, "/api/v1/accounts/#{other_user.id}/unblock")
-
- assert %{"id" => _id, "blocking" => false} = json_response_and_validate_schema(conn, 200)
- end
-
- describe "create account by app" do
- setup do
- valid_params = %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- agreement: true
- }
-
- [valid_params: valid_params]
- end
-
- test "registers and logs in without :account_activation_required / :account_approval_required",
- %{conn: conn} do
- clear_config([:instance, :account_activation_required], false)
- clear_config([:instance, :account_approval_required], false)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/apps", %{
- client_name: "client_name",
- redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
- scopes: "read, write, follow"
- })
-
- assert %{
- "client_id" => client_id,
- "client_secret" => client_secret,
- "id" => _,
- "name" => "client_name",
- "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
- "vapid_key" => _,
- "website" => nil
- } = json_response_and_validate_schema(conn, 200)
-
- conn =
- post(conn, "/oauth/token", %{
- grant_type: "client_credentials",
- client_id: client_id,
- client_secret: client_secret
- })
-
- assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
- json_response(conn, 200)
-
- assert token
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- assert refresh
- assert scope == "read write follow"
-
- clear_config([User, :email_blacklist], ["example.org"])
-
- params = %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- bio: "Test Bio",
- agreement: true
- }
-
- conn =
- build_conn()
- |> put_req_header("content-type", "multipart/form-data")
- |> put_req_header("authorization", "Bearer " <> token)
- |> post("/api/v1/accounts", params)
-
- assert %{"error" => "{\"email\":[\"Invalid email\"]}"} =
- json_response_and_validate_schema(conn, 400)
-
- Pleroma.Config.put([User, :email_blacklist], [])
-
- conn =
- build_conn()
- |> put_req_header("content-type", "multipart/form-data")
- |> put_req_header("authorization", "Bearer " <> token)
- |> post("/api/v1/accounts", params)
-
- %{
- "access_token" => token,
- "created_at" => _created_at,
- "scope" => ^scope,
- "token_type" => "Bearer"
- } = json_response_and_validate_schema(conn, 200)
-
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- user = Repo.preload(token_from_db, :user).user
-
- assert user
- refute user.confirmation_pending
- refute user.approval_pending
- end
-
- test "registers but does not log in with :account_activation_required", %{conn: conn} do
- clear_config([:instance, :account_activation_required], true)
- clear_config([:instance, :account_approval_required], false)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/apps", %{
- client_name: "client_name",
- redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
- scopes: "read, write, follow"
- })
-
- assert %{
- "client_id" => client_id,
- "client_secret" => client_secret,
- "id" => _,
- "name" => "client_name",
- "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
- "vapid_key" => _,
- "website" => nil
- } = json_response_and_validate_schema(conn, 200)
-
- conn =
- post(conn, "/oauth/token", %{
- grant_type: "client_credentials",
- client_id: client_id,
- client_secret: client_secret
- })
-
- assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
- json_response(conn, 200)
-
- assert token
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- assert refresh
- assert scope == "read write follow"
-
- conn =
- build_conn()
- |> put_req_header("content-type", "multipart/form-data")
- |> put_req_header("authorization", "Bearer " <> token)
- |> post("/api/v1/accounts", %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- bio: "Test Bio",
- agreement: true
- })
-
- response = json_response_and_validate_schema(conn, 200)
- assert %{"identifier" => "missing_confirmed_email"} = response
- refute response["access_token"]
- refute response["token_type"]
-
- user = Repo.get_by(User, email: "lain@example.org")
- assert user.confirmation_pending
- end
-
- test "registers but does not log in with :account_approval_required", %{conn: conn} do
- clear_config([:instance, :account_approval_required], true)
- clear_config([:instance, :account_activation_required], false)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/apps", %{
- client_name: "client_name",
- redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
- scopes: "read, write, follow"
- })
-
- assert %{
- "client_id" => client_id,
- "client_secret" => client_secret,
- "id" => _,
- "name" => "client_name",
- "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
- "vapid_key" => _,
- "website" => nil
- } = json_response_and_validate_schema(conn, 200)
-
- conn =
- post(conn, "/oauth/token", %{
- grant_type: "client_credentials",
- client_id: client_id,
- client_secret: client_secret
- })
-
- assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
- json_response(conn, 200)
-
- assert token
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- assert refresh
- assert scope == "read write follow"
-
- conn =
- build_conn()
- |> put_req_header("content-type", "multipart/form-data")
- |> put_req_header("authorization", "Bearer " <> token)
- |> post("/api/v1/accounts", %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- bio: "Test Bio",
- agreement: true,
- reason: "I'm a cool dude, bro"
- })
-
- response = json_response_and_validate_schema(conn, 200)
- assert %{"identifier" => "awaiting_approval"} = response
- refute response["access_token"]
- refute response["token_type"]
-
- user = Repo.get_by(User, email: "lain@example.org")
-
- assert user.approval_pending
- assert user.registration_reason == "I'm a cool dude, bro"
- 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)
-
- res =
- conn
- |> put_req_header("authorization", "Bearer " <> app_token.token)
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/accounts", valid_params)
-
- assert json_response_and_validate_schema(res, 400) == %{
- "error" => "{\"email\":[\"has already been taken\"]}"
- }
- 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)
- |> put_req_header("content-type", "application/json")
-
- res = post(conn, "/api/v1/accounts", valid_params)
- assert json_response_and_validate_schema(res, 200)
-
- [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
- |> Stream.zip(Map.delete(valid_params, :email))
- |> Enum.each(fn {ip, {attr, _}} ->
- res =
- conn
- |> Map.put(:remote_ip, ip)
- |> post("/api/v1/accounts", Map.delete(valid_params, attr))
- |> json_response_and_validate_schema(400)
-
- assert res == %{
- "error" => "Missing field: #{attr}.",
- "errors" => [
- %{
- "message" => "Missing field: #{attr}",
- "source" => %{"pointer" => "/#{attr}"},
- "title" => "Invalid value"
- }
- ]
- }
- end)
- end
-
- test "returns bad_request if missing email params when :account_activation_required is enabled",
- %{conn: conn, valid_params: valid_params} do
- clear_config([:instance, :account_activation_required], true)
-
- app_token = insert(:oauth_token, user: nil)
-
- conn =
- conn
- |> put_req_header("authorization", "Bearer " <> app_token.token)
- |> put_req_header("content-type", "application/json")
-
- res =
- conn
- |> Map.put(:remote_ip, {127, 0, 0, 5})
- |> post("/api/v1/accounts", Map.delete(valid_params, :email))
-
- assert json_response_and_validate_schema(res, 400) ==
- %{"error" => "Missing parameter: email"}
-
- res =
- conn
- |> Map.put(:remote_ip, {127, 0, 0, 6})
- |> post("/api/v1/accounts", Map.put(valid_params, :email, ""))
-
- assert json_response_and_validate_schema(res, 400) == %{
- "error" => "{\"email\":[\"can't be blank\"]}"
- }
- end
-
- test "allow registration without an email", %{conn: conn, valid_params: valid_params} do
- app_token = insert(:oauth_token, user: nil)
- conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
-
- res =
- conn
- |> put_req_header("content-type", "application/json")
- |> Map.put(:remote_ip, {127, 0, 0, 7})
- |> post("/api/v1/accounts", Map.delete(valid_params, :email))
-
- assert json_response_and_validate_schema(res, 200)
- end
-
- test "allow registration with an empty email", %{conn: conn, valid_params: valid_params} do
- app_token = insert(:oauth_token, user: nil)
- conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
-
- res =
- conn
- |> put_req_header("content-type", "application/json")
- |> Map.put(:remote_ip, {127, 0, 0, 8})
- |> post("/api/v1/accounts", Map.put(valid_params, :email, ""))
-
- assert json_response_and_validate_schema(res, 200)
- end
-
- test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
- res =
- conn
- |> put_req_header("authorization", "Bearer " <> "invalid-token")
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v1/accounts", valid_params)
-
- assert json_response_and_validate_schema(res, 403) == %{"error" => "Invalid credentials"}
- end
-
- test "registration from trusted app" do
- clear_config([Pleroma.Captcha, :enabled], true)
- app = insert(:oauth_app, trusted: true, scopes: ["read", "write", "follow", "push"])
-
- conn =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "client_credentials",
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
-
- assert %{"access_token" => token, "token_type" => "Bearer"} = json_response(conn, 200)
-
- response =
- build_conn()
- |> Plug.Conn.put_req_header("authorization", "Bearer " <> token)
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v1/accounts", %{
- nickname: "nickanme",
- agreement: true,
- email: "email@example.com",
- fullname: "Lain",
- username: "Lain",
- password: "some_password",
- confirm: "some_password"
- })
- |> json_response_and_validate_schema(200)
-
- assert %{
- "access_token" => access_token,
- "created_at" => _,
- "scope" => "read write follow push",
- "token_type" => "Bearer"
- } = response
-
- response =
- build_conn()
- |> Plug.Conn.put_req_header("authorization", "Bearer " <> access_token)
- |> get("/api/v1/accounts/verify_credentials")
- |> json_response_and_validate_schema(200)
-
- assert %{
- "acct" => "Lain",
- "bot" => false,
- "display_name" => "Lain",
- "follow_requests_count" => 0,
- "followers_count" => 0,
- "following_count" => 0,
- "locked" => false,
- "note" => "",
- "source" => %{
- "fields" => [],
- "note" => "",
- "pleroma" => %{
- "actor_type" => "Person",
- "discoverable" => false,
- "no_rich_text" => false,
- "show_role" => true
- },
- "privacy" => "public",
- "sensitive" => false
- },
- "statuses_count" => 0,
- "username" => "Lain"
- } = response
- end
- end
-
- describe "create account by app / rate limit" do
- setup do: clear_config([:rate_limit, :app_account_creation], {10_000, 2})
-
- test "respects rate limit setting", %{conn: conn} do
- app_token = insert(:oauth_token, user: nil)
-
- conn =
- conn
- |> put_req_header("authorization", "Bearer " <> app_token.token)
- |> Map.put(:remote_ip, {15, 15, 15, 15})
- |> put_req_header("content-type", "multipart/form-data")
-
- for i <- 1..2 do
- conn =
- conn
- |> post("/api/v1/accounts", %{
- username: "#{i}lain",
- email: "#{i}lain@example.org",
- password: "PlzDontHackLain",
- agreement: true
- })
-
- %{
- "access_token" => token,
- "created_at" => _created_at,
- "scope" => _scope,
- "token_type" => "Bearer"
- } = json_response_and_validate_schema(conn, 200)
-
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- token_from_db = Repo.preload(token_from_db, :user)
- assert token_from_db.user
- end
-
- conn =
- post(conn, "/api/v1/accounts", %{
- username: "6lain",
- email: "6lain@example.org",
- password: "PlzDontHackLain",
- agreement: true
- })
-
- assert json_response_and_validate_schema(conn, :too_many_requests) == %{
- "error" => "Throttled"
- }
- end
- end
-
- describe "create account with enabled captcha" do
- setup %{conn: conn} do
- app_token = insert(:oauth_token, user: nil)
-
- conn =
- conn
- |> put_req_header("authorization", "Bearer " <> app_token.token)
- |> put_req_header("content-type", "multipart/form-data")
-
- [conn: conn]
- end
-
- setup do: clear_config([Pleroma.Captcha, :enabled], true)
-
- test "creates an account and returns 200 if captcha is valid", %{conn: conn} do
- %{token: token, answer_data: answer_data} = Pleroma.Captcha.new()
-
- params = %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- agreement: true,
- captcha_solution: Pleroma.Captcha.Mock.solution(),
- captcha_token: token,
- captcha_answer_data: answer_data
- }
-
- assert %{
- "access_token" => access_token,
- "created_at" => _,
- "scope" => "read",
- "token_type" => "Bearer"
- } =
- conn
- |> post("/api/v1/accounts", params)
- |> json_response_and_validate_schema(:ok)
-
- assert Token |> Repo.get_by(token: access_token) |> Repo.preload(:user) |> Map.get(:user)
-
- Cachex.del(:used_captcha_cache, token)
- end
-
- test "returns 400 if any captcha field is not provided", %{conn: conn} do
- captcha_fields = [:captcha_solution, :captcha_token, :captcha_answer_data]
-
- valid_params = %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- agreement: true,
- captcha_solution: "xx",
- captcha_token: "xx",
- captcha_answer_data: "xx"
- }
-
- for field <- captcha_fields do
- expected = %{
- "error" => "{\"captcha\":[\"Invalid CAPTCHA (Missing parameter: #{field})\"]}"
- }
-
- assert expected ==
- conn
- |> post("/api/v1/accounts", Map.delete(valid_params, field))
- |> json_response_and_validate_schema(:bad_request)
- end
- end
-
- test "returns an error if captcha is invalid", %{conn: conn} do
- params = %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- agreement: true,
- captcha_solution: "cofe",
- captcha_token: "cofe",
- captcha_answer_data: "cofe"
- }
-
- assert %{"error" => "{\"captcha\":[\"Invalid answer data\"]}"} ==
- conn
- |> post("/api/v1/accounts", params)
- |> json_response_and_validate_schema(:bad_request)
- end
- end
-
- describe "GET /api/v1/accounts/:id/lists - account_lists" do
- test "returns lists to which the account belongs" do
- %{user: user, conn: conn} = oauth_access(["read:lists"])
- other_user = insert(:user)
- assert {:ok, %Pleroma.List{id: list_id} = list} = Pleroma.List.create("Test List", user)
- {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user)
-
- assert [%{"id" => list_id, "title" => "Test List"}] =
- conn
- |> get("/api/v1/accounts/#{other_user.id}/lists")
- |> json_response_and_validate_schema(200)
- end
- end
-
- describe "verify_credentials" do
- test "verify_credentials" do
- %{user: user, conn: conn} = oauth_access(["read:accounts"])
- [notification | _] = insert_list(7, :notification, user: user)
- Pleroma.Notification.set_read_up_to(user, notification.id)
- conn = get(conn, "/api/v1/accounts/verify_credentials")
-
- response = json_response_and_validate_schema(conn, 200)
-
- assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
- assert response["pleroma"]["chat_token"]
- assert response["pleroma"]["unread_notifications_count"] == 6
- assert id == to_string(user.id)
- end
-
- test "verify_credentials default scope unlisted" do
- user = insert(:user, default_scope: "unlisted")
- %{conn: conn} = oauth_access(["read:accounts"], user: user)
-
- conn = get(conn, "/api/v1/accounts/verify_credentials")
-
- assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} =
- json_response_and_validate_schema(conn, 200)
-
- assert id == to_string(user.id)
- end
-
- test "locked accounts" do
- user = insert(:user, default_scope: "private")
- %{conn: conn} = oauth_access(["read:accounts"], user: user)
-
- conn = get(conn, "/api/v1/accounts/verify_credentials")
-
- assert %{"id" => id, "source" => %{"privacy" => "private"}} =
- json_response_and_validate_schema(conn, 200)
-
- assert id == to_string(user.id)
- end
- end
-
- describe "user relationships" do
- setup do: oauth_access(["read:follows"])
-
- test "returns the relationships for the current user", %{user: user, conn: conn} do
- %{id: other_user_id} = other_user = insert(:user)
- {:ok, _user} = User.follow(user, other_user)
-
- assert [%{"id" => ^other_user_id}] =
- conn
- |> get("/api/v1/accounts/relationships?id=#{other_user.id}")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => ^other_user_id}] =
- conn
- |> get("/api/v1/accounts/relationships?id[]=#{other_user.id}")
- |> json_response_and_validate_schema(200)
- end
-
- test "returns an empty list on a bad request", %{conn: conn} do
- conn = get(conn, "/api/v1/accounts/relationships", %{})
-
- assert [] = json_response_and_validate_schema(conn, 200)
- end
- end
-
- test "getting a list of mutes" do
- %{user: user, conn: conn} = oauth_access(["read:mutes"])
- other_user = insert(:user)
-
- {:ok, _user_relationships} = User.mute(user, other_user)
-
- conn = get(conn, "/api/v1/mutes")
-
- other_user_id = to_string(other_user.id)
- assert [%{"id" => ^other_user_id}] = json_response_and_validate_schema(conn, 200)
- end
-
- test "getting a list of blocks" do
- %{user: user, conn: conn} = oauth_access(["read:blocks"])
- other_user = insert(:user)
-
- {:ok, _user_relationship} = User.block(user, other_user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/blocks")
-
- other_user_id = to_string(other_user.id)
- assert [%{"id" => ^other_user_id}] = json_response_and_validate_schema(conn, 200)
- end
-end
diff --git a/test/web/mastodon_api/controllers/app_controller_test.exs b/test/web/mastodon_api/controllers/app_controller_test.exs
deleted file mode 100644
index a0b8b126c..000000000
--- a/test/web/mastodon_api/controllers/app_controller_test.exs
+++ /dev/null
@@ -1,60 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.AppControllerTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Repo
- alias Pleroma.Web.OAuth.App
- alias Pleroma.Web.Push
-
- import Pleroma.Factory
-
- test "apps/verify_credentials", %{conn: conn} do
- token = insert(:oauth_token)
-
- conn =
- conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> get("/api/v1/apps/verify_credentials")
-
- app = Repo.preload(token, :app).app
-
- expected = %{
- "name" => app.client_name,
- "website" => app.website,
- "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
- }
-
- assert expected == json_response_and_validate_schema(conn, 200)
- end
-
- test "creates an oauth app", %{conn: conn} do
- user = insert(:user)
- app_attrs = build(:oauth_app)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> assign(:user, user)
- |> post("/api/v1/apps", %{
- client_name: app_attrs.client_name,
- redirect_uris: app_attrs.redirect_uris
- })
-
- [app] = Repo.all(App)
-
- expected = %{
- "name" => app.client_name,
- "website" => app.website,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret,
- "id" => app.id |> to_string(),
- "redirect_uri" => app.redirect_uris,
- "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
- }
-
- assert expected == json_response_and_validate_schema(conn, 200)
- end
-end
diff --git a/test/web/mastodon_api/controllers/auth_controller_test.exs b/test/web/mastodon_api/controllers/auth_controller_test.exs
deleted file mode 100644
index 4fa95fce1..000000000
--- a/test/web/mastodon_api/controllers/auth_controller_test.exs
+++ /dev/null
@@ -1,162 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.AuthControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Config
- alias Pleroma.Repo
- alias Pleroma.Tests.ObanHelpers
-
- import Pleroma.Factory
- import Swoosh.TestAssertions
-
- describe "GET /web/login" do
- setup %{conn: conn} do
- session_opts = [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session()
-
- test_path = "/web/statuses/test"
- %{conn: conn, path: test_path}
- end
-
- test "redirects to the saved path after log in", %{conn: conn, path: path} do
- app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".")
- auth = insert(:oauth_authorization, app: app)
-
- conn =
- conn
- |> put_session(:return_to, path)
- |> get("/web/login", %{code: auth.token})
-
- assert conn.status == 302
- assert redirected_to(conn) == path
- end
-
- test "redirects to the getting-started page when referer is not present", %{conn: conn} do
- app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".")
- auth = insert(:oauth_authorization, app: app)
-
- conn = get(conn, "/web/login", %{code: auth.token})
-
- assert conn.status == 302
- assert redirected_to(conn) == "/web/getting-started"
- end
- end
-
- describe "POST /auth/password, with valid parameters" do
- setup %{conn: conn} do
- user = insert(:user)
- conn = post(conn, "/auth/password?email=#{user.email}")
- %{conn: conn, user: user}
- end
-
- test "it returns 204", %{conn: conn} do
- assert json_response(conn, :no_content)
- end
-
- test "it creates a PasswordResetToken record for user", %{user: user} do
- token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
- assert token_record
- 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)
- notify_email = Config.get([:instance, :notify_email])
- instance_name = Config.get([:instance, :name])
-
- assert_email_sent(
- from: {instance_name, notify_email},
- to: {user.name, user.email},
- html_body: email.html_body
- )
- end
- end
-
- describe "POST /auth/password, with nickname" do
- test "it returns 204", %{conn: conn} do
- user = insert(:user)
-
- assert conn
- |> post("/auth/password?nickname=#{user.nickname}")
- |> json_response(:no_content)
-
- 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)
- notify_email = Config.get([:instance, :notify_email])
- instance_name = Config.get([:instance, :name])
-
- assert_email_sent(
- from: {instance_name, notify_email},
- to: {user.name, user.email},
- html_body: email.html_body
- )
- end
-
- test "it doesn't fail when a user has no email", %{conn: conn} do
- user = insert(:user, %{email: nil})
-
- assert conn
- |> post("/auth/password?nickname=#{user.nickname}")
- |> json_response(:no_content)
- end
- end
-
- describe "POST /auth/password, with invalid parameters" do
- setup do
- user = insert(:user)
- {:ok, user: user}
- end
-
- test "it returns 204 when user is not found", %{conn: conn, user: user} do
- conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
-
- assert conn
- |> json_response(:no_content)
- end
-
- test "it returns 204 when user is not local", %{conn: conn, user: user} do
- {:ok, user} = Repo.update(Ecto.Changeset.change(user, local: false))
- conn = post(conn, "/auth/password?email=#{user.email}")
-
- assert conn
- |> json_response(:no_content)
- end
-
- test "it returns 204 when user is deactivated", %{conn: conn, user: user} do
- {:ok, user} = Repo.update(Ecto.Changeset.change(user, deactivated: true, local: true))
- conn = post(conn, "/auth/password?email=#{user.email}")
-
- assert conn
- |> json_response(:no_content)
- 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
-end
diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/web/mastodon_api/controllers/conversation_controller_test.exs
deleted file mode 100644
index 3e21e6bf1..000000000
--- a/test/web/mastodon_api/controllers/conversation_controller_test.exs
+++ /dev/null
@@ -1,209 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- setup do: oauth_access(["read:statuses"])
-
- describe "returns a list of conversations" do
- setup(%{user: user_one, conn: conn}) do
- user_two = insert(:user)
- user_three = insert(:user)
-
- {:ok, user_two} = User.follow(user_two, user_one)
-
- {:ok, %{user: user_one, user_two: user_two, user_three: user_three, conn: conn}}
- end
-
- test "returns correct conversations", %{
- user: user_one,
- user_two: user_two,
- user_three: user_three,
- conn: conn
- } do
- assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
- {:ok, direct} = create_direct_message(user_one, [user_two, user_three])
-
- assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
-
- {:ok, _follower_only} =
- CommonAPI.post(user_one, %{
- status: "Hi @#{user_two.nickname}!",
- visibility: "private"
- })
-
- res_conn = get(conn, "/api/v1/conversations")
-
- assert response = json_response_and_validate_schema(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 == false
- assert res_last_status["id"] == direct.id
- assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
- end
-
- test "observes limit params", %{
- user: user_one,
- user_two: user_two,
- user_three: user_three,
- conn: conn
- } do
- {:ok, _} = create_direct_message(user_one, [user_two, user_three])
- {:ok, _} = create_direct_message(user_two, [user_one, user_three])
- {:ok, _} = create_direct_message(user_three, [user_two, user_one])
-
- res_conn = get(conn, "/api/v1/conversations?limit=1")
-
- assert response = json_response_and_validate_schema(res_conn, 200)
-
- assert Enum.count(response) == 1
-
- res_conn = get(conn, "/api/v1/conversations?limit=2")
-
- assert response = json_response_and_validate_schema(res_conn, 200)
-
- assert Enum.count(response) == 2
- end
- end
-
- test "filters conversations by recipients", %{user: user_one, conn: conn} do
- user_two = insert(:user)
- user_three = insert(:user)
- {:ok, direct1} = create_direct_message(user_one, [user_two])
- {:ok, _direct2} = create_direct_message(user_one, [user_three])
- {:ok, direct3} = create_direct_message(user_one, [user_two, user_three])
- {:ok, _direct4} = create_direct_message(user_two, [user_three])
- {:ok, direct5} = create_direct_message(user_two, [user_one])
-
- assert [conversation1, conversation2] =
- conn
- |> get("/api/v1/conversations?recipients[]=#{user_two.id}")
- |> json_response_and_validate_schema(200)
-
- assert conversation1["last_status"]["id"] == direct5.id
- assert conversation2["last_status"]["id"] == direct1.id
-
- [conversation1] =
- conn
- |> get("/api/v1/conversations?recipients[]=#{user_two.id}&recipients[]=#{user_three.id}")
- |> json_response_and_validate_schema(200)
-
- assert conversation1["last_status"]["id"] == direct3.id
- end
-
- test "updates the last_status on reply", %{user: user_one, conn: conn} do
- user_two = insert(:user)
- {:ok, direct} = create_direct_message(user_one, [user_two])
-
- {:ok, direct_reply} =
- CommonAPI.post(user_two, %{
- status: "reply",
- visibility: "direct",
- in_reply_to_status_id: direct.id
- })
-
- [%{"last_status" => res_last_status}] =
- conn
- |> get("/api/v1/conversations")
- |> json_response_and_validate_schema(200)
-
- assert res_last_status["id"] == direct_reply.id
- end
-
- test "the user marks a conversation as read", %{user: user_one, conn: conn} do
- user_two = insert(:user)
- {:ok, direct} = create_direct_message(user_one, [user_two])
-
- assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
- assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
-
- user_two_conn =
- build_conn()
- |> assign(:user, user_two)
- |> assign(
- :token,
- insert(:oauth_token, user: user_two, scopes: ["read:statuses", "write:conversations"])
- )
-
- [%{"id" => direct_conversation_id, "unread" => true}] =
- user_two_conn
- |> get("/api/v1/conversations")
- |> json_response_and_validate_schema(200)
-
- %{"unread" => false} =
- user_two_conn
- |> post("/api/v1/conversations/#{direct_conversation_id}/read")
- |> json_response_and_validate_schema(200)
-
- assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
- assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
-
- # The conversation is marked as unread on reply
- {:ok, _} =
- CommonAPI.post(user_two, %{
- status: "reply",
- visibility: "direct",
- in_reply_to_status_id: direct.id
- })
-
- [%{"unread" => true}] =
- conn
- |> get("/api/v1/conversations")
- |> json_response_and_validate_schema(200)
-
- assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1
- assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
-
- # A reply doesn't increment the user's unread_conversation_count if the conversation is unread
- {:ok, _} =
- CommonAPI.post(user_two, %{
- status: "reply",
- visibility: "direct",
- in_reply_to_status_id: direct.id
- })
-
- assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1
- assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
- end
-
- test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
- user_two = insert(:user)
- {:ok, direct} = create_direct_message(user_one, [user_two])
-
- res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
-
- assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
- end
-
- defp create_direct_message(sender, recips) do
- hellos =
- recips
- |> Enum.map(fn s -> "@#{s.nickname}" end)
- |> Enum.join(", ")
-
- CommonAPI.post(sender, %{
- status: "Hi #{hellos}!",
- visibility: "direct"
- })
- end
-end
diff --git a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs b/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs
deleted file mode 100644
index ab0027f90..000000000
--- a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs
+++ /dev/null
@@ -1,23 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.CustomEmojiControllerTest do
- use Pleroma.Web.ConnCase, async: true
-
- test "with tags", %{conn: conn} do
- assert resp =
- conn
- |> get("/api/v1/custom_emojis")
- |> json_response_and_validate_schema(200)
-
- assert [emoji | _body] = resp
- assert Map.has_key?(emoji, "shortcode")
- assert Map.has_key?(emoji, "static_url")
- assert Map.has_key?(emoji, "tags")
- assert is_list(emoji["tags"])
- assert Map.has_key?(emoji, "category")
- assert Map.has_key?(emoji, "url")
- assert Map.has_key?(emoji, "visible_in_picker")
- 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
deleted file mode 100644
index 664654500..000000000
--- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs
+++ /dev/null
@@ -1,79 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.User
-
- import Pleroma.Factory
-
- test "blocking / unblocking a domain" do
- %{user: user, conn: conn} = oauth_access(["write:blocks"])
- other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
-
- ret_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
-
- assert %{} == json_response_and_validate_schema(ret_conn, 200)
- user = User.get_cached_by_ap_id(user.ap_id)
- assert User.blocks?(user, other_user)
-
- ret_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
-
- assert %{} == json_response_and_validate_schema(ret_conn, 200)
- user = User.get_cached_by_ap_id(user.ap_id)
- refute User.blocks?(user, other_user)
- end
-
- test "blocking a domain via query params" do
- %{user: user, conn: conn} = oauth_access(["write:blocks"])
- other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
-
- ret_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/domain_blocks?domain=dogwhistle.zone")
-
- assert %{} == json_response_and_validate_schema(ret_conn, 200)
- user = User.get_cached_by_ap_id(user.ap_id)
- assert User.blocks?(user, other_user)
- end
-
- test "unblocking a domain via query params" do
- %{user: user, conn: conn} = oauth_access(["write:blocks"])
- other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
-
- User.block_domain(user, "dogwhistle.zone")
- user = refresh_record(user)
- assert User.blocks?(user, other_user)
-
- ret_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> delete("/api/v1/domain_blocks?domain=dogwhistle.zone")
-
- assert %{} == json_response_and_validate_schema(ret_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" do
- %{user: user, conn: conn} = oauth_access(["read:blocks"])
-
- {:ok, user} = User.block_domain(user, "bad.site")
- {:ok, user} = User.block_domain(user, "even.worse.site")
-
- assert ["even.worse.site", "bad.site"] ==
- conn
- |> assign(:user, user)
- |> get("/api/v1/domain_blocks")
- |> json_response_and_validate_schema(200)
- end
-end
diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs
deleted file mode 100644
index 0d426ec34..000000000
--- a/test/web/mastodon_api/controllers/filter_controller_test.exs
+++ /dev/null
@@ -1,152 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Web.MastodonAPI.FilterView
-
- test "creating a filter" do
- %{conn: conn} = oauth_access(["write:filters"])
-
- filter = %Pleroma.Filter{
- phrase: "knights",
- context: ["home"]
- }
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context})
-
- assert response = json_response_and_validate_schema(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" do
- %{user: user, conn: conn} = oauth_access(["read:filters"])
-
- 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
- |> get("/api/v1/filters")
- |> json_response_and_validate_schema(200)
-
- assert response ==
- render_json(
- FilterView,
- "index.json",
- filters: [filter_two, filter_one]
- )
- end
-
- test "get a filter" do
- %{user: user, conn: conn} = oauth_access(["read:filters"])
-
- # check whole_word false
- query = %Pleroma.Filter{
- user_id: user.id,
- filter_id: 2,
- phrase: "knight",
- context: ["home"],
- whole_word: false
- }
-
- {:ok, filter} = Pleroma.Filter.create(query)
-
- conn = get(conn, "/api/v1/filters/#{filter.filter_id}")
-
- assert response = json_response_and_validate_schema(conn, 200)
- assert response["whole_word"] == false
-
- # check whole_word true
- %{user: user, conn: conn} = oauth_access(["read:filters"])
-
- query = %Pleroma.Filter{
- user_id: user.id,
- filter_id: 3,
- phrase: "knight",
- context: ["home"],
- whole_word: true
- }
-
- {:ok, filter} = Pleroma.Filter.create(query)
-
- conn = get(conn, "/api/v1/filters/#{filter.filter_id}")
-
- assert response = json_response_and_validate_schema(conn, 200)
- assert response["whole_word"] == true
- end
-
- test "update a filter" do
- %{user: user, conn: conn} = oauth_access(["write:filters"])
-
- query = %Pleroma.Filter{
- user_id: user.id,
- filter_id: 2,
- phrase: "knight",
- context: ["home"],
- hide: true,
- whole_word: true
- }
-
- {:ok, _filter} = Pleroma.Filter.create(query)
-
- new = %Pleroma.Filter{
- phrase: "nii",
- context: ["home"]
- }
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/v1/filters/#{query.filter_id}", %{
- phrase: new.phrase,
- context: new.context
- })
-
- assert response = json_response_and_validate_schema(conn, 200)
- assert response["phrase"] == new.phrase
- assert response["context"] == new.context
- assert response["irreversible"] == true
- assert response["whole_word"] == true
- end
-
- test "delete a filter" do
- %{user: user, conn: conn} = oauth_access(["write:filters"])
-
- query = %Pleroma.Filter{
- user_id: user.id,
- filter_id: 2,
- phrase: "knight",
- context: ["home"]
- }
-
- {:ok, filter} = Pleroma.Filter.create(query)
-
- conn = delete(conn, "/api/v1/filters/#{filter.filter_id}")
-
- assert json_response_and_validate_schema(conn, 200) == %{}
- 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
deleted file mode 100644
index 6749e0e83..000000000
--- a/test/web/mastodon_api/controllers/follow_request_controller_test.exs
+++ /dev/null
@@ -1,74 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "locked accounts" do
- setup do
- user = insert(:user, locked: true)
- %{conn: conn} = oauth_access(["follow"], user: user)
- %{user: user, conn: conn}
- end
-
- test "/api/v1/follow_requests works", %{user: user, conn: conn} do
- other_user = insert(:user)
-
- {:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
- {:ok, other_user} = User.follow(other_user, user, :follow_pending)
-
- assert User.following?(other_user, user) == false
-
- conn = get(conn, "/api/v1/follow_requests")
-
- assert [relationship] = json_response_and_validate_schema(conn, 200)
- assert to_string(other_user.id) == relationship["id"]
- end
-
- test "/api/v1/follow_requests/:id/authorize works", %{user: user, conn: conn} do
- other_user = insert(:user)
-
- {:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
- {:ok, other_user} = User.follow(other_user, user, :follow_pending)
-
- user = User.get_cached_by_id(user.id)
- other_user = User.get_cached_by_id(other_user.id)
-
- assert User.following?(other_user, user) == false
-
- conn = post(conn, "/api/v1/follow_requests/#{other_user.id}/authorize")
-
- assert relationship = json_response_and_validate_schema(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", %{user: user, conn: conn} do
- other_user = insert(:user)
-
- {:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
-
- user = User.get_cached_by_id(user.id)
-
- conn = post(conn, "/api/v1/follow_requests/#{other_user.id}/reject")
-
- assert relationship = json_response_and_validate_schema(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/instance_controller_test.exs b/test/web/mastodon_api/controllers/instance_controller_test.exs
deleted file mode 100644
index 6a9ccd979..000000000
--- a/test/web/mastodon_api/controllers/instance_controller_test.exs
+++ /dev/null
@@ -1,87 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.User
- import Pleroma.Factory
-
- test "get instance information", %{conn: conn} do
- conn = get(conn, "/api/v1/instance")
- assert result = json_response_and_validate_schema(conn, 200)
-
- email = Pleroma.Config.get([:instance, :email])
- # Note: not checking for "max_toot_chars" since it's optional
- assert %{
- "uri" => _,
- "title" => _,
- "description" => _,
- "version" => _,
- "email" => from_config_email,
- "urls" => %{
- "streaming_api" => _
- },
- "stats" => _,
- "thumbnail" => _,
- "languages" => _,
- "registrations" => _,
- "approval_required" => _,
- "poll_limits" => _,
- "upload_limit" => _,
- "avatar_upload_limit" => _,
- "background_upload_limit" => _,
- "banner_upload_limit" => _,
- "background_image" => _,
- "chat_limit" => _,
- "description_limit" => _
- } = result
-
- assert result["pleroma"]["metadata"]["account_activation_required"] != nil
- assert result["pleroma"]["metadata"]["features"]
- assert result["pleroma"]["metadata"]["federation"]
- assert result["pleroma"]["metadata"]["fields_limits"]
- assert result["pleroma"]["vapid_public_key"]
-
- assert email == from_config_email
- end
-
- test "get instance stats", %{conn: conn} do
- user = insert(:user, %{local: true})
-
- user2 = insert(:user, %{local: true})
- {:ok, _user2} = User.deactivate(user2, !user2.deactivated)
-
- insert(:user, %{local: false, nickname: "u@peer1.com"})
- insert(:user, %{local: false, nickname: "u@peer2.com"})
-
- {:ok, _} = Pleroma.Web.CommonAPI.post(user, %{status: "cofe"})
-
- Pleroma.Stats.force_update()
-
- conn = get(conn, "/api/v1/instance")
-
- assert result = json_response_and_validate_schema(conn, 200)
-
- stats = result["stats"]
-
- assert stats
- assert stats["user_count"] == 1
- assert stats["status_count"] == 1
- assert stats["domain_count"] == 2
- end
-
- test "get peers", %{conn: conn} do
- insert(:user, %{local: false, nickname: "u@peer1.com"})
- insert(:user, %{local: false, nickname: "u@peer2.com"})
-
- Pleroma.Stats.force_update()
-
- conn = get(conn, "/api/v1/instance/peers")
-
- assert result = json_response_and_validate_schema(conn, 200)
-
- assert ["peer1.com", "peer2.com"] == Enum.sort(result)
- end
-end
diff --git a/test/web/mastodon_api/controllers/list_controller_test.exs b/test/web/mastodon_api/controllers/list_controller_test.exs
deleted file mode 100644
index 57a9ef4a4..000000000
--- a/test/web/mastodon_api/controllers/list_controller_test.exs
+++ /dev/null
@@ -1,158 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ListControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Repo
-
- import Pleroma.Factory
-
- test "creating a list" do
- %{conn: conn} = oauth_access(["write:lists"])
-
- assert %{"title" => "cuties"} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/lists", %{"title" => "cuties"})
- |> json_response_and_validate_schema(:ok)
- end
-
- test "renders error for invalid params" do
- %{conn: conn} = oauth_access(["write:lists"])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/lists", %{"title" => nil})
-
- assert %{"error" => "title - null value where string expected."} =
- json_response_and_validate_schema(conn, 400)
- end
-
- test "listing a user's lists" do
- %{conn: conn} = oauth_access(["read:lists", "write:lists"])
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/lists", %{"title" => "cuties"})
- |> json_response_and_validate_schema(:ok)
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/lists", %{"title" => "cofe"})
- |> json_response_and_validate_schema(:ok)
-
- conn = get(conn, "/api/v1/lists")
-
- assert [
- %{"id" => _, "title" => "cofe"},
- %{"id" => _, "title" => "cuties"}
- ] = json_response_and_validate_schema(conn, :ok)
- end
-
- test "adding users to a list" do
- %{user: user, conn: conn} = oauth_access(["write:lists"])
- other_user = insert(:user)
- {:ok, list} = Pleroma.List.create("name", user)
-
- assert %{} ==
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
- |> json_response_and_validate_schema(:ok)
-
- %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
- assert following == [other_user.follower_address]
- end
-
- test "removing users from a list" do
- %{user: user, conn: conn} = oauth_access(["write:lists"])
- other_user = insert(:user)
- third_user = insert(:user)
- {:ok, list} = Pleroma.List.create("name", user)
- {:ok, list} = Pleroma.List.follow(list, other_user)
- {:ok, list} = Pleroma.List.follow(list, third_user)
-
- assert %{} ==
- conn
- |> put_req_header("content-type", "application/json")
- |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
- |> json_response_and_validate_schema(:ok)
-
- %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
- assert following == [third_user.follower_address]
- end
-
- test "listing users in a list" do
- %{user: user, conn: conn} = oauth_access(["read:lists"])
- other_user = insert(:user)
- {:ok, list} = Pleroma.List.create("name", user)
- {:ok, list} = Pleroma.List.follow(list, other_user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
-
- assert [%{"id" => id}] = json_response_and_validate_schema(conn, 200)
- assert id == to_string(other_user.id)
- end
-
- test "retrieving a list" do
- %{user: user, conn: conn} = oauth_access(["read:lists"])
- {:ok, list} = Pleroma.List.create("name", user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/lists/#{list.id}")
-
- assert %{"id" => id} = json_response_and_validate_schema(conn, 200)
- assert id == to_string(list.id)
- end
-
- test "renders 404 if list is not found" do
- %{conn: conn} = oauth_access(["read:lists"])
-
- conn = get(conn, "/api/v1/lists/666")
-
- assert %{"error" => "List not found"} = json_response_and_validate_schema(conn, :not_found)
- end
-
- test "renaming a list" do
- %{user: user, conn: conn} = oauth_access(["write:lists"])
- {:ok, list} = Pleroma.List.create("name", user)
-
- assert %{"title" => "newname"} =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"})
- |> json_response_and_validate_schema(:ok)
- end
-
- test "validates title when renaming a list" do
- %{user: user, conn: conn} = oauth_access(["write:lists"])
- {:ok, list} = Pleroma.List.create("name", user)
-
- conn =
- conn
- |> assign(:user, user)
- |> put_req_header("content-type", "application/json")
- |> put("/api/v1/lists/#{list.id}", %{"title" => " "})
-
- assert %{"error" => "can't be blank"} ==
- json_response_and_validate_schema(conn, :unprocessable_entity)
- end
-
- test "deleting a list" do
- %{user: user, conn: conn} = oauth_access(["write:lists"])
- {:ok, list} = Pleroma.List.create("name", user)
-
- conn = delete(conn, "/api/v1/lists/#{list.id}")
-
- assert %{} = json_response_and_validate_schema(conn, 200)
- assert is_nil(Repo.get(Pleroma.List, list.id))
- end
-end
diff --git a/test/web/mastodon_api/controllers/marker_controller_test.exs b/test/web/mastodon_api/controllers/marker_controller_test.exs
deleted file mode 100644
index 6dd40fb4a..000000000
--- a/test/web/mastodon_api/controllers/marker_controller_test.exs
+++ /dev/null
@@ -1,131 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- describe "GET /api/v1/markers" do
- test "gets markers with correct scopes", %{conn: conn} do
- user = insert(:user)
- token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
- insert_list(7, :notification, user: user)
-
- {:ok, %{"notifications" => marker}} =
- Pleroma.Marker.upsert(
- user,
- %{"notifications" => %{"last_read_id" => "69420"}}
- )
-
- response =
- conn
- |> assign(:user, user)
- |> assign(:token, token)
- |> get("/api/v1/markers?timeline[]=notifications")
- |> json_response_and_validate_schema(200)
-
- assert response == %{
- "notifications" => %{
- "last_read_id" => "69420",
- "updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
- "version" => 0,
- "pleroma" => %{"unread_count" => 7}
- }
- }
- end
-
- test "gets markers with missed scopes", %{conn: conn} do
- user = insert(:user)
- token = insert(:oauth_token, user: user, scopes: [])
-
- Pleroma.Marker.upsert(user, %{"notifications" => %{"last_read_id" => "69420"}})
-
- response =
- conn
- |> assign(:user, user)
- |> assign(:token, token)
- |> get("/api/v1/markers", %{timeline: ["notifications"]})
- |> json_response_and_validate_schema(403)
-
- assert response == %{"error" => "Insufficient permissions: read:statuses."}
- end
- end
-
- describe "POST /api/v1/markers" do
- test "creates a marker with correct scopes", %{conn: conn} do
- user = insert(:user)
- token = insert(:oauth_token, user: user, scopes: ["write:statuses"])
-
- response =
- conn
- |> assign(:user, user)
- |> assign(:token, token)
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/markers", %{
- home: %{last_read_id: "777"},
- notifications: %{"last_read_id" => "69420"}
- })
- |> json_response_and_validate_schema(200)
-
- assert %{
- "notifications" => %{
- "last_read_id" => "69420",
- "updated_at" => _,
- "version" => 0,
- "pleroma" => %{"unread_count" => 0}
- }
- } = response
- end
-
- test "updates exist marker", %{conn: conn} do
- user = insert(:user)
- token = insert(:oauth_token, user: user, scopes: ["write:statuses"])
-
- {:ok, %{"notifications" => marker}} =
- Pleroma.Marker.upsert(
- user,
- %{"notifications" => %{"last_read_id" => "69477"}}
- )
-
- response =
- conn
- |> assign(:user, user)
- |> assign(:token, token)
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/markers", %{
- home: %{last_read_id: "777"},
- notifications: %{"last_read_id" => "69888"}
- })
- |> json_response_and_validate_schema(200)
-
- assert response == %{
- "notifications" => %{
- "last_read_id" => "69888",
- "updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
- "version" => 0,
- "pleroma" => %{"unread_count" => 0}
- }
- }
- end
-
- test "creates a marker with missed scopes", %{conn: conn} do
- user = insert(:user)
- token = insert(:oauth_token, user: user, scopes: [])
-
- response =
- conn
- |> assign(:user, user)
- |> assign(:token, token)
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/markers", %{
- home: %{last_read_id: "777"},
- notifications: %{"last_read_id" => "69420"}
- })
- |> json_response_and_validate_schema(403)
-
- assert response == %{"error" => "Insufficient permissions: write:statuses."}
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/media_controller_test.exs b/test/web/mastodon_api/controllers/media_controller_test.exs
deleted file mode 100644
index 906fd940f..000000000
--- a/test/web/mastodon_api/controllers/media_controller_test.exs
+++ /dev/null
@@ -1,146 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
-
- describe "Upload media" do
- setup do: oauth_access(["write:media"])
-
- setup do
- image = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- [image: image]
- end
-
- setup do: clear_config([:media_proxy])
- setup do: clear_config([Pleroma.Upload])
-
- test "/api/v1/media", %{conn: conn, image: image} do
- desc = "Description of the image"
-
- media =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v1/media", %{"file" => image, "description" => desc})
- |> json_response_and_validate_schema(:ok)
-
- assert media["type"] == "image"
- assert media["description"] == desc
- assert media["id"]
-
- object = Object.get_by_id(media["id"])
- assert object.data["actor"] == User.ap_id(conn.assigns[:user])
- end
-
- test "/api/v2/media", %{conn: conn, user: user, image: image} do
- desc = "Description of the image"
-
- response =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/v2/media", %{"file" => image, "description" => desc})
- |> json_response_and_validate_schema(202)
-
- assert media_id = response["id"]
-
- %{conn: conn} = oauth_access(["read:media"], user: user)
-
- media =
- conn
- |> get("/api/v1/media/#{media_id}")
- |> json_response_and_validate_schema(200)
-
- assert media["type"] == "image"
- assert media["description"] == desc
- assert media["id"]
-
- object = Object.get_by_id(media["id"])
- assert object.data["actor"] == user.ap_id
- end
- end
-
- describe "Update media description" do
- setup do: oauth_access(["write:media"])
-
- setup %{user: actor} do
- 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"
- )
-
- [object: object]
- end
-
- test "/api/v1/media/:id good request", %{conn: conn, object: object} do
- media =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> put("/api/v1/media/#{object.id}", %{"description" => "test-media"})
- |> json_response_and_validate_schema(:ok)
-
- assert media["description"] == "test-media"
- assert refresh_record(object).data["name"] == "test-media"
- end
- end
-
- describe "Get media by id (/api/v1/media/:id)" do
- setup do: oauth_access(["read:media"])
-
- setup %{user: actor} do
- 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-media"
- )
-
- [object: object]
- end
-
- test "it returns media object when requested by owner", %{conn: conn, object: object} do
- media =
- conn
- |> get("/api/v1/media/#{object.id}")
- |> json_response_and_validate_schema(:ok)
-
- assert media["description"] == "test-media"
- assert media["type"] == "image"
- assert media["id"]
- end
-
- test "it returns 403 if media object requested by non-owner", %{object: object, user: user} do
- %{conn: conn, user: other_user} = oauth_access(["read:media"])
-
- assert object.data["actor"] == user.ap_id
- refute user.id == other_user.id
-
- conn
- |> get("/api/v1/media/#{object.id}")
- |> json_response(403)
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs
deleted file mode 100644
index 70ef0e8b5..000000000
--- a/test/web/mastodon_api/controllers/notification_controller_test.exs
+++ /dev/null
@@ -1,626 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Notification
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "does NOT render account/pleroma/relationship by default" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
- {:ok, [_notification]} = Notification.create_notifications(activity)
-
- response =
- conn
- |> assign(:user, user)
- |> get("/api/v1/notifications")
- |> json_response_and_validate_schema(200)
-
- assert Enum.all?(response, fn n ->
- get_in(n, ["account", "pleroma", "relationship"]) == %{}
- end)
- end
-
- test "list of notifications" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- 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 class=\"u-url mention\" data-user=\"#{user.id}\" href=\"#{
- user.ap_id
- }\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>"
-
- assert [%{"status" => %{"content" => response}} | _rest] =
- json_response_and_validate_schema(conn, 200)
-
- assert response == expected_response
- end
-
- test "by default, does not contain pleroma:chat_mention" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- other_user = insert(:user)
-
- {:ok, _activity} = CommonAPI.post_chat_message(other_user, user, "hey")
-
- result =
- conn
- |> get("/api/v1/notifications")
- |> json_response_and_validate_schema(200)
-
- assert [] == result
-
- result =
- conn
- |> get("/api/v1/notifications?include_types[]=pleroma:chat_mention")
- |> json_response_and_validate_schema(200)
-
- assert [_] = result
- end
-
- test "getting a single notification" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
-
- {:ok, [notification]} = Notification.create_notifications(activity)
-
- conn = get(conn, "/api/v1/notifications/#{notification.id}")
-
- expected_response =
- "hi <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{user.id}\" href=\"#{
- user.ap_id
- }\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>"
-
- assert %{"status" => %{"content" => response}} = json_response_and_validate_schema(conn, 200)
- assert response == expected_response
- end
-
- test "dismissing a single notification (deprecated endpoint)" do
- %{user: user, conn: conn} = oauth_access(["write:notifications"])
- 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)
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/notifications/dismiss", %{"id" => to_string(notification.id)})
-
- assert %{} = json_response_and_validate_schema(conn, 200)
- end
-
- test "dismissing a single notification" do
- %{user: user, conn: conn} = oauth_access(["write:notifications"])
- 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/#{notification.id}/dismiss")
-
- assert %{} = json_response_and_validate_schema(conn, 200)
- end
-
- test "clearing all notifications" do
- %{user: user, conn: conn} = oauth_access(["write:notifications", "read:notifications"])
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
-
- {:ok, [_notification]} = Notification.create_notifications(activity)
-
- ret_conn = post(conn, "/api/v1/notifications/clear")
-
- assert %{} = json_response_and_validate_schema(ret_conn, 200)
-
- ret_conn = get(conn, "/api/v1/notifications")
-
- assert all = json_response_and_validate_schema(ret_conn, 200)
- assert all == []
- end
-
- test "paginates notifications using min_id, since_id, max_id, and limit" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- 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_and_validate_schema(: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_and_validate_schema(: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_and_validate_schema(:ok)
-
- assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
- end
-
- describe "exclude_visibilities" do
- test "filters notifications for mentions" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- other_user = insert(:user)
-
- {:ok, public_activity} =
- CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "public"})
-
- {:ok, direct_activity} =
- CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "direct"})
-
- {:ok, unlisted_activity} =
- CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "unlisted"})
-
- {:ok, private_activity} =
- CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "private"})
-
- query = params_to_query(%{exclude_visibilities: ["public", "unlisted", "private"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
- assert id == direct_activity.id
-
- query = params_to_query(%{exclude_visibilities: ["public", "unlisted", "direct"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
- assert id == private_activity.id
-
- query = params_to_query(%{exclude_visibilities: ["public", "private", "direct"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
- assert id == unlisted_activity.id
-
- query = params_to_query(%{exclude_visibilities: ["unlisted", "private", "direct"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
- assert id == public_activity.id
- end
-
- test "filters notifications for Like activities" do
- user = insert(:user)
- %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
-
- {:ok, public_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "public"})
-
- {:ok, direct_activity} =
- CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "direct"})
-
- {:ok, unlisted_activity} =
- CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"})
-
- {:ok, private_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "private"})
-
- {:ok, _} = CommonAPI.favorite(user, public_activity.id)
- {:ok, _} = CommonAPI.favorite(user, direct_activity.id)
- {:ok, _} = CommonAPI.favorite(user, unlisted_activity.id)
- {:ok, _} = CommonAPI.favorite(user, private_activity.id)
-
- activity_ids =
- conn
- |> get("/api/v1/notifications?exclude_visibilities[]=direct")
- |> json_response_and_validate_schema(200)
- |> Enum.map(& &1["status"]["id"])
-
- assert public_activity.id in activity_ids
- assert unlisted_activity.id in activity_ids
- assert private_activity.id in activity_ids
- refute direct_activity.id in activity_ids
-
- activity_ids =
- conn
- |> get("/api/v1/notifications?exclude_visibilities[]=unlisted")
- |> json_response_and_validate_schema(200)
- |> Enum.map(& &1["status"]["id"])
-
- assert public_activity.id in activity_ids
- refute unlisted_activity.id in activity_ids
- assert private_activity.id in activity_ids
- assert direct_activity.id in activity_ids
-
- activity_ids =
- conn
- |> get("/api/v1/notifications?exclude_visibilities[]=private")
- |> json_response_and_validate_schema(200)
- |> Enum.map(& &1["status"]["id"])
-
- assert public_activity.id in activity_ids
- assert unlisted_activity.id in activity_ids
- refute private_activity.id in activity_ids
- assert direct_activity.id in activity_ids
-
- activity_ids =
- conn
- |> get("/api/v1/notifications?exclude_visibilities[]=public")
- |> json_response_and_validate_schema(200)
- |> Enum.map(& &1["status"]["id"])
-
- refute public_activity.id in activity_ids
- assert unlisted_activity.id in activity_ids
- assert private_activity.id in activity_ids
- assert direct_activity.id in activity_ids
- end
-
- test "filters notifications for Announce activities" do
- user = insert(:user)
- %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
-
- {:ok, public_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "public"})
-
- {:ok, unlisted_activity} =
- CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"})
-
- {:ok, _} = CommonAPI.repeat(public_activity.id, user)
- {:ok, _} = CommonAPI.repeat(unlisted_activity.id, user)
-
- activity_ids =
- conn
- |> get("/api/v1/notifications?exclude_visibilities[]=unlisted")
- |> json_response_and_validate_schema(200)
- |> Enum.map(& &1["status"]["id"])
-
- assert public_activity.id in activity_ids
- refute unlisted_activity.id in activity_ids
- end
-
- test "doesn't return less than the requested amount of records when the user's reply is liked" do
- user = insert(:user)
- %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
-
- {:ok, mention} =
- CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "public"})
-
- {:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
-
- {:ok, reply} =
- CommonAPI.post(other_user, %{
- status: ".",
- visibility: "public",
- in_reply_to_status_id: activity.id
- })
-
- {:ok, _favorite} = CommonAPI.favorite(user, reply.id)
-
- activity_ids =
- conn
- |> get("/api/v1/notifications?exclude_visibilities[]=direct&limit=2")
- |> json_response_and_validate_schema(200)
- |> Enum.map(& &1["status"]["id"])
-
- assert [reply.id, mention.id] == activity_ids
- end
- end
-
- test "filters notifications using exclude_types" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- 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(other_user, create_activity.id)
- {: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)
-
- query = params_to_query(%{exclude_types: ["mention", "favourite", "reblog"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
-
- query = params_to_query(%{exclude_types: ["favourite", "reblog", "follow"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"id" => ^mention_notification_id}] =
- json_response_and_validate_schema(conn_res, 200)
-
- query = params_to_query(%{exclude_types: ["reblog", "follow", "mention"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"id" => ^favorite_notification_id}] =
- json_response_and_validate_schema(conn_res, 200)
-
- query = params_to_query(%{exclude_types: ["follow", "mention", "favourite"]})
- conn_res = get(conn, "/api/v1/notifications?" <> query)
-
- assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
- end
-
- test "filters notifications using include_types" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- 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(other_user, create_activity.id)
- {: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_res = get(conn, "/api/v1/notifications?include_types[]=follow")
-
- assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
-
- conn_res = get(conn, "/api/v1/notifications?include_types[]=mention")
-
- assert [%{"id" => ^mention_notification_id}] =
- json_response_and_validate_schema(conn_res, 200)
-
- conn_res = get(conn, "/api/v1/notifications?include_types[]=favourite")
-
- assert [%{"id" => ^favorite_notification_id}] =
- json_response_and_validate_schema(conn_res, 200)
-
- conn_res = get(conn, "/api/v1/notifications?include_types[]=reblog")
-
- assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
-
- result = conn |> get("/api/v1/notifications") |> json_response_and_validate_schema(200)
-
- assert length(result) == 4
-
- query = params_to_query(%{include_types: ["follow", "mention", "favourite", "reblog"]})
-
- result =
- conn
- |> get("/api/v1/notifications?" <> query)
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 4
- end
-
- test "destroy multiple" do
- %{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
- 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)
-
- result =
- conn
- |> get("/api/v1/notifications")
- |> json_response_and_validate_schema(:ok)
-
- assert [%{"id" => ^notification2_id}, %{"id" => ^notification1_id}] = result
-
- conn2 =
- conn
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:notifications"]))
-
- result =
- conn2
- |> get("/api/v1/notifications")
- |> json_response_and_validate_schema(:ok)
-
- assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
-
- query = params_to_query(%{ids: [notification1_id, notification2_id]})
- conn_destroy = delete(conn, "/api/v1/notifications/destroy_multiple?" <> query)
-
- assert json_response_and_validate_schema(conn_destroy, 200) == %{}
-
- result =
- conn2
- |> get("/api/v1/notifications")
- |> json_response_and_validate_schema(:ok)
-
- assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
- end
-
- test "doesn't see notifications after muting user with notifications" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- user2 = insert(:user)
-
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
- {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
-
- ret_conn = get(conn, "/api/v1/notifications")
-
- assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
-
- {:ok, _user_relationships} = User.mute(user, user2)
-
- conn = get(conn, "/api/v1/notifications")
-
- assert json_response_and_validate_schema(conn, 200) == []
- end
-
- test "see notifications after muting user without notifications" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- user2 = insert(:user)
-
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
- {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
-
- ret_conn = get(conn, "/api/v1/notifications")
-
- assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
-
- {:ok, _user_relationships} = User.mute(user, user2, false)
-
- conn = get(conn, "/api/v1/notifications")
-
- assert length(json_response_and_validate_schema(conn, 200)) == 1
- end
-
- test "see notifications after muting user with notifications and with_muted parameter" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- user2 = insert(:user)
-
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
- {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
-
- ret_conn = get(conn, "/api/v1/notifications")
-
- assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
-
- {:ok, _user_relationships} = User.mute(user, user2)
-
- conn = get(conn, "/api/v1/notifications?with_muted=true")
-
- assert length(json_response_and_validate_schema(conn, 200)) == 1
- end
-
- @tag capture_log: true
- test "see move notifications" do
- old_user = insert(:user)
- new_user = insert(:user, also_known_as: [old_user.ap_id])
- %{user: follower, conn: conn} = oauth_access(["read:notifications"])
-
- old_user_url = old_user.ap_id
-
- body =
- File.read!("test/fixtures/users_mock/localhost.json")
- |> String.replace("{{nickname}}", old_user.nickname)
- |> Jason.encode!()
-
- Tesla.Mock.mock(fn
- %{method: :get, url: ^old_user_url} ->
- %Tesla.Env{status: 200, body: body}
- end)
-
- User.follow(follower, old_user)
- Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
- Pleroma.Tests.ObanHelpers.perform_all()
-
- conn = get(conn, "/api/v1/notifications")
-
- assert length(json_response_and_validate_schema(conn, 200)) == 1
- end
-
- describe "link headers" do
- test "preserves parameters in link headers" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
- other_user = insert(:user)
-
- {:ok, activity1} =
- CommonAPI.post(other_user, %{
- status: "hi @#{user.nickname}",
- visibility: "public"
- })
-
- {:ok, activity2} =
- CommonAPI.post(other_user, %{
- status: "hi @#{user.nickname}",
- visibility: "public"
- })
-
- notification1 = Repo.get_by(Notification, activity_id: activity1.id)
- notification2 = Repo.get_by(Notification, activity_id: activity2.id)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/notifications?limit=5")
-
- assert [link_header] = get_resp_header(conn, "link")
- assert link_header =~ ~r/limit=5/
- assert link_header =~ ~r/min_id=#{notification2.id}/
- assert link_header =~ ~r/max_id=#{notification1.id}/
- end
- end
-
- describe "from specified user" do
- test "account_id" do
- %{user: user, conn: conn} = oauth_access(["read:notifications"])
-
- %{id: account_id} = other_user1 = insert(:user)
- other_user2 = insert(:user)
-
- {:ok, _activity} = CommonAPI.post(other_user1, %{status: "hi @#{user.nickname}"})
- {:ok, _activity} = CommonAPI.post(other_user2, %{status: "bye @#{user.nickname}"})
-
- assert [%{"account" => %{"id" => ^account_id}}] =
- conn
- |> assign(:user, user)
- |> get("/api/v1/notifications?account_id=#{account_id}")
- |> json_response_and_validate_schema(200)
-
- assert %{"error" => "Account is not found"} =
- conn
- |> assign(:user, user)
- |> get("/api/v1/notifications?account_id=cofe")
- |> json_response_and_validate_schema(404)
- end
- end
-
- defp get_notification_id_by_activity(%{id: id}) do
- Notification
- |> Repo.get_by(activity_id: id)
- |> Map.get(:id)
- |> to_string()
- end
-
- defp params_to_query(%{} = params) do
- Enum.map_join(params, "&", fn
- {k, v} when is_list(v) -> Enum.map_join(v, "&", &"#{k}[]=#{&1}")
- {k, v} -> k <> "=" <> v
- end)
- end
-end
diff --git a/test/web/mastodon_api/controllers/poll_controller_test.exs b/test/web/mastodon_api/controllers/poll_controller_test.exs
deleted file mode 100644
index f41de6448..000000000
--- a/test/web/mastodon_api/controllers/poll_controller_test.exs
+++ /dev/null
@@ -1,171 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Object
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "GET /api/v1/polls/:id" do
- setup do: oauth_access(["read:statuses"])
-
- test "returns poll entity for object id", %{user: user, conn: conn} do
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Pleroma does",
- poll: %{options: ["what Mastodon't", "n't what Mastodoes"], expires_in: 20}
- })
-
- object = Object.normalize(activity)
-
- conn = get(conn, "/api/v1/polls/#{object.id}")
-
- response = json_response_and_validate_schema(conn, 200)
- id = to_string(object.id)
- assert %{"id" => ^id, "expired" => false, "multiple" => false} = response
- end
-
- test "does not expose polls for private statuses", %{conn: conn} do
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(other_user, %{
- status: "Pleroma does",
- poll: %{options: ["what Mastodon't", "n't what Mastodoes"], expires_in: 20},
- visibility: "private"
- })
-
- object = Object.normalize(activity)
-
- conn = get(conn, "/api/v1/polls/#{object.id}")
-
- assert json_response_and_validate_schema(conn, 404)
- end
- end
-
- describe "POST /api/v1/polls/:id/votes" do
- setup do: oauth_access(["write:statuses"])
-
- test "votes are added to the poll", %{conn: conn} do
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(other_user, %{
- status: "A very delicious sandwich",
- poll: %{
- options: ["Lettuce", "Grilled Bacon", "Tomato"],
- expires_in: 20,
- multiple: true
- }
- })
-
- object = Object.normalize(activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1, 2]})
-
- assert json_response_and_validate_schema(conn, 200)
- object = Object.get_by_id(object.id)
-
- assert Enum.all?(object.data["anyOf"], fn %{"replies" => %{"totalItems" => total_items}} ->
- total_items == 1
- end)
- end
-
- test "author can't vote", %{user: user, conn: conn} do
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Am I cute?",
- poll: %{options: ["Yes", "No"], expires_in: 20}
- })
-
- object = Object.normalize(activity)
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [1]})
- |> json_response_and_validate_schema(422) == %{"error" => "Poll's author can't vote"}
-
- object = Object.get_by_id(object.id)
-
- refute Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 1
- end
-
- test "does not allow multiple choices on a single-choice question", %{conn: conn} do
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(other_user, %{
- status: "The glass is",
- poll: %{options: ["half empty", "half full"], expires_in: 20}
- })
-
- object = Object.normalize(activity)
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1]})
- |> json_response_and_validate_schema(422) == %{"error" => "Too many choices"}
-
- object = Object.get_by_id(object.id)
-
- refute Enum.any?(object.data["oneOf"], fn %{"replies" => %{"totalItems" => total_items}} ->
- total_items == 1
- end)
- end
-
- test "does not allow choice index to be greater than options count", %{conn: conn} do
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(other_user, %{
- status: "Am I cute?",
- poll: %{options: ["Yes", "No"], expires_in: 20}
- })
-
- object = Object.normalize(activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [2]})
-
- assert json_response_and_validate_schema(conn, 422) == %{"error" => "Invalid indices"}
- end
-
- test "returns 404 error when object is not exist", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/polls/1/votes", %{"choices" => [0]})
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
-
- test "returns 404 when poll is private and not available for user", %{conn: conn} do
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(other_user, %{
- status: "Am I cute?",
- poll: %{options: ["Yes", "No"], expires_in: 20},
- visibility: "private"
- })
-
- object = Object.normalize(activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0]})
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/report_controller_test.exs b/test/web/mastodon_api/controllers/report_controller_test.exs
deleted file mode 100644
index 6636cff96..000000000
--- a/test/web/mastodon_api/controllers/report_controller_test.exs
+++ /dev/null
@@ -1,95 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- setup do: oauth_access(["write:reports"])
-
- setup do
- target_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"})
-
- [target_user: target_user, activity: activity]
- end
-
- test "submit a basic report", %{conn: conn, target_user: target_user} do
- assert %{"action_taken" => false, "id" => _} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/reports", %{"account_id" => target_user.id})
- |> json_response_and_validate_schema(200)
- end
-
- test "submit a report with statuses and comment", %{
- conn: conn,
- target_user: target_user,
- activity: activity
- } do
- assert %{"action_taken" => false, "id" => _} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/reports", %{
- "account_id" => target_user.id,
- "status_ids" => [activity.id],
- "comment" => "bad status!",
- "forward" => "false"
- })
- |> json_response_and_validate_schema(200)
- end
-
- test "account_id is required", %{
- conn: conn,
- activity: activity
- } do
- assert %{"error" => "Missing field: account_id."} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/reports", %{"status_ids" => [activity.id]})
- |> json_response_and_validate_schema(400)
- end
-
- test "comment must be up to the size specified in the config", %{
- conn: conn,
- target_user: target_user
- } do
- max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
- comment = String.pad_trailing("a", max_size + 1, "a")
-
- error = %{"error" => "Comment must be up to #{max_size} characters"}
-
- assert ^error =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment})
- |> json_response_and_validate_schema(400)
- end
-
- test "returns error when account is not exist", %{
- conn: conn,
- activity: activity
- } do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"})
-
- assert json_response_and_validate_schema(conn, 400) == %{"error" => "Account not found"}
- end
-
- test "doesn't fail if an admin has no email", %{conn: conn, target_user: target_user} do
- insert(:user, %{is_admin: true, email: nil})
-
- assert %{"action_taken" => false, "id" => _} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/reports", %{"account_id" => target_user.id})
- |> json_response_and_validate_schema(200)
- 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
deleted file mode 100644
index 1ff871c89..000000000
--- a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
+++ /dev/null
@@ -1,139 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Repo
- alias Pleroma.ScheduledActivity
-
- import Pleroma.Factory
- import Ecto.Query
-
- setup do: clear_config([ScheduledActivity, :enabled])
-
- test "shows scheduled activities" do
- %{user: user, conn: conn} = oauth_access(["read:statuses"])
-
- 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()
-
- # min_id
- conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}")
-
- result = json_response_and_validate_schema(conn_res, 200)
- assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
-
- # since_id
- conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}")
-
- result = json_response_and_validate_schema(conn_res, 200)
- assert [%{"id" => ^scheduled_activity_id4}, %{"id" => ^scheduled_activity_id3}] = result
-
- # max_id
- conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}")
-
- result = json_response_and_validate_schema(conn_res, 200)
- assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
- end
-
- test "shows a scheduled activity" do
- %{user: user, conn: conn} = oauth_access(["read:statuses"])
- scheduled_activity = insert(:scheduled_activity, user: user)
-
- res_conn = get(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}")
-
- assert %{"id" => scheduled_activity_id} = json_response_and_validate_schema(res_conn, 200)
- assert scheduled_activity_id == scheduled_activity.id |> to_string()
-
- res_conn = get(conn, "/api/v1/scheduled_statuses/404")
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404)
- end
-
- test "updates a scheduled activity" do
- Pleroma.Config.put([ScheduledActivity, :enabled], true)
- %{user: user, conn: conn} = oauth_access(["write:statuses"])
-
- scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 60)
-
- {:ok, scheduled_activity} =
- ScheduledActivity.create(
- user,
- %{
- scheduled_at: scheduled_at,
- params: build(:note).data
- }
- )
-
- job = Repo.one(from(j in Oban.Job, where: j.queue == "scheduled_activities"))
-
- assert job.args == %{"activity_id" => scheduled_activity.id}
- assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(scheduled_at)
-
- new_scheduled_at =
- NaiveDateTime.utc_now()
- |> Timex.shift(minutes: 120)
- |> Timex.format!("%Y-%m-%dT%H:%M:%S.%fZ", :strftime)
-
- res_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{
- scheduled_at: new_scheduled_at
- })
-
- assert %{"scheduled_at" => expected_scheduled_at} =
- json_response_and_validate_schema(res_conn, 200)
-
- assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(new_scheduled_at)
- job = refresh_record(job)
-
- assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(new_scheduled_at)
-
- res_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> put("/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at})
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404)
- end
-
- test "deletes a scheduled activity" do
- Pleroma.Config.put([ScheduledActivity, :enabled], true)
- %{user: user, conn: conn} = oauth_access(["write:statuses"])
- scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 60)
-
- {:ok, scheduled_activity} =
- ScheduledActivity.create(
- user,
- %{
- scheduled_at: scheduled_at,
- params: build(:note).data
- }
- )
-
- job = Repo.one(from(j in Oban.Job, where: j.queue == "scheduled_activities"))
-
- assert job.args == %{"activity_id" => scheduled_activity.id}
-
- res_conn =
- conn
- |> assign(:user, user)
- |> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
-
- assert %{} = json_response_and_validate_schema(res_conn, 200)
- refute Repo.get(ScheduledActivity, scheduled_activity.id)
- refute Repo.get(Oban.Job, job.id)
-
- res_conn =
- conn
- |> assign(:user, user)
- |> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404)
- end
-end
diff --git a/test/web/mastodon_api/controllers/search_controller_test.exs b/test/web/mastodon_api/controllers/search_controller_test.exs
deleted file mode 100644
index 24d1959f8..000000000
--- a/test/web/mastodon_api/controllers/search_controller_test.exs
+++ /dev/null
@@ -1,413 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Object
- alias Pleroma.Web
- alias Pleroma.Web.CommonAPI
- import Pleroma.Factory
- import ExUnit.CaptureLog
- import Tesla.Mock
- import Mock
-
- setup_all do
- mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- describe ".search2" do
- test "it returns empty result if user or status search return undefined error", %{conn: conn} do
- with_mocks [
- {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]},
- {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]}
- ] do
- capture_log(fn ->
- results =
- conn
- |> get("/api/v2/search?q=2hu")
- |> json_response_and_validate_schema(200)
-
- assert results["accounts"] == []
- assert results["statuses"] == []
- end) =~
- "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}"
- end
- end
-
- test "search", %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user, %{nickname: "shp@shitposter.club"})
- user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
-
- {:ok, activity} = CommonAPI.post(user, %{status: "This is about 2hu private 天子"})
-
- {:ok, _activity} =
- CommonAPI.post(user, %{
- status: "This is about 2hu, but private",
- visibility: "private"
- })
-
- {:ok, _} = CommonAPI.post(user_two, %{status: "This isn't"})
-
- results =
- conn
- |> get("/api/v2/search?#{URI.encode_query(%{q: "2hu #private"})}")
- |> json_response_and_validate_schema(200)
-
- [account | _] = results["accounts"]
- assert account["id"] == to_string(user_three.id)
-
- assert results["hashtags"] == [
- %{"name" => "private", "url" => "#{Web.base_url()}/tag/private"}
- ]
-
- [status] = results["statuses"]
- assert status["id"] == to_string(activity.id)
-
- results =
- get(conn, "/api/v2/search?q=天子")
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "天子", "url" => "#{Web.base_url()}/tag/天子"}
- ]
-
- [status] = results["statuses"]
- assert status["id"] == to_string(activity.id)
- end
-
- @tag capture_log: true
- test "constructs hashtags from search query", %{conn: conn} do
- results =
- conn
- |> get("/api/v2/search?#{URI.encode_query(%{q: "some text with #explicit #hashtags"})}")
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "explicit", "url" => "#{Web.base_url()}/tag/explicit"},
- %{"name" => "hashtags", "url" => "#{Web.base_url()}/tag/hashtags"}
- ]
-
- results =
- conn
- |> get("/api/v2/search?#{URI.encode_query(%{q: "john doe JOHN DOE"})}")
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "john", "url" => "#{Web.base_url()}/tag/john"},
- %{"name" => "doe", "url" => "#{Web.base_url()}/tag/doe"},
- %{"name" => "JohnDoe", "url" => "#{Web.base_url()}/tag/JohnDoe"}
- ]
-
- results =
- conn
- |> get("/api/v2/search?#{URI.encode_query(%{q: "accident-prone"})}")
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "accident", "url" => "#{Web.base_url()}/tag/accident"},
- %{"name" => "prone", "url" => "#{Web.base_url()}/tag/prone"},
- %{"name" => "AccidentProne", "url" => "#{Web.base_url()}/tag/AccidentProne"}
- ]
-
- results =
- conn
- |> get("/api/v2/search?#{URI.encode_query(%{q: "https://shpposter.club/users/shpuld"})}")
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "shpuld", "url" => "#{Web.base_url()}/tag/shpuld"}
- ]
-
- results =
- conn
- |> get(
- "/api/v2/search?#{
- URI.encode_query(%{
- q:
- "https://www.washingtonpost.com/sports/2020/06/10/" <>
- "nascar-ban-display-confederate-flag-all-events-properties/"
- })
- }"
- )
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "nascar", "url" => "#{Web.base_url()}/tag/nascar"},
- %{"name" => "ban", "url" => "#{Web.base_url()}/tag/ban"},
- %{"name" => "display", "url" => "#{Web.base_url()}/tag/display"},
- %{"name" => "confederate", "url" => "#{Web.base_url()}/tag/confederate"},
- %{"name" => "flag", "url" => "#{Web.base_url()}/tag/flag"},
- %{"name" => "all", "url" => "#{Web.base_url()}/tag/all"},
- %{"name" => "events", "url" => "#{Web.base_url()}/tag/events"},
- %{"name" => "properties", "url" => "#{Web.base_url()}/tag/properties"},
- %{
- "name" => "NascarBanDisplayConfederateFlagAllEventsProperties",
- "url" =>
- "#{Web.base_url()}/tag/NascarBanDisplayConfederateFlagAllEventsProperties"
- }
- ]
- end
-
- test "supports pagination of hashtags search results", %{conn: conn} do
- results =
- conn
- |> get(
- "/api/v2/search?#{
- URI.encode_query(%{q: "#some #text #with #hashtags", limit: 2, offset: 1})
- }"
- )
- |> json_response_and_validate_schema(200)
-
- assert results["hashtags"] == [
- %{"name" => "text", "url" => "#{Web.base_url()}/tag/text"},
- %{"name" => "with", "url" => "#{Web.base_url()}/tag/with"}
- ]
- end
-
- test "excludes a blocked users from search results", %{conn: conn} do
- user = insert(:user)
- user_smith = insert(:user, %{nickname: "Agent", name: "I love 2hu"})
- user_neo = insert(:user, %{nickname: "Agent Neo", name: "Agent"})
-
- {:ok, act1} = CommonAPI.post(user, %{status: "This is about 2hu private 天子"})
- {:ok, act2} = CommonAPI.post(user_smith, %{status: "Agent Smith"})
- {:ok, act3} = CommonAPI.post(user_neo, %{status: "Agent Smith"})
- Pleroma.User.block(user, user_smith)
-
- results =
- conn
- |> assign(:user, user)
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
- |> get("/api/v2/search?q=Agent")
- |> json_response_and_validate_schema(200)
-
- status_ids = Enum.map(results["statuses"], fn g -> g["id"] end)
-
- assert act3.id in status_ids
- refute act2.id in status_ids
- refute act1.id in status_ids
- end
- end
-
- describe ".account_search" do
- test "account search", %{conn: conn} do
- user_two = insert(:user, %{nickname: "shp@shitposter.club"})
- user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
-
- results =
- conn
- |> get("/api/v1/accounts/search?q=shp")
- |> json_response_and_validate_schema(200)
-
- result_ids = for result <- results, do: result["acct"]
-
- assert user_two.nickname in result_ids
- assert user_three.nickname in result_ids
-
- results =
- conn
- |> get("/api/v1/accounts/search?q=2hu")
- |> json_response_and_validate_schema(200)
-
- result_ids = for result <- results, do: result["acct"]
-
- assert user_three.nickname in result_ids
- end
-
- test "returns account if query contains a space", %{conn: conn} do
- insert(:user, %{nickname: "shp@shitposter.club"})
-
- results =
- conn
- |> get("/api/v1/accounts/search?q=shp@shitposter.club xxx")
- |> json_response_and_validate_schema(200)
-
- assert length(results) == 1
- end
- end
-
- describe ".search" do
- test "it returns empty result if user or status search return undefined error", %{conn: conn} do
- with_mocks [
- {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]},
- {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]}
- ] do
- capture_log(fn ->
- results =
- conn
- |> get("/api/v1/search?q=2hu")
- |> json_response_and_validate_schema(200)
-
- assert results["accounts"] == []
- assert results["statuses"] == []
- end) =~
- "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}"
- end
- end
-
- test "search", %{conn: conn} do
- user = insert(:user)
- user_two = insert(:user, %{nickname: "shp@shitposter.club"})
- user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
-
- {:ok, activity} = CommonAPI.post(user, %{status: "This is about 2hu"})
-
- {:ok, _activity} =
- CommonAPI.post(user, %{
- status: "This is about 2hu, but private",
- visibility: "private"
- })
-
- {:ok, _} = CommonAPI.post(user_two, %{status: "This isn't"})
-
- results =
- conn
- |> get("/api/v1/search?q=2hu")
- |> json_response_and_validate_schema(200)
-
- [account | _] = results["accounts"]
- assert account["id"] == to_string(user_three.id)
-
- assert results["hashtags"] == ["2hu"]
-
- [status] = results["statuses"]
- assert status["id"] == to_string(activity.id)
- end
-
- test "search fetches remote statuses and prefers them over other results", %{conn: conn} do
- capture_log(fn ->
- {:ok, %{id: activity_id}} =
- CommonAPI.post(insert(:user), %{
- status: "check out https://shitposter.club/notice/2827873"
- })
-
- results =
- conn
- |> get("/api/v1/search?q=https://shitposter.club/notice/2827873")
- |> json_response_and_validate_schema(200)
-
- [status, %{"id" => ^activity_id}] = results["statuses"]
-
- assert status["uri"] ==
- "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
- end)
- end
-
- test "search doesn't show statuses that it shouldn't", %{conn: conn} do
- {:ok, activity} =
- CommonAPI.post(insert(:user), %{
- status: "This is about 2hu, but private",
- visibility: "private"
- })
-
- capture_log(fn ->
- q = Object.normalize(activity).data["id"]
-
- results =
- conn
- |> get("/api/v1/search?q=#{q}")
- |> json_response_and_validate_schema(200)
-
- [] = results["statuses"]
- end)
- end
-
- test "search fetches remote accounts", %{conn: conn} do
- user = insert(:user)
-
- query = URI.encode_query(%{q: " mike@osada.macgirvin.com ", resolve: true})
-
- results =
- conn
- |> assign(:user, user)
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
- |> get("/api/v1/search?#{query}")
- |> json_response_and_validate_schema(200)
-
- [account] = results["accounts"]
- assert account["acct"] == "mike@osada.macgirvin.com"
- end
-
- test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do
- results =
- conn
- |> get("/api/v1/search?q=mike@osada.macgirvin.com&resolve=false")
- |> json_response_and_validate_schema(200)
-
- assert [] == results["accounts"]
- end
-
- test "search with limit and offset", %{conn: conn} do
- user = insert(:user)
- _user_two = insert(:user, %{nickname: "shp@shitposter.club"})
- _user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
-
- {:ok, _activity1} = CommonAPI.post(user, %{status: "This is about 2hu"})
- {:ok, _activity2} = CommonAPI.post(user, %{status: "This is also about 2hu"})
-
- result =
- conn
- |> get("/api/v1/search?q=2hu&limit=1")
-
- assert results = json_response_and_validate_schema(result, 200)
- assert [%{"id" => activity_id1}] = results["statuses"]
- assert [_] = results["accounts"]
-
- results =
- conn
- |> get("/api/v1/search?q=2hu&limit=1&offset=1")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => activity_id2}] = results["statuses"]
- assert [] = results["accounts"]
-
- assert activity_id1 != activity_id2
- end
-
- test "search returns results only for the given type", %{conn: conn} do
- user = insert(:user)
- _user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
-
- {:ok, _activity} = CommonAPI.post(user, %{status: "This is about 2hu"})
-
- assert %{"statuses" => [_activity], "accounts" => [], "hashtags" => []} =
- conn
- |> get("/api/v1/search?q=2hu&type=statuses")
- |> json_response_and_validate_schema(200)
-
- assert %{"statuses" => [], "accounts" => [_user_two], "hashtags" => []} =
- conn
- |> get("/api/v1/search?q=2hu&type=accounts")
- |> json_response_and_validate_schema(200)
- end
-
- test "search uses account_id to filter statuses by the author", %{conn: conn} do
- user = insert(:user, %{nickname: "shp@shitposter.club"})
- user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
-
- {:ok, activity1} = CommonAPI.post(user, %{status: "This is about 2hu"})
- {:ok, activity2} = CommonAPI.post(user_two, %{status: "This is also about 2hu"})
-
- results =
- conn
- |> get("/api/v1/search?q=2hu&account_id=#{user.id}")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => activity_id1}] = results["statuses"]
- assert activity_id1 == activity1.id
- assert [_] = results["accounts"]
-
- results =
- conn
- |> get("/api/v1/search?q=2hu&account_id=#{user_two.id}")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => activity_id2}] = results["statuses"]
- assert activity_id2 == activity2.id
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs
deleted file mode 100644
index f221884e7..000000000
--- a/test/web/mastodon_api/controllers/status_controller_test.exs
+++ /dev/null
@@ -1,1704 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Activity
- alias Pleroma.ActivityExpiration
- alias Pleroma.Config
- alias Pleroma.Conversation.Participation
- 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
-
- import Pleroma.Factory
-
- setup do: clear_config([:instance, :federating])
- setup do: clear_config([:instance, :allow_relay])
- setup do: clear_config([:rich_media, :enabled])
- setup do: clear_config([:mrf, :policies])
- setup do: clear_config([:mrf_keyword, :reject])
-
- describe "posting statuses" do
- setup do: oauth_access(["write:statuses"])
-
- test "posting a status does not increment reblog_count when relaying", %{conn: conn} do
- Pleroma.Config.put([:instance, :federating], true)
- Pleroma.Config.get([:instance, :allow_relay], true)
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("api/v1/statuses", %{
- "content_type" => "text/plain",
- "source" => "Pleroma FE",
- "status" => "Hello world",
- "visibility" => "public"
- })
- |> json_response_and_validate_schema(200)
-
- assert response["reblogs_count"] == 0
- ObanHelpers.perform_all()
-
- response =
- conn
- |> get("api/v1/statuses/#{response["id"]}", %{})
- |> json_response_and_validate_schema(200)
-
- assert response["reblogs_count"] == 0
- end
-
- test "posting a status", %{conn: conn} do
- idempotency_key = "Pikachu rocks!"
-
- conn_one =
- conn
- |> put_req_header("content-type", "application/json")
- |> put_req_header("idempotency-key", idempotency_key)
- |> post("/api/v1/statuses", %{
- "status" => "cofe",
- "spoiler_text" => "2hu",
- "sensitive" => "0"
- })
-
- {: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_and_validate_schema(conn_one, 200)
-
- assert Activity.get_by_id(id)
-
- conn_two =
- conn
- |> put_req_header("content-type", "application/json")
- |> put_req_header("idempotency-key", idempotency_key)
- |> post("/api/v1/statuses", %{
- "status" => "cofe",
- "spoiler_text" => "2hu",
- "sensitive" => 0
- })
-
- assert %{"id" => second_id} = json_response(conn_two, 200)
- assert id == second_id
-
- conn_three =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "cofe",
- "spoiler_text" => "2hu",
- "sensitive" => "False"
- })
-
- assert %{"id" => third_id} = json_response_and_validate_schema(conn_three, 200)
- refute id == third_id
-
- # An activity that will expire:
- # 2 hours
- expires_in = 120 * 60
-
- conn_four =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("api/v1/statuses", %{
- "status" => "oolong",
- "expires_in" => expires_in
- })
-
- assert fourth_response =
- %{"id" => fourth_id} = json_response_and_validate_schema(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 "it fails to create a status if `expires_in` is less or equal than an hour", %{
- conn: conn
- } do
- # 1 hour
- expires_in = 60 * 60
-
- assert %{"error" => "Expiry date is too soon"} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("api/v1/statuses", %{
- "status" => "oolong",
- "expires_in" => expires_in
- })
- |> json_response_and_validate_schema(422)
-
- # 30 minutes
- expires_in = 30 * 60
-
- assert %{"error" => "Expiry date is too soon"} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("api/v1/statuses", %{
- "status" => "oolong",
- "expires_in" => expires_in
- })
- |> json_response_and_validate_schema(422)
- end
-
- test "Get MRF reason when posting a status is rejected by one", %{conn: conn} do
- Pleroma.Config.put([:mrf_keyword, :reject], ["GNO"])
- Pleroma.Config.put([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
-
- assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("api/v1/statuses", %{"status" => "GNO/Linux"})
- |> json_response_and_validate_schema(422)
- end
-
- test "posting an undefined status with an attachment", %{user: user, conn: conn} do
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "media_ids" => [to_string(upload.id)]
- })
-
- assert json_response_and_validate_schema(conn, 200)
- end
-
- test "replying to a status", %{user: user, conn: conn} do
- {:ok, replied_to} = CommonAPI.post(user, %{status: "cofe"})
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
-
- assert %{"content" => "xD", "id" => id} = json_response_and_validate_schema(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", %{
- user: user,
- conn: conn
- } do
- {:ok, replied_to} = CommonAPI.post(user, %{status: "suya..", visibility: "direct"})
-
- Enum.each(["public", "private", "unlisted"], fn visibility ->
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "@#{user.nickname} hey",
- "in_reply_to_id" => replied_to.id,
- "visibility" => visibility
- })
-
- assert json_response_and_validate_schema(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
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""})
-
- assert %{"content" => "xD", "id" => id} = json_response_and_validate_schema(conn, 200)
- assert Activity.get_by_id(id)
- end
-
- test "posting a sensitive status", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
-
- assert %{"content" => "cofe", "id" => id, "sensitive" => true} =
- json_response_and_validate_schema(conn, 200)
-
- assert Activity.get_by_id(id)
- end
-
- test "posting a fake status", %{conn: conn} do
- real_conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> 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_and_validate_schema(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
- |> put_req_header("content-type", "application/json")
- |> 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_and_validate_schema(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 "fake statuses' preview card is not cached", %{conn: conn} do
- clear_config([:rich_media, :enabled], true)
-
- Tesla.Mock.mock(fn
- %{
- method: :get,
- url: "https://example.com/twitter-card"
- } ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}
-
- env ->
- apply(HttpRequestMock, :request, [env])
- end)
-
- conn1 =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "https://example.com/ogp",
- "preview" => true
- })
-
- conn2 =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "https://example.com/twitter-card",
- "preview" => true
- })
-
- assert %{"card" => %{"title" => "The Rock"}} = json_response_and_validate_schema(conn1, 200)
-
- assert %{"card" => %{"title" => "Small Island Developing States Photo Submission"}} =
- json_response_and_validate_schema(conn2, 200)
- end
-
- test "posting a status with OGP link preview", %{conn: conn} do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- clear_config([:rich_media, :enabled], true)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "https://example.com/ogp"
- })
-
- assert %{"id" => id, "card" => %{"title" => "The Rock"}} =
- json_response_and_validate_schema(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
- |> put_req_header("content-type", "application/json")
- |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
-
- assert %{"id" => id} = response = json_response_and_validate_schema(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
- setup do: oauth_access(["write:statuses"])
-
- test "creates a scheduled activity", %{conn: conn} do
- scheduled_at =
- NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond)
- |> NaiveDateTime.to_iso8601()
- |> Kernel.<>("Z")
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "scheduled",
- "scheduled_at" => scheduled_at
- })
-
- assert %{"scheduled_at" => expected_scheduled_at} =
- json_response_and_validate_schema(conn, 200)
-
- assert expected_scheduled_at == CommonAPI.Utils.to_masto_date(scheduled_at)
- assert [] == Repo.all(Activity)
- end
-
- test "ignores nil values", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "not scheduled",
- "scheduled_at" => nil
- })
-
- assert result = json_response_and_validate_schema(conn, 200)
- assert Activity.get_by_id(result["id"])
- end
-
- test "creates a scheduled activity with a media attachment", %{user: user, conn: conn} do
- scheduled_at =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(120), :millisecond)
- |> NaiveDateTime.to_iso8601()
- |> Kernel.<>("Z")
-
- 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
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "media_ids" => [to_string(upload.id)],
- "status" => "scheduled",
- "scheduled_at" => scheduled_at
- })
-
- assert %{"media_attachments" => [media_attachment]} =
- json_response_and_validate_schema(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
- scheduled_at =
- NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(5) - 1, :millisecond)
- |> NaiveDateTime.to_iso8601()
- |> Kernel.<>("Z")
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "not scheduled",
- "scheduled_at" => scheduled_at
- })
-
- assert %{"content" => "not scheduled"} = json_response_and_validate_schema(conn, 200)
- assert [] == Repo.all(ScheduledActivity)
- end
-
- test "returns error when daily user limit is exceeded", %{user: user, conn: conn} do
- today =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
- |> NaiveDateTime.to_iso8601()
- # TODO
- |> Kernel.<>("Z")
-
- attrs = %{params: %{}, scheduled_at: today}
- {:ok, _} = ScheduledActivity.create(user, attrs)
- {:ok, _} = ScheduledActivity.create(user, attrs)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today})
-
- assert %{"error" => "daily limit exceeded"} == json_response_and_validate_schema(conn, 422)
- end
-
- test "returns error when total user limit is exceeded", %{user: user, conn: conn} do
- today =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
- |> NaiveDateTime.to_iso8601()
- |> Kernel.<>("Z")
-
- tomorrow =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.hours(36), :millisecond)
- |> NaiveDateTime.to_iso8601()
- |> Kernel.<>("Z")
-
- 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
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow})
-
- assert %{"error" => "total limit exceeded"} == json_response_and_validate_schema(conn, 422)
- end
- end
-
- describe "posting polls" do
- setup do: oauth_access(["write:statuses"])
-
- test "posting a poll", %{conn: conn} do
- time = NaiveDateTime.utc_now()
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "Who is the #bestgrill?",
- "poll" => %{
- "options" => ["Rei", "Asuka", "Misato"],
- "expires_in" => 420
- }
- })
-
- response = json_response_and_validate_schema(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"]
-
- question = Object.get_by_id(response["poll"]["id"])
-
- # closed contains utc timezone
- assert question.data["closed"] =~ "Z"
- end
-
- test "option limit is enforced", %{conn: conn} do
- limit = Config.get([:instance, :poll_limits, :max_options])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "desu~",
- "poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1}
- })
-
- %{"error" => error} = json_response_and_validate_schema(conn, 422)
- assert error == "Poll can't contain more than #{limit} options"
- end
-
- test "option character limit is enforced", %{conn: conn} do
- limit = Config.get([:instance, :poll_limits, :max_option_chars])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{
- "status" => "...",
- "poll" => %{
- "options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)],
- "expires_in" => 1
- }
- })
-
- %{"error" => error} = json_response_and_validate_schema(conn, 422)
- assert error == "Poll options cannot be longer than #{limit} characters each"
- end
-
- test "minimal date limit is enforced", %{conn: conn} do
- limit = Config.get([:instance, :poll_limits, :min_expiration])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> 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_and_validate_schema(conn, 422)
- assert error == "Expiration date is too soon"
- end
-
- test "maximum date limit is enforced", %{conn: conn} do
- limit = Config.get([:instance, :poll_limits, :max_expiration])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> 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_and_validate_schema(conn, 422)
- assert error == "Expiration date is too far in the future"
- end
- end
-
- test "get a status" do
- %{conn: conn} = oauth_access(["read:statuses"])
- activity = insert(:note_activity)
-
- conn = get(conn, "/api/v1/statuses/#{activity.id}")
-
- assert %{"id" => id} = json_response_and_validate_schema(conn, 200)
- assert id == to_string(activity.id)
- end
-
- defp local_and_remote_activities do
- local = insert(:note_activity)
- remote = insert(:note_activity, local: false)
- {:ok, local: local, remote: remote}
- end
-
- describe "status with restrict unauthenticated activities for local and remote" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/statuses/#{local.id}")
-
- assert json_response_and_validate_schema(res_conn, :not_found) == %{
- "error" => "Record not found"
- }
-
- res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
-
- assert json_response_and_validate_schema(res_conn, :not_found) == %{
- "error" => "Record not found"
- }
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
- res_conn = get(conn, "/api/v1/statuses/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
- end
-
- describe "status with restrict unauthenticated activities for local" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/statuses/#{local.id}")
-
- assert json_response_and_validate_schema(res_conn, :not_found) == %{
- "error" => "Record not found"
- }
-
- res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
- res_conn = get(conn, "/api/v1/statuses/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
- end
-
- describe "status with restrict unauthenticated activities for remote" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/statuses/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
-
- assert json_response_and_validate_schema(res_conn, :not_found) == %{
- "error" => "Record not found"
- }
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
- res_conn = get(conn, "/api/v1/statuses/#{local.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
- assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
- end
- end
-
- test "getting a status that doesn't exist returns 404" do
- %{conn: conn} = oauth_access(["read:statuses"])
- activity = insert(:note_activity)
-
- conn = get(conn, "/api/v1/statuses/#{String.downcase(activity.id)}")
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
-
- test "get a direct status" do
- %{user: user, conn: conn} = oauth_access(["read:statuses"])
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "direct"})
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/statuses/#{activity.id}")
-
- [participation] = Participation.for_user(user)
-
- res = json_response_and_validate_schema(conn, 200)
- assert res["pleroma"]["direct_conversation_id"] == participation.id
- end
-
- test "get statuses by IDs" do
- %{conn: conn} = oauth_access(["read:statuses"])
- %{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_and_validate_schema(conn, :ok), & &1["id"])
- end
-
- describe "getting statuses by ids with restricted unauthenticated for local and remote" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
-
- assert json_response_and_validate_schema(res_conn, 200) == []
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
-
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- end
- end
-
- describe "getting statuses by ids with restricted unauthenticated for local" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
-
- remote_id = remote.id
- assert [%{"id" => ^remote_id}] = json_response_and_validate_schema(res_conn, 200)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
-
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- end
- end
-
- describe "getting statuses by ids with restricted unauthenticated for remote" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
-
- test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
- res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
-
- local_id = local.id
- assert [%{"id" => ^local_id}] = json_response_and_validate_schema(res_conn, 200)
- end
-
- test "if user is authenticated", %{local: local, remote: remote} do
- %{conn: conn} = oauth_access(["read"])
-
- res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}")
-
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- end
- end
-
- describe "deleting a status" do
- test "when you created it" do
- %{user: author, conn: conn} = oauth_access(["write:statuses"])
- activity = insert(:note_activity, user: author)
- object = Object.normalize(activity)
-
- content = object.data["content"]
- source = object.data["source"]
-
- result =
- conn
- |> assign(:user, author)
- |> delete("/api/v1/statuses/#{activity.id}")
- |> json_response_and_validate_schema(200)
-
- assert match?(%{"content" => ^content, "text" => ^source}, result)
-
- refute Activity.get_by_id(activity.id)
- end
-
- test "when it doesn't exist" do
- %{user: author, conn: conn} = oauth_access(["write:statuses"])
- activity = insert(:note_activity, user: author)
-
- conn =
- conn
- |> assign(:user, author)
- |> delete("/api/v1/statuses/#{String.downcase(activity.id)}")
-
- assert %{"error" => "Record not found"} == json_response_and_validate_schema(conn, 404)
- end
-
- test "when you didn't create it" do
- %{conn: conn} = oauth_access(["write:statuses"])
- activity = insert(:note_activity)
-
- conn = delete(conn, "/api/v1/statuses/#{activity.id}")
-
- assert %{"error" => "Record not found"} == json_response_and_validate_schema(conn, 404)
-
- 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, is_admin: true)
- moderator = insert(:user, is_moderator: true)
-
- res_conn =
- conn
- |> assign(:user, admin)
- |> assign(:token, insert(:oauth_token, user: admin, scopes: ["write:statuses"]))
- |> delete("/api/v1/statuses/#{activity1.id}")
-
- assert %{} = json_response_and_validate_schema(res_conn, 200)
-
- res_conn =
- conn
- |> assign(:user, moderator)
- |> assign(:token, insert(:oauth_token, user: moderator, scopes: ["write:statuses"]))
- |> delete("/api/v1/statuses/#{activity2.id}")
-
- assert %{} = json_response_and_validate_schema(res_conn, 200)
-
- refute Activity.get_by_id(activity1.id)
- refute Activity.get_by_id(activity2.id)
- end
- end
-
- describe "reblogging" do
- setup do: oauth_access(["write:statuses"])
-
- test "reblogs and returns the reblogged status", %{conn: conn} do
- activity = insert(:note_activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/reblog")
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1},
- "reblogged" => true
- } = json_response_and_validate_schema(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 404 if the reblogged status doesn't exist", %{conn: conn} do
- activity = insert(:note_activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{String.downcase(activity.id)}/reblog")
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404)
- end
-
- test "reblogs privately and returns the reblogged status", %{conn: conn} do
- activity = insert(:note_activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post(
- "/api/v1/statuses/#{activity.id}/reblog",
- %{"visibility" => "private"}
- )
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1},
- "reblogged" => true,
- "visibility" => "private"
- } = json_response_and_validate_schema(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "reblogged status for another user" do
- activity = insert(:note_activity)
- user1 = insert(:user)
- user2 = insert(:user)
- user3 = insert(:user)
- {:ok, _} = CommonAPI.favorite(user2, activity.id)
- {:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id)
- {:ok, reblog_activity1} = CommonAPI.repeat(activity.id, user1)
- {:ok, _} = CommonAPI.repeat(activity.id, user2)
-
- conn_res =
- build_conn()
- |> assign(:user, user3)
- |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"]))
- |> get("/api/v1/statuses/#{reblog_activity1.id}")
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => false, "reblogs_count" => 2},
- "reblogged" => false,
- "favourited" => false,
- "bookmarked" => false
- } = json_response_and_validate_schema(conn_res, 200)
-
- conn_res =
- build_conn()
- |> assign(:user, user2)
- |> assign(:token, insert(:oauth_token, user: user2, scopes: ["read:statuses"]))
- |> get("/api/v1/statuses/#{reblog_activity1.id}")
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 2},
- "reblogged" => true,
- "favourited" => true,
- "bookmarked" => true
- } = json_response_and_validate_schema(conn_res, 200)
-
- assert to_string(activity.id) == id
- end
- end
-
- describe "unreblogging" do
- setup do: oauth_access(["write:statuses"])
-
- test "unreblogs and returns the unreblogged status", %{user: user, conn: conn} do
- activity = insert(:note_activity)
-
- {:ok, _} = CommonAPI.repeat(activity.id, user)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/unreblog")
-
- assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} =
- json_response_and_validate_schema(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 404 error when activity does not exist", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/foo/unreblog")
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
- end
-
- describe "favoriting" do
- setup do: oauth_access(["write:favourites"])
-
- test "favs a status and returns it", %{conn: conn} do
- activity = insert(:note_activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/favourite")
-
- assert %{"id" => id, "favourites_count" => 1, "favourited" => true} =
- json_response_and_validate_schema(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "favoriting twice will just return 200", %{conn: conn} do
- activity = insert(:note_activity)
-
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/favourite")
-
- assert conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/favourite")
- |> json_response_and_validate_schema(200)
- end
-
- test "returns 404 error for a wrong id", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/1/favourite")
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
- end
-
- describe "unfavoriting" do
- setup do: oauth_access(["write:favourites"])
-
- test "unfavorites a status and returns it", %{user: user, conn: conn} do
- activity = insert(:note_activity)
-
- {:ok, _} = CommonAPI.favorite(user, activity.id)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/unfavourite")
-
- assert %{"id" => id, "favourites_count" => 0, "favourited" => false} =
- json_response_and_validate_schema(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 404 error for a wrong id", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/1/unfavourite")
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
- end
-
- describe "pinned statuses" do
- setup do: oauth_access(["write:accounts"])
-
- setup %{user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "HI!!!"})
-
- %{activity: activity}
- end
-
- setup do: clear_config([:instance, :max_pinned_statuses], 1)
-
- test "pin status", %{conn: conn, user: user, activity: activity} do
- id_str = to_string(activity.id)
-
- assert %{"id" => ^id_str, "pinned" => true} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/pin")
- |> json_response_and_validate_schema(200)
-
- assert [%{"id" => ^id_str, "pinned" => true}] =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
- |> json_response_and_validate_schema(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
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{dm.id}/pin")
-
- assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not pin"}
- end
-
- test "unpin status", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.pin(activity.id, user)
- user = refresh_record(user)
-
- id_str = to_string(activity.id)
-
- assert %{"id" => ^id_str, "pinned" => false} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/unpin")
- |> json_response_and_validate_schema(200)
-
- assert [] =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
- |> json_response_and_validate_schema(200)
- end
-
- test "/unpin: returns 400 error when activity is not exist", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/1/unpin")
-
- assert json_response_and_validate_schema(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
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{id_str_one}/pin")
- |> json_response_and_validate_schema(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_and_validate_schema(400)
- end
- end
-
- describe "cards" do
- setup do
- Config.put([:rich_media, :enabled], true)
-
- oauth_access(["read:statuses"])
- 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_and_validate_schema(200)
-
- assert response == card_data
-
- # works with private posts
- {:ok, activity} =
- CommonAPI.post(user, %{status: "https://example.com/ogp", visibility: "direct"})
-
- response_two =
- conn
- |> get("/api/v1/statuses/#{activity.id}/card")
- |> json_response_and_validate_schema(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_and_validate_schema(: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
- bookmarks_uri = "/api/v1/bookmarks"
-
- %{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"])
- author = insert(:user)
-
- {:ok, activity1} = CommonAPI.post(author, %{status: "heweoo?"})
- {:ok, activity2} = CommonAPI.post(author, %{status: "heweoo!"})
-
- response1 =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity1.id}/bookmark")
-
- assert json_response_and_validate_schema(response1, 200)["bookmarked"] == true
-
- response2 =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity2.id}/bookmark")
-
- assert json_response_and_validate_schema(response2, 200)["bookmarked"] == true
-
- bookmarks = get(conn, bookmarks_uri)
-
- assert [
- json_response_and_validate_schema(response2, 200),
- json_response_and_validate_schema(response1, 200)
- ] ==
- json_response_and_validate_schema(bookmarks, 200)
-
- response1 =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity1.id}/unbookmark")
-
- assert json_response_and_validate_schema(response1, 200)["bookmarked"] == false
-
- bookmarks = get(conn, bookmarks_uri)
-
- assert [json_response_and_validate_schema(response2, 200)] ==
- json_response_and_validate_schema(bookmarks, 200)
- end
-
- describe "conversation muting" do
- setup do: oauth_access(["write:mutes"])
-
- setup do
- post_user = insert(:user)
- {:ok, activity} = CommonAPI.post(post_user, %{status: "HIE"})
- %{activity: activity}
- end
-
- test "mute conversation", %{conn: conn, activity: activity} do
- id_str = to_string(activity.id)
-
- assert %{"id" => ^id_str, "muted" => true} =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/mute")
- |> json_response_and_validate_schema(200)
- end
-
- test "cannot mute already muted conversation", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/mute")
-
- assert json_response_and_validate_schema(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)
-
- assert %{"id" => ^id_str, "muted" => false} =
- conn
- # |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/unmute")
- |> json_response_and_validate_schema(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)
- |> assign(:token, insert(:oauth_token, user: user2, scopes: ["write:statuses"]))
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
-
- assert %{"content" => "xD", "id" => id} = json_response_and_validate_schema(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)
- |> assign(:token, insert(:oauth_token, user: user3, scopes: ["write:statuses"]))
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/#{activity.id}/reblog")
-
- assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} =
- json_response_and_validate_schema(conn2, 200)
-
- assert to_string(activity.id) == id
-
- # Getting third user status
- conn3 =
- conn
- |> assign(:user, user3)
- |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"]))
- |> 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: oauth_access(["read:accounts"])
-
- setup %{user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "test"})
-
- %{activity: activity}
- end
-
- test "returns users who have favorited the status", %{conn: conn, activity: activity} do
- other_user = insert(:user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response_and_validate_schema(: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_and_validate_schema(: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_relationship} = User.block(user, other_user)
-
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not fail on an unauthenticated request", %{activity: activity} do
- other_user = insert(:user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
-
- response =
- build_conn()
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response_and_validate_schema(:ok)
-
- [%{"id" => id}] = response
- assert id == other_user.id
- end
-
- test "requires authentication for private posts", %{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(other_user, activity.id)
-
- favourited_by_url = "/api/v1/statuses/#{activity.id}/favourited_by"
-
- build_conn()
- |> get(favourited_by_url)
- |> json_response_and_validate_schema(404)
-
- conn =
- build_conn()
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"]))
-
- conn
- |> assign(:token, nil)
- |> get(favourited_by_url)
- |> json_response_and_validate_schema(404)
-
- response =
- conn
- |> get(favourited_by_url)
- |> json_response_and_validate_schema(200)
-
- [%{"id" => id}] = response
- assert id == other_user.id
- end
-
- test "returns empty array when :show_reactions is disabled", %{conn: conn, activity: activity} do
- clear_config([:instance, :show_reactions], false)
-
- other_user = insert(:user)
- {:ok, _} = CommonAPI.favorite(other_user, activity.id)
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response)
- end
- end
-
- describe "GET /api/v1/statuses/:id/reblogged_by" do
- setup do: oauth_access(["read:accounts"])
-
- setup %{user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "test"})
-
- %{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_and_validate_schema(: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_and_validate_schema(: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_relationship} = User.block(user, other_user)
-
- {:ok, _} = CommonAPI.repeat(activity.id, other_user)
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not return users who have reblogged the status privately", %{
- conn: conn
- } do
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "my secret post"})
-
- {:ok, _} = CommonAPI.repeat(activity.id, other_user, %{visibility: "private"})
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not fail on an unauthenticated request", %{activity: activity} do
- other_user = insert(:user)
- {:ok, _} = CommonAPI.repeat(activity.id, other_user)
-
- response =
- build_conn()
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response_and_validate_schema(:ok)
-
- [%{"id" => id}] = response
- assert id == other_user.id
- end
-
- test "requires authentication for private posts", %{user: user} do
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "@#{other_user.nickname} wanna get some #cofe together?",
- visibility: "direct"
- })
-
- build_conn()
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response_and_validate_schema(404)
-
- response =
- build_conn()
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"]))
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response_and_validate_schema(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()
- |> get("/api/v1/statuses/#{id3}/context")
- |> json_response_and_validate_schema(:ok)
-
- assert %{
- "ancestors" => [%{"id" => ^id1}, %{"id" => ^id2}],
- "descendants" => [%{"id" => ^id4}, %{"id" => ^id5}]
- } = response
- end
-
- test "favorites paginate correctly" do
- %{user: user, conn: conn} = oauth_access(["read:favourites"])
- other_user = insert(:user)
- {:ok, first_post} = CommonAPI.post(other_user, %{status: "bla"})
- {:ok, second_post} = CommonAPI.post(other_user, %{status: "bla"})
- {:ok, third_post} = CommonAPI.post(other_user, %{status: "bla"})
-
- {:ok, _first_favorite} = CommonAPI.favorite(user, third_post.id)
- {:ok, _second_favorite} = CommonAPI.favorite(user, first_post.id)
- {:ok, third_favorite} = CommonAPI.favorite(user, second_post.id)
-
- result =
- conn
- |> get("/api/v1/favourites?limit=1")
-
- assert [%{"id" => post_id}] = json_response_and_validate_schema(result, 200)
- assert post_id == second_post.id
-
- # Using the header for pagination works correctly
- [next, _] = get_resp_header(result, "link") |> hd() |> String.split(", ")
- [_, max_id] = Regex.run(~r/max_id=([^&]+)/, next)
-
- assert max_id == third_favorite.id
-
- result =
- conn
- |> get("/api/v1/favourites?max_id=#{max_id}")
-
- assert [%{"id" => first_post_id}, %{"id" => third_post_id}] =
- json_response_and_validate_schema(result, 200)
-
- assert first_post_id == first_post.id
- assert third_post_id == third_post.id
- end
-
- test "returns the favorites of a user" do
- %{user: user, conn: conn} = oauth_access(["read:favourites"])
- other_user = insert(:user)
-
- {:ok, _} = CommonAPI.post(other_user, %{status: "bla"})
- {:ok, activity} = CommonAPI.post(other_user, %{status: "trees are happy"})
-
- {:ok, last_like} = CommonAPI.favorite(user, activity.id)
-
- first_conn = get(conn, "/api/v1/favourites")
-
- assert [status] = json_response_and_validate_schema(first_conn, 200)
- assert status["id"] == to_string(activity.id)
-
- assert [{"link", _link_header}] =
- Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end)
-
- # Honours query params
- {:ok, second_activity} =
- CommonAPI.post(other_user, %{
- status: "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
- })
-
- {:ok, _} = CommonAPI.favorite(user, second_activity.id)
-
- second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like.id}")
-
- assert [second_status] = json_response_and_validate_schema(second_conn, 200)
- assert second_status["id"] == to_string(second_activity.id)
-
- third_conn = get(conn, "/api/v1/favourites?limit=0")
-
- assert [] = json_response_and_validate_schema(third_conn, 200)
- end
-
- test "expires_at is nil for another user" do
- %{conn: conn, user: user} = oauth_access(["read:statuses"])
- {:ok, activity} = CommonAPI.post(user, %{status: "foobar", expires_in: 1_000_000})
-
- expires_at =
- activity.id
- |> ActivityExpiration.get_by_activity_id()
- |> Map.get(:scheduled_at)
- |> NaiveDateTime.to_iso8601()
-
- assert %{"pleroma" => %{"expires_at" => ^expires_at}} =
- conn
- |> get("/api/v1/statuses/#{activity.id}")
- |> json_response_and_validate_schema(:ok)
-
- %{conn: conn} = oauth_access(["read:statuses"])
-
- assert %{"pleroma" => %{"expires_at" => nil}} =
- conn
- |> get("/api/v1/statuses/#{activity.id}")
- |> json_response_and_validate_schema(:ok)
- end
-end
diff --git a/test/web/mastodon_api/controllers/subscription_controller_test.exs b/test/web/mastodon_api/controllers/subscription_controller_test.exs
deleted file mode 100644
index d36bb1ae8..000000000
--- a/test/web/mastodon_api/controllers/subscription_controller_test.exs
+++ /dev/null
@@ -1,199 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Web.Push
- alias Pleroma.Web.Push.Subscription
-
- @sub %{
- "endpoint" => "https://example.com/example/1234",
- "keys" => %{
- "auth" => "8eDyX_uCN0XRhSbY5hs7Hg==",
- "p256dh" =>
- "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA="
- }
- }
- @server_key Keyword.get(Push.vapid_config(), :public_key)
-
- setup do
- user = insert(:user)
- token = insert(:oauth_token, user: user, scopes: ["push"])
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> assign(:token, token)
- |> put_req_header("content-type", "application/json")
-
- %{conn: conn, user: user, token: token}
- end
-
- defmacro assert_error_when_disable_push(do: yield) do
- quote do
- vapid_details = Application.get_env(:web_push_encryption, :vapid_details, [])
- Application.put_env(:web_push_encryption, :vapid_details, [])
-
- assert %{"error" => "Web push subscription is disabled on this Pleroma instance"} ==
- unquote(yield)
-
- Application.put_env(:web_push_encryption, :vapid_details, vapid_details)
- end
- end
-
- describe "creates push subscription" do
- test "returns error when push disabled ", %{conn: conn} do
- assert_error_when_disable_push do
- conn
- |> post("/api/v1/push/subscription", %{subscription: @sub})
- |> json_response_and_validate_schema(403)
- end
- end
-
- test "successful creation", %{conn: conn} do
- result =
- conn
- |> post("/api/v1/push/subscription", %{
- "data" => %{
- "alerts" => %{"mention" => true, "test" => true, "pleroma:chat_mention" => true}
- },
- "subscription" => @sub
- })
- |> json_response_and_validate_schema(200)
-
- [subscription] = Pleroma.Repo.all(Subscription)
-
- assert %{
- "alerts" => %{"mention" => true, "pleroma:chat_mention" => true},
- "endpoint" => subscription.endpoint,
- "id" => to_string(subscription.id),
- "server_key" => @server_key
- } == result
- end
- end
-
- describe "gets a user subscription" do
- test "returns error when push disabled ", %{conn: conn} do
- assert_error_when_disable_push do
- conn
- |> get("/api/v1/push/subscription", %{})
- |> json_response_and_validate_schema(403)
- end
- end
-
- test "returns error when user hasn't subscription", %{conn: conn} do
- res =
- conn
- |> get("/api/v1/push/subscription", %{})
- |> json_response_and_validate_schema(404)
-
- assert %{"error" => "Record not found"} == res
- end
-
- test "returns a user subsciption", %{conn: conn, user: user, token: token} do
- subscription =
- insert(:push_subscription,
- user: user,
- token: token,
- data: %{"alerts" => %{"mention" => true}}
- )
-
- res =
- conn
- |> get("/api/v1/push/subscription", %{})
- |> json_response_and_validate_schema(200)
-
- expect = %{
- "alerts" => %{"mention" => true},
- "endpoint" => "https://example.com/example/1234",
- "id" => to_string(subscription.id),
- "server_key" => @server_key
- }
-
- assert expect == res
- end
- end
-
- describe "updates a user subsciption" do
- setup %{conn: conn, user: user, token: token} do
- subscription =
- insert(:push_subscription,
- user: user,
- token: token,
- data: %{"alerts" => %{"mention" => true}}
- )
-
- %{conn: conn, user: user, token: token, subscription: subscription}
- end
-
- test "returns error when push disabled ", %{conn: conn} do
- assert_error_when_disable_push do
- conn
- |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}})
- |> json_response_and_validate_schema(403)
- end
- end
-
- test "returns updated subsciption", %{conn: conn, subscription: subscription} do
- res =
- conn
- |> put("/api/v1/push/subscription", %{
- data: %{"alerts" => %{"mention" => false, "follow" => true}}
- })
- |> json_response_and_validate_schema(200)
-
- expect = %{
- "alerts" => %{"follow" => true, "mention" => false},
- "endpoint" => "https://example.com/example/1234",
- "id" => to_string(subscription.id),
- "server_key" => @server_key
- }
-
- assert expect == res
- end
- end
-
- describe "deletes the user subscription" do
- test "returns error when push disabled ", %{conn: conn} do
- assert_error_when_disable_push do
- conn
- |> delete("/api/v1/push/subscription", %{})
- |> json_response_and_validate_schema(403)
- end
- end
-
- test "returns error when user hasn't subscription", %{conn: conn} do
- res =
- conn
- |> delete("/api/v1/push/subscription", %{})
- |> json_response_and_validate_schema(404)
-
- assert %{"error" => "Record not found"} == res
- end
-
- test "returns empty result and delete user subsciption", %{
- conn: conn,
- user: user,
- token: token
- } do
- subscription =
- insert(:push_subscription,
- user: user,
- token: token,
- data: %{"alerts" => %{"mention" => true}}
- )
-
- res =
- conn
- |> delete("/api/v1/push/subscription", %{})
- |> json_response_and_validate_schema(200)
-
- assert %{} == res
- refute Pleroma.Repo.get(Subscription, subscription.id)
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/web/mastodon_api/controllers/suggestion_controller_test.exs
deleted file mode 100644
index 7f08e187c..000000000
--- a/test/web/mastodon_api/controllers/suggestion_controller_test.exs
+++ /dev/null
@@ -1,18 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
- use Pleroma.Web.ConnCase
-
- setup do: oauth_access(["read"])
-
- test "returns empty result", %{conn: conn} do
- res =
- conn
- |> get("/api/v1/suggestions")
- |> json_response_and_validate_schema(200)
-
- assert res == []
- end
-end
diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs
deleted file mode 100644
index 517cabcff..000000000
--- a/test/web/mastodon_api/controllers/timeline_controller_test.exs
+++ /dev/null
@@ -1,552 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
- import Tesla.Mock
-
- alias Pleroma.Config
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- describe "home" do
- setup do: oauth_access(["read:statuses"])
-
- test "does NOT embed account/pleroma/relationship in statuses", %{
- user: user,
- conn: conn
- } do
- other_user = insert(:user)
-
- {:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
-
- response =
- conn
- |> assign(:user, user)
- |> get("/api/v1/timelines/home")
- |> json_response_and_validate_schema(200)
-
- assert Enum.all?(response, fn n ->
- get_in(n, ["account", "pleroma", "relationship"]) == %{}
- end)
- end
-
- test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do
- {:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
- {:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
-
- {:ok, unlisted_activity} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
-
- {:ok, private_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
-
- conn = get(conn, "/api/v1/timelines/home?exclude_visibilities[]=direct")
-
- assert status_ids = json_response_and_validate_schema(conn, :ok) |> Enum.map(& &1["id"])
- assert public_activity.id in status_ids
- assert unlisted_activity.id in status_ids
- assert private_activity.id in status_ids
- refute direct_activity.id in status_ids
- end
- end
-
- describe "public" do
- @tag capture_log: true
- test "the public timeline", %{conn: conn} do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "test"})
-
- _activity = insert(:note_activity, local: false)
-
- conn = get(conn, "/api/v1/timelines/public?local=False")
-
- assert length(json_response_and_validate_schema(conn, :ok)) == 2
-
- conn = get(build_conn(), "/api/v1/timelines/public?local=True")
-
- assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok)
-
- conn = get(build_conn(), "/api/v1/timelines/public?local=1")
-
- assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok)
-
- # does not contain repeats
- {:ok, _} = CommonAPI.repeat(activity.id, user)
-
- conn = get(build_conn(), "/api/v1/timelines/public?local=true")
-
- assert [_] = json_response_and_validate_schema(conn, :ok)
- end
-
- test "the public timeline includes only public statuses for an authenticated user" do
- %{user: user, conn: conn} = oauth_access(["read:statuses"])
-
- {: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_and_validate_schema(res_conn, 200)) == 1
- end
-
- test "doesn't return replies if follower is posting with blocked user" do
- %{conn: conn, user: blocker} = oauth_access(["read:statuses"])
- [blockee, friend] = insert_list(2, :user)
- {:ok, blocker} = User.follow(blocker, friend)
- {:ok, _} = User.block(blocker, blockee)
-
- conn = assign(conn, :user, blocker)
-
- {:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
-
- {:ok, reply_from_blockee} =
- CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
-
- {:ok, _reply_from_friend} =
- CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
-
- res_conn = get(conn, "/api/v1/timelines/public")
- [%{"id" => ^activity_id}] = json_response_and_validate_schema(res_conn, 200)
- end
-
- test "doesn't return replies if follow is posting with users from blocked domain" do
- %{conn: conn, user: blocker} = oauth_access(["read:statuses"])
- friend = insert(:user)
- blockee = insert(:user, ap_id: "https://example.com/users/blocked")
- {:ok, blocker} = User.follow(blocker, friend)
- {:ok, blocker} = User.block_domain(blocker, "example.com")
-
- conn = assign(conn, :user, blocker)
-
- {:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
-
- {:ok, reply_from_blockee} =
- CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
-
- {:ok, _reply_from_friend} =
- CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
-
- res_conn = get(conn, "/api/v1/timelines/public")
-
- activities = json_response_and_validate_schema(res_conn, 200)
- [%{"id" => ^activity_id}] = activities
- end
- end
-
- defp local_and_remote_activities do
- insert(:note_activity)
- insert(:note_activity, local: false)
- :ok
- end
-
- describe "public with restrict unauthenticated timeline for local and federated timelines" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true)
-
- setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true)
-
- test "if user is unauthenticated", %{conn: conn} do
- res_conn = get(conn, "/api/v1/timelines/public?local=true")
-
- assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
- "error" => "authorization required for timeline view"
- }
-
- res_conn = get(conn, "/api/v1/timelines/public?local=false")
-
- assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
- "error" => "authorization required for timeline view"
- }
- end
-
- test "if user is authenticated" do
- %{conn: conn} = oauth_access(["read:statuses"])
-
- res_conn = get(conn, "/api/v1/timelines/public?local=true")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/timelines/public?local=false")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- end
- end
-
- describe "public with restrict unauthenticated timeline for local" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true)
-
- test "if user is unauthenticated", %{conn: conn} do
- res_conn = get(conn, "/api/v1/timelines/public?local=true")
-
- assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
- "error" => "authorization required for timeline view"
- }
-
- res_conn = get(conn, "/api/v1/timelines/public?local=false")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- end
-
- test "if user is authenticated", %{conn: _conn} do
- %{conn: conn} = oauth_access(["read:statuses"])
-
- res_conn = get(conn, "/api/v1/timelines/public?local=true")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/timelines/public?local=false")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- end
- end
-
- describe "public with restrict unauthenticated timeline for remote" do
- setup do: local_and_remote_activities()
-
- setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true)
-
- test "if user is unauthenticated", %{conn: conn} do
- res_conn = get(conn, "/api/v1/timelines/public?local=true")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/timelines/public?local=false")
-
- assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
- "error" => "authorization required for timeline view"
- }
- end
-
- test "if user is authenticated", %{conn: _conn} do
- %{conn: conn} = oauth_access(["read:statuses"])
-
- res_conn = get(conn, "/api/v1/timelines/public?local=true")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 1
-
- res_conn = get(conn, "/api/v1/timelines/public?local=false")
- assert length(json_response_and_validate_schema(res_conn, 200)) == 2
- 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"
- })
-
- conn_user_two =
- conn
- |> assign(:user, user_two)
- |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"]))
-
- # Only direct should be visible here
- res_conn = get(conn_user_two, "api/v1/timelines/direct")
-
- assert [status] = json_response_and_validate_schema(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)
- |> assign(:token, insert(:oauth_token, user: user_one, scopes: ["read:statuses"]))
- |> get("api/v1/timelines/direct")
-
- [status] = json_response_and_validate_schema(res_conn, :ok)
-
- assert %{"visibility" => "direct"} = status
-
- # Both should be visible here
- res_conn = get(conn_user_two, "api/v1/timelines/home")
-
- [_s1, _s2] = json_response_and_validate_schema(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 = get(conn_user_two, "api/v1/timelines/direct")
-
- statuses = json_response_and_validate_schema(res_conn, :ok)
- assert length(statuses) == 20
-
- max_id = List.last(statuses)["id"]
-
- res_conn = get(conn_user_two, "api/v1/timelines/direct?max_id=#{max_id}")
-
- assert [status] = json_response_and_validate_schema(res_conn, :ok)
-
- assert status["url"] != direct.data["id"]
- end
-
- test "doesn't include DMs from blocked users" do
- %{user: blocker, conn: conn} = oauth_access(["read:statuses"])
- blocked = insert(:user)
- other_user = insert(:user)
- {:ok, _user_relationship} = User.block(blocker, blocked)
-
- {:ok, _blocked_direct} =
- CommonAPI.post(blocked, %{
- status: "Hi @#{blocker.nickname}!",
- visibility: "direct"
- })
-
- {:ok, direct} =
- CommonAPI.post(other_user, %{
- status: "Hi @#{blocker.nickname}!",
- visibility: "direct"
- })
-
- res_conn = get(conn, "api/v1/timelines/direct")
-
- [status] = json_response_and_validate_schema(res_conn, :ok)
- assert status["id"] == direct.id
- end
- end
-
- describe "list" do
- setup do: oauth_access(["read:lists"])
-
- test "does not contain retoots", %{user: user, conn: conn} do
- other_user = insert(:user)
- {:ok, activity_one} = CommonAPI.post(user, %{status: "Marisa is cute."})
- {:ok, activity_two} = CommonAPI.post(other_user, %{status: "Marisa is stupid."})
- {:ok, _} = CommonAPI.repeat(activity_one.id, other_user)
-
- {:ok, list} = Pleroma.List.create("name", user)
- {:ok, list} = Pleroma.List.follow(list, other_user)
-
- conn = get(conn, "/api/v1/timelines/list/#{list.id}")
-
- assert [%{"id" => id}] = json_response_and_validate_schema(conn, :ok)
-
- assert id == to_string(activity_two.id)
- end
-
- test "works with pagination", %{user: user, conn: conn} do
- other_user = insert(:user)
- {:ok, list} = Pleroma.List.create("name", user)
- {:ok, list} = Pleroma.List.follow(list, other_user)
-
- Enum.each(1..30, fn i ->
- CommonAPI.post(other_user, %{status: "post number #{i}"})
- end)
-
- res =
- get(conn, "/api/v1/timelines/list/#{list.id}?limit=1")
- |> json_response_and_validate_schema(:ok)
-
- assert length(res) == 1
-
- [first] = res
-
- res =
- get(conn, "/api/v1/timelines/list/#{list.id}?max_id=#{first["id"]}&limit=30")
- |> json_response_and_validate_schema(:ok)
-
- assert length(res) == 29
- end
-
- test "list timeline", %{user: user, conn: conn} do
- 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 = get(conn, "/api/v1/timelines/list/#{list.id}")
-
- assert [%{"id" => id}] = json_response_and_validate_schema(conn, :ok)
-
- assert id == to_string(activity_two.id)
- end
-
- test "list timeline does not leak non-public statuses for unfollowed users", %{
- user: user,
- conn: conn
- } do
- 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 = get(conn, "/api/v1/timelines/list/#{list.id}")
-
- assert [%{"id" => id}] = json_response_and_validate_schema(conn, :ok)
-
- assert id == to_string(activity_one.id)
- end
- end
-
- describe "hashtag" do
- setup do: oauth_access(["n/a"])
-
- @tag capture_log: true
- test "hashtag timeline", %{conn: conn} do
- following = insert(:user)
-
- {:ok, activity} = CommonAPI.post(following, %{status: "test #2hu"})
-
- nconn = get(conn, "/api/v1/timelines/tag/2hu")
-
- assert [%{"id" => id}] = json_response_and_validate_schema(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_and_validate_schema(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_and_validate_schema(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_and_validate_schema(restricted_test, :ok)
-
- all_test = get(conn, "/api/v1/timelines/tag/test?all[]=none")
-
- assert [status_none] == json_response_and_validate_schema(all_test, :ok)
- end
- end
-
- describe "hashtag timeline handling of :restrict_unauthenticated setting" do
- setup do
- user = insert(:user)
- {:ok, activity1} = CommonAPI.post(user, %{status: "test #tag1"})
- {:ok, _activity2} = CommonAPI.post(user, %{status: "test #tag1"})
-
- activity1
- |> Ecto.Changeset.change(%{local: false})
- |> Pleroma.Repo.update()
-
- base_uri = "/api/v1/timelines/tag/tag1"
- error_response = %{"error" => "authorization required for timeline view"}
-
- %{base_uri: base_uri, error_response: error_response}
- end
-
- defp ensure_authenticated_access(base_uri) do
- %{conn: auth_conn} = oauth_access(["read:statuses"])
-
- res_conn = get(auth_conn, "#{base_uri}?local=true")
- assert length(json_response(res_conn, 200)) == 1
-
- res_conn = get(auth_conn, "#{base_uri}?local=false")
- assert length(json_response(res_conn, 200)) == 2
- end
-
- test "with default settings on private instances, returns 403 for unauthenticated users", %{
- conn: conn,
- base_uri: base_uri,
- error_response: error_response
- } do
- clear_config([:instance, :public], false)
- clear_config([:restrict_unauthenticated, :timelines])
-
- for local <- [true, false] do
- res_conn = get(conn, "#{base_uri}?local=#{local}")
-
- assert json_response(res_conn, :unauthorized) == error_response
- end
-
- ensure_authenticated_access(base_uri)
- end
-
- test "with `%{local: true, federated: true}`, returns 403 for unauthenticated users", %{
- conn: conn,
- base_uri: base_uri,
- error_response: error_response
- } do
- clear_config([:restrict_unauthenticated, :timelines, :local], true)
- clear_config([:restrict_unauthenticated, :timelines, :federated], true)
-
- for local <- [true, false] do
- res_conn = get(conn, "#{base_uri}?local=#{local}")
-
- assert json_response(res_conn, :unauthorized) == error_response
- end
-
- ensure_authenticated_access(base_uri)
- end
-
- test "with `%{local: false, federated: true}`, forbids unauthenticated access to federated timeline",
- %{conn: conn, base_uri: base_uri, error_response: error_response} do
- clear_config([:restrict_unauthenticated, :timelines, :local], false)
- clear_config([:restrict_unauthenticated, :timelines, :federated], true)
-
- res_conn = get(conn, "#{base_uri}?local=true")
- assert length(json_response(res_conn, 200)) == 1
-
- res_conn = get(conn, "#{base_uri}?local=false")
- assert json_response(res_conn, :unauthorized) == error_response
-
- ensure_authenticated_access(base_uri)
- end
-
- test "with `%{local: true, federated: false}`, forbids unauthenticated access to public timeline" <>
- "(but not to local public activities which are delivered as part of federated timeline)",
- %{conn: conn, base_uri: base_uri, error_response: error_response} do
- clear_config([:restrict_unauthenticated, :timelines, :local], true)
- clear_config([:restrict_unauthenticated, :timelines, :federated], false)
-
- res_conn = get(conn, "#{base_uri}?local=true")
- assert json_response(res_conn, :unauthorized) == error_response
-
- # Note: local activities get delivered as part of federated timeline
- res_conn = get(conn, "#{base_uri}?local=false")
- assert length(json_response(res_conn, 200)) == 2
-
- ensure_authenticated_access(base_uri)
- end
- end
-end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
deleted file mode 100644
index bb4bc4396..000000000
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ /dev/null
@@ -1,34 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
- use Pleroma.Web.ConnCase
-
- describe "empty_array/2 (stubs)" do
- test "GET /api/v1/accounts/:id/identity_proofs" do
- %{user: user, conn: conn} = oauth_access(["read:accounts"])
-
- assert [] ==
- conn
- |> get("/api/v1/accounts/#{user.id}/identity_proofs")
- |> json_response(200)
- end
-
- test "GET /api/v1/endorsements" do
- %{conn: conn} = oauth_access(["read:accounts"])
-
- assert [] ==
- conn
- |> get("/api/v1/endorsements")
- |> json_response(200)
- end
-
- test "GET /api/v1/trends", %{conn: conn} do
- assert [] ==
- conn
- |> get("/api/v1/trends")
- |> json_response(200)
- end
- end
-end
diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/web/mastodon_api/mastodon_api_test.exs
deleted file mode 100644
index 0c5a38bf6..000000000
--- a/test/web/mastodon_api/mastodon_api_test.exs
+++ /dev/null
@@ -1,103 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Notification
- alias Pleroma.ScheduledActivity
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI.MastodonAPI
-
- import Pleroma.Factory
-
- describe "follow/3" do
- test "returns error when followed user is deactivated" do
- follower = insert(:user)
- user = insert(:user, local: true, deactivated: true)
- assert {:error, _error} = MastodonAPI.follow(follower, user)
- end
-
- test "following for user" do
- follower = insert(:user)
- user = insert(:user)
- {:ok, follower} = MastodonAPI.follow(follower, user)
- assert User.following?(follower, user)
- end
-
- test "returns ok if user already followed" do
- follower = insert(:user)
- user = insert(:user)
- {:ok, follower} = User.follow(follower, user)
- {:ok, follower} = MastodonAPI.follow(follower, refresh_record(user))
- assert User.following?(follower, user)
- end
- end
-
- describe "get_followers/2" do
- test "returns user followers" do
- follower1_user = insert(:user)
- follower2_user = insert(:user)
- user = insert(:user)
- {:ok, _follower1_user} = User.follow(follower1_user, user)
- {:ok, follower2_user} = User.follow(follower2_user, user)
-
- assert MastodonAPI.get_followers(user, %{"limit" => 1}) == [follower2_user]
- end
- end
-
- describe "get_friends/2" do
- test "returns user friends" do
- user = insert(:user)
- followed_one = insert(:user)
- followed_two = insert(:user)
- followed_three = insert(:user)
-
- {:ok, user} = User.follow(user, followed_one)
- {:ok, user} = User.follow(user, followed_two)
- {:ok, user} = User.follow(user, followed_three)
- res = MastodonAPI.get_friends(user)
-
- assert length(res) == 3
- assert Enum.member?(res, refresh_record(followed_three))
- assert Enum.member?(res, refresh_record(followed_two))
- assert Enum.member?(res, refresh_record(followed_one))
- end
- end
-
- describe "get_notifications/2" do
- test "returns notifications for user" do
- user = insert(:user)
- subscriber = insert(:user)
-
- User.subscribe(subscriber, user)
-
- {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
-
- {:ok, status1} = CommonAPI.post(user, %{status: "Magi"})
- {:ok, [notification]} = Notification.create_notifications(status)
- {:ok, [notification1]} = Notification.create_notifications(status1)
- res = MastodonAPI.get_notifications(subscriber)
-
- assert Enum.member?(Enum.map(res, & &1.id), notification.id)
- assert Enum.member?(Enum.map(res, & &1.id), notification1.id)
- end
- end
-
- describe "get_scheduled_activities/2" do
- test "returns user scheduled activities" do
- user = insert(:user)
-
- today =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
- |> NaiveDateTime.to_iso8601()
-
- attrs = %{params: %{}, scheduled_at: today}
- {:ok, schedule} = ScheduledActivity.create(user, attrs)
- assert MastodonAPI.get_scheduled_activities(user) == [schedule]
- 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
deleted file mode 100644
index 68a5d0091..000000000
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ /dev/null
@@ -1,572 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.User
- alias Pleroma.UserRelationship
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI.AccountView
-
- import Pleroma.Factory
- import Tesla.Mock
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "Represent a user account" do
- background_image = %{
- "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
- }
-
- user =
- insert(:user, %{
- follower_count: 3,
- note_count: 5,
- background: background_image,
- nickname: "shp@shitposter.club",
- name: ":karjalanpiirakka: shp",
- bio:
- "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"",
- inserted_at: ~N[2017-08-15 15:47:06.597036],
- emoji: %{"karjalanpiirakka" => "/file.png"},
- raw_bio: "valid html. a\nb\nc\nd\nf '&<>\""
- })
-
- expected = %{
- id: to_string(user.id),
- username: "shp",
- acct: user.nickname,
- display_name: user.name,
- locked: false,
- created_at: "2017-08-15T15:47:06.000Z",
- followers_count: 3,
- following_count: 0,
- statuses_count: 5,
- note: "<span>valid html</span>. a<br/>b<br/>c<br/>d<br/>f &#39;&amp;&lt;&gt;&quot;",
- url: user.ap_id,
- avatar: "http://localhost:4001/images/avi.png",
- avatar_static: "http://localhost:4001/images/avi.png",
- header: "http://localhost:4001/images/banner.png",
- header_static: "http://localhost:4001/images/banner.png",
- emojis: [
- %{
- static_url: "/file.png",
- url: "/file.png",
- shortcode: "karjalanpiirakka",
- visible_in_picker: false
- }
- ],
- fields: [],
- bot: false,
- source: %{
- note: "valid html. a\nb\nc\nd\nf '&<>\"",
- sensitive: false,
- pleroma: %{
- actor_type: "Person",
- discoverable: false
- },
- fields: []
- },
- pleroma: %{
- ap_id: user.ap_id,
- background_image: "https://example.com/images/asuka_hospital.png",
- favicon: nil,
- confirmation_pending: false,
- tags: [],
- is_admin: false,
- is_moderator: false,
- hide_favorites: true,
- hide_followers: false,
- hide_follows: false,
- hide_followers_count: false,
- hide_follows_count: false,
- relationship: %{},
- skip_thread_containment: false,
- accepts_chat_messages: nil
- }
- }
-
- assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- end
-
- describe "favicon" do
- setup do
- [user: insert(:user)]
- end
-
- test "is parsed when :instance_favicons is enabled", %{user: user} do
- clear_config([:instances_favicons, :enabled], true)
-
- assert %{
- pleroma: %{
- favicon:
- "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png"
- }
- } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- end
-
- test "is nil when :instances_favicons is disabled", %{user: user} do
- assert %{pleroma: %{favicon: nil}} =
- AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- end
- end
-
- test "Favicon when :instance_favicons is enabled" do
- end
-
- test "Represent the user account for the account owner" do
- user = insert(:user)
-
- notification_settings = %{
- block_from_strangers: false,
- hide_notification_contents: false
- }
-
- privacy = user.default_scope
-
- assert %{
- pleroma: %{notification_settings: ^notification_settings, allow_following_move: true},
- source: %{privacy: ^privacy}
- } = AccountView.render("show.json", %{user: user, for: user})
- end
-
- test "Represent a Service(bot) account" do
- user =
- insert(:user, %{
- follower_count: 3,
- note_count: 5,
- actor_type: "Service",
- nickname: "shp@shitposter.club",
- inserted_at: ~N[2017-08-15 15:47:06.597036]
- })
-
- expected = %{
- id: to_string(user.id),
- username: "shp",
- acct: user.nickname,
- display_name: user.name,
- locked: false,
- created_at: "2017-08-15T15:47:06.000Z",
- followers_count: 3,
- following_count: 0,
- statuses_count: 5,
- note: user.bio,
- url: user.ap_id,
- avatar: "http://localhost:4001/images/avi.png",
- avatar_static: "http://localhost:4001/images/avi.png",
- header: "http://localhost:4001/images/banner.png",
- header_static: "http://localhost:4001/images/banner.png",
- emojis: [],
- fields: [],
- bot: true,
- source: %{
- note: user.bio,
- sensitive: false,
- pleroma: %{
- actor_type: "Service",
- discoverable: false
- },
- fields: []
- },
- pleroma: %{
- ap_id: user.ap_id,
- background_image: nil,
- favicon: nil,
- confirmation_pending: false,
- tags: [],
- is_admin: false,
- is_moderator: false,
- hide_favorites: true,
- hide_followers: false,
- hide_follows: false,
- hide_followers_count: false,
- hide_follows_count: false,
- relationship: %{},
- skip_thread_containment: false,
- accepts_chat_messages: nil
- }
- }
-
- assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- end
-
- test "Represent a Funkwhale channel" do
- {:ok, user} =
- User.get_or_fetch_by_ap_id(
- "https://channels.tests.funkwhale.audio/federation/actors/compositions"
- )
-
- assert represented =
- AccountView.render("show.json", %{user: user, skip_visibility_check: true})
-
- assert represented.acct == "compositions@channels.tests.funkwhale.audio"
- assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions"
- end
-
- test "Represent a deactivated user for an admin" do
- admin = insert(:user, is_admin: true)
- deactivated_user = insert(:user, deactivated: true)
- represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
- assert represented[:pleroma][:deactivated] == true
- end
-
- test "Represent a smaller mention" do
- user = insert(:user)
-
- expected = %{
- id: to_string(user.id),
- acct: user.nickname,
- username: user.nickname,
- url: user.ap_id
- }
-
- assert expected == AccountView.render("mention.json", %{user: user})
- end
-
- test "demands :for or :skip_visibility_check option for account rendering" do
- clear_config([:restrict_unauthenticated, :profiles, :local], false)
-
- user = insert(:user)
- user_id = user.id
-
- assert %{id: ^user_id} = AccountView.render("show.json", %{user: user, for: nil})
- assert %{id: ^user_id} = AccountView.render("show.json", %{user: user, for: user})
-
- assert %{id: ^user_id} =
- AccountView.render("show.json", %{user: user, skip_visibility_check: true})
-
- assert_raise RuntimeError, ~r/:skip_visibility_check or :for option is required/, fn ->
- AccountView.render("show.json", %{user: user})
- end
- end
-
- describe "relationship" do
- defp test_relationship_rendering(user, other_user, expected_result) do
- opts = %{user: user, target: other_user, relationships: nil}
- assert expected_result == AccountView.render("relationship.json", opts)
-
- relationships_opt = UserRelationship.view_relationships_option(user, [other_user])
- opts = Map.put(opts, :relationships, relationships_opt)
- assert expected_result == AccountView.render("relationship.json", opts)
-
- assert [expected_result] ==
- AccountView.render("relationships.json", %{user: user, targets: [other_user]})
- end
-
- @blank_response %{
- following: false,
- followed_by: false,
- blocking: false,
- blocked_by: false,
- muting: false,
- muting_notifications: false,
- subscribing: false,
- requested: false,
- domain_blocking: false,
- showing_reblogs: true,
- endorsed: false
- }
-
- test "represent a relationship for the following and followed user" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, user} = User.follow(user, other_user)
- {:ok, other_user} = User.follow(other_user, user)
- {:ok, _subscription} = User.subscribe(user, other_user)
- {:ok, _user_relationships} = User.mute(user, other_user, true)
- {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
-
- expected =
- Map.merge(
- @blank_response,
- %{
- following: true,
- followed_by: true,
- muting: true,
- muting_notifications: true,
- subscribing: true,
- showing_reblogs: false,
- id: to_string(other_user.id)
- }
- )
-
- test_relationship_rendering(user, other_user, expected)
- end
-
- test "represent a relationship for the blocking and blocked user" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, user} = User.follow(user, other_user)
- {:ok, _subscription} = User.subscribe(user, other_user)
- {:ok, _user_relationship} = User.block(user, other_user)
- {:ok, _user_relationship} = User.block(other_user, user)
-
- expected =
- Map.merge(
- @blank_response,
- %{following: false, blocking: true, blocked_by: true, id: to_string(other_user.id)}
- )
-
- test_relationship_rendering(user, other_user, expected)
- end
-
- test "represent a relationship for the user blocking a domain" do
- user = insert(:user)
- other_user = insert(:user, ap_id: "https://bad.site/users/other_user")
-
- {:ok, user} = User.block_domain(user, "bad.site")
-
- expected =
- Map.merge(
- @blank_response,
- %{domain_blocking: true, blocking: false, id: to_string(other_user.id)}
- )
-
- test_relationship_rendering(user, other_user, expected)
- end
-
- test "represent a relationship for the user with a pending follow request" do
- user = insert(:user)
- other_user = insert(:user, locked: true)
-
- {:ok, user, other_user, _} = CommonAPI.follow(user, other_user)
- user = User.get_cached_by_id(user.id)
- other_user = User.get_cached_by_id(other_user.id)
-
- expected =
- Map.merge(
- @blank_response,
- %{requested: true, following: false, id: to_string(other_user.id)}
- )
-
- test_relationship_rendering(user, other_user, expected)
- end
- end
-
- test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
- user = insert(:user, pleroma_settings_store: %{fe: "test"})
-
- result =
- AccountView.render("show.json", %{user: user, for: user, with_pleroma_settings: true})
-
- assert result.pleroma.settings_store == %{:fe => "test"}
-
- result = AccountView.render("show.json", %{user: user, for: nil, with_pleroma_settings: true})
- assert result.pleroma[:settings_store] == nil
-
- result = AccountView.render("show.json", %{user: user, for: user})
- assert result.pleroma[:settings_store] == nil
- end
-
- test "doesn't sanitize display names" do
- user = insert(:user, name: "<marquee> username </marquee>")
- result = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- assert result.display_name == "<marquee> username </marquee>"
- end
-
- test "never display nil user follow counts" do
- user = insert(:user, following_count: 0, follower_count: 0)
- result = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
-
- assert result.following_count == 0
- assert result.followers_count == 0
- end
-
- describe "hiding follows/following" do
- test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
- user =
- insert(:user, %{
- hide_followers: true,
- hide_followers_count: true,
- hide_follows: true,
- hide_follows_count: 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: 0,
- following_count: 0,
- pleroma: %{hide_follows_count: true, hide_followers_count: true}
- } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- end
-
- test "shows when follows/followers are hidden" do
- user = insert(:user, 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("show.json", %{user: user, skip_visibility_check: true})
- end
-
- test "shows actual follower/following count to the account owner" do
- user = insert(:user, hide_followers: true, hide_follows: true)
- other_user = insert(:user)
- {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
-
- assert User.following?(user, other_user)
- assert Pleroma.FollowingRelationship.follower_count(other_user) == 1
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
-
- assert %{
- followers_count: 1,
- following_count: 1
- } = AccountView.render("show.json", %{user: user, for: user})
- end
-
- test "shows unread_conversation_count only to the account owner" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, _activity} =
- CommonAPI.post(other_user, %{
- status: "Hey @#{user.nickname}.",
- visibility: "direct"
- })
-
- user = User.get_cached_by_ap_id(user.ap_id)
-
- assert AccountView.render("show.json", %{user: user, for: other_user})[:pleroma][
- :unread_conversation_count
- ] == nil
-
- assert AccountView.render("show.json", %{user: user, for: user})[:pleroma][
- :unread_conversation_count
- ] == 1
- end
-
- test "shows unread_count only to the account owner" do
- user = insert(:user)
- insert_list(7, :notification, user: user)
- other_user = insert(:user)
-
- user = User.get_cached_by_ap_id(user.ap_id)
-
- assert AccountView.render(
- "show.json",
- %{user: user, for: other_user}
- )[:pleroma][:unread_notifications_count] == nil
-
- assert AccountView.render(
- "show.json",
- %{user: user, for: user}
- )[:pleroma][:unread_notifications_count] == 7
- 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("show.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("show.json", %{user: user, for: user})
- end
-
- test "shows non-zero when follow requests are pending" do
- user = insert(:user, locked: true)
-
- assert %{locked: true} = AccountView.render("show.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("show.json", %{user: user, for: user})
- end
-
- test "decreases when accepting a follow request" do
- user = insert(:user, locked: true)
-
- assert %{locked: true} = AccountView.render("show.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("show.json", %{user: user, for: user})
-
- {:ok, _other_user} = CommonAPI.accept_follow_request(other_user, user)
-
- assert %{locked: true, follow_requests_count: 0} =
- AccountView.render("show.json", %{user: user, for: user})
- end
-
- test "decreases when rejecting a follow request" do
- user = insert(:user, locked: true)
-
- assert %{locked: true} = AccountView.render("show.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("show.json", %{user: user, for: user})
-
- {:ok, _other_user} = CommonAPI.reject_follow_request(other_user, user)
-
- assert %{locked: true, follow_requests_count: 0} =
- AccountView.render("show.json", %{user: user, for: user})
- end
-
- test "shows non-zero when historical unapproved requests are present" do
- user = insert(:user, locked: true)
-
- assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
-
- other_user = insert(:user)
- {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
-
- {:ok, user} = User.update_and_set_cache(user, %{locked: false})
-
- assert %{locked: false, follow_requests_count: 1} =
- AccountView.render("show.json", %{user: user, for: user})
- end
- end
-
- test "uses mediaproxy urls when it's enabled" do
- clear_config([:media_proxy, :enabled], true)
-
- user =
- insert(:user,
- avatar: %{"url" => [%{"href" => "https://evil.website/avatar.png"}]},
- banner: %{"url" => [%{"href" => "https://evil.website/banner.png"}]},
- emoji: %{"joker_smile" => "https://evil.website/society.png"}
- )
-
- AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- |> Enum.all?(fn
- {key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
- String.starts_with?(url, Pleroma.Web.base_url())
-
- {:emojis, emojis} ->
- Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
- String.starts_with?(url, Pleroma.Web.base_url()) &&
- String.starts_with?(static_url, Pleroma.Web.base_url())
- end)
-
- _ ->
- true
- end)
- |> assert()
- end
-end
diff --git a/test/web/mastodon_api/views/conversation_view_test.exs b/test/web/mastodon_api/views/conversation_view_test.exs
deleted file mode 100644
index 2e8203c9b..000000000
--- a/test/web/mastodon_api/views/conversation_view_test.exs
+++ /dev/null
@@ -1,44 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Conversation.Participation
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI.ConversationView
-
- import Pleroma.Factory
-
- test "represents a Mastodon Conversation entity" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, parent} = CommonAPI.post(user, %{status: "parent"})
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "hey @#{other_user.nickname}",
- visibility: "direct",
- in_reply_to_id: parent.id
- })
-
- {:ok, _reply_activity} =
- CommonAPI.post(user, %{status: "hu", visibility: "public", in_reply_to_id: parent.id})
-
- [participation] = Participation.for_user_with_last_activity_id(user)
-
- assert participation
-
- conversation =
- ConversationView.render("participation.json", %{participation: participation, for: user})
-
- assert conversation.id == participation.id |> to_string()
- assert conversation.last_status.id == activity.id
-
- assert [account] = conversation.accounts
- assert account.id == other_user.id
- assert conversation.last_status.pleroma.direct_conversation_id == participation.id
- end
-end
diff --git a/test/web/mastodon_api/views/list_view_test.exs b/test/web/mastodon_api/views/list_view_test.exs
deleted file mode 100644
index ca99242cb..000000000
--- a/test/web/mastodon_api/views/list_view_test.exs
+++ /dev/null
@@ -1,32 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ListViewTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.MastodonAPI.ListView
-
- test "show" do
- user = insert(:user)
- title = "mortal enemies"
- {:ok, list} = Pleroma.List.create(title, user)
-
- expected = %{
- id: to_string(list.id),
- title: title
- }
-
- assert expected == ListView.render("show.json", %{list: list})
- end
-
- test "index" do
- user = insert(:user)
-
- {:ok, list} = Pleroma.List.create("my list", user)
- {:ok, list2} = Pleroma.List.create("cofe", user)
-
- assert [%{id: _, title: "my list"}, %{id: _, title: "cofe"}] =
- ListView.render("index.json", lists: [list, list2])
- end
-end
diff --git a/test/web/mastodon_api/views/marker_view_test.exs b/test/web/mastodon_api/views/marker_view_test.exs
deleted file mode 100644
index 48a0a6d33..000000000
--- a/test/web/mastodon_api/views/marker_view_test.exs
+++ /dev/null
@@ -1,29 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MarkerViewTest do
- use Pleroma.DataCase
- alias Pleroma.Web.MastodonAPI.MarkerView
- import Pleroma.Factory
-
- test "returns markers" do
- marker1 = insert(:marker, timeline: "notifications", last_read_id: "17", unread_count: 5)
- marker2 = insert(:marker, timeline: "home", last_read_id: "42")
-
- assert MarkerView.render("markers.json", %{markers: [marker1, marker2]}) == %{
- "home" => %{
- last_read_id: "42",
- updated_at: NaiveDateTime.to_iso8601(marker2.updated_at),
- version: 0,
- pleroma: %{unread_count: 0}
- },
- "notifications" => %{
- last_read_id: "17",
- updated_at: NaiveDateTime.to_iso8601(marker1.updated_at),
- version: 0,
- pleroma: %{unread_count: 5}
- }
- }
- end
-end
diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs
deleted file mode 100644
index 2f6a808f1..000000000
--- a/test/web/mastodon_api/views/notification_view_test.exs
+++ /dev/null
@@ -1,231 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Notification
- alias Pleroma.Object
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.CommonAPI.Utils
- alias Pleroma.Web.MastodonAPI.AccountView
- alias Pleroma.Web.MastodonAPI.NotificationView
- alias Pleroma.Web.MastodonAPI.StatusView
- alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
- import Pleroma.Factory
-
- defp test_notifications_rendering(notifications, user, expected_result) do
- result = NotificationView.render("index.json", %{notifications: notifications, for: user})
-
- assert expected_result == result
-
- result =
- NotificationView.render("index.json", %{
- notifications: notifications,
- for: user,
- relationships: nil
- })
-
- assert expected_result == result
- end
-
- test "ChatMessage notification" do
- user = insert(:user)
- recipient = insert(:user)
- {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "what's up my dude")
-
- {:ok, [notification]} = Notification.create_notifications(activity)
-
- object = Object.normalize(activity)
- chat = Chat.get(recipient.id, user.ap_id)
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "pleroma:chat_mention",
- account: AccountView.render("show.json", %{user: user, for: recipient}),
- chat_message: MessageReferenceView.render("show.json", %{chat_message_reference: cm_ref}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], recipient, [expected])
- end
-
- test "Mention notification" do
- user = insert(:user)
- mentioned_user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{mentioned_user.nickname}"})
- {:ok, [notification]} = Notification.create_notifications(activity)
- user = User.get_cached_by_id(user.id)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "mention",
- account:
- AccountView.render("show.json", %{
- user: user,
- for: mentioned_user
- }),
- status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], mentioned_user, [expected])
- end
-
- test "Favourite notification" do
- user = insert(:user)
- another_user = insert(:user)
- {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id)
- {:ok, [notification]} = Notification.create_notifications(favorite_activity)
- create_activity = Activity.get_by_id(create_activity.id)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "favourite",
- account: AccountView.render("show.json", %{user: another_user, for: user}),
- status: StatusView.render("show.json", %{activity: create_activity, for: user}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], user, [expected])
- end
-
- test "Reblog notification" do
- user = insert(:user)
- another_user = insert(:user)
- {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, another_user)
- {:ok, [notification]} = Notification.create_notifications(reblog_activity)
- reblog_activity = Activity.get_by_id(create_activity.id)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "reblog",
- account: AccountView.render("show.json", %{user: another_user, for: user}),
- status: StatusView.render("show.json", %{activity: reblog_activity, for: user}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], user, [expected])
- end
-
- test "Follow notification" do
- follower = insert(:user)
- followed = insert(:user)
- {:ok, follower, followed, _activity} = CommonAPI.follow(follower, followed)
- notification = Notification |> Repo.one() |> Repo.preload(:activity)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "follow",
- account: AccountView.render("show.json", %{user: follower, for: followed}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], followed, [expected])
-
- User.perform(:delete, follower)
- refute Repo.one(Notification)
- end
-
- @tag capture_log: true
- test "Move notification" do
- old_user = insert(:user)
- new_user = insert(:user, also_known_as: [old_user.ap_id])
- follower = insert(:user)
-
- old_user_url = old_user.ap_id
-
- body =
- File.read!("test/fixtures/users_mock/localhost.json")
- |> String.replace("{{nickname}}", old_user.nickname)
- |> Jason.encode!()
-
- Tesla.Mock.mock(fn
- %{method: :get, url: ^old_user_url} ->
- %Tesla.Env{status: 200, body: body}
- end)
-
- User.follow(follower, old_user)
- Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
- Pleroma.Tests.ObanHelpers.perform_all()
-
- old_user = refresh_record(old_user)
- new_user = refresh_record(new_user)
-
- [notification] = Notification.for_user(follower)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "move",
- account: AccountView.render("show.json", %{user: old_user, for: follower}),
- target: AccountView.render("show.json", %{user: new_user, for: follower}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], follower, [expected])
- end
-
- test "EmojiReact notification" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
- {:ok, _activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
-
- activity = Repo.get(Activity, activity.id)
-
- [notification] = Notification.for_user(user)
-
- assert notification
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: false, is_muted: false},
- type: "pleroma:emoji_reaction",
- emoji: "☕",
- account: AccountView.render("show.json", %{user: other_user, for: user}),
- status: StatusView.render("show.json", %{activity: activity, for: user}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], user, [expected])
- end
-
- test "muted notification" do
- user = insert(:user)
- another_user = insert(:user)
-
- {:ok, _} = Pleroma.UserRelationship.create_mute(user, another_user)
- {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id)
- {:ok, [notification]} = Notification.create_notifications(favorite_activity)
- create_activity = Activity.get_by_id(create_activity.id)
-
- expected = %{
- id: to_string(notification.id),
- pleroma: %{is_seen: true, is_muted: true},
- type: "favourite",
- account: AccountView.render("show.json", %{user: another_user, for: user}),
- status: StatusView.render("show.json", %{activity: create_activity, for: user}),
- created_at: Utils.to_masto_date(notification.inserted_at)
- }
-
- test_notifications_rendering([notification], user, [expected])
- end
-end
diff --git a/test/web/mastodon_api/views/poll_view_test.exs b/test/web/mastodon_api/views/poll_view_test.exs
deleted file mode 100644
index b7e2f17ef..000000000
--- a/test/web/mastodon_api/views/poll_view_test.exs
+++ /dev/null
@@ -1,167 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.PollViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Object
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI.PollView
-
- import Pleroma.Factory
- import Tesla.Mock
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "renders a poll" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Is Tenshi eating a corndog cute?",
- poll: %{
- options: ["absolutely!", "sure", "yes", "why are you even asking?"],
- expires_in: 20
- }
- })
-
- object = Object.normalize(activity)
-
- expected = %{
- emojis: [],
- expired: false,
- id: to_string(object.id),
- multiple: false,
- options: [
- %{title: "absolutely!", votes_count: 0},
- %{title: "sure", votes_count: 0},
- %{title: "yes", votes_count: 0},
- %{title: "why are you even asking?", votes_count: 0}
- ],
- voted: false,
- votes_count: 0,
- voters_count: nil
- }
-
- result = PollView.render("show.json", %{object: object})
- expires_at = result.expires_at
- result = Map.delete(result, :expires_at)
-
- assert result == expected
-
- expires_at = NaiveDateTime.from_iso8601!(expires_at)
- assert NaiveDateTime.diff(expires_at, NaiveDateTime.utc_now()) in 15..20
- end
-
- test "detects if it is multiple choice" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Which Mastodon developer is your favourite?",
- poll: %{
- options: ["Gargron", "Eugen"],
- expires_in: 20,
- multiple: true
- }
- })
-
- voter = insert(:user)
-
- object = Object.normalize(activity)
-
- {:ok, _votes, object} = CommonAPI.vote(voter, object, [0, 1])
-
- assert match?(
- %{
- multiple: true,
- voters_count: 1,
- votes_count: 2
- },
- PollView.render("show.json", %{object: object})
- )
- end
-
- test "detects emoji" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "What's with the smug face?",
- poll: %{
- options: [":blank: sip", ":blank::blank: sip", ":blank::blank::blank: sip"],
- expires_in: 20
- }
- })
-
- object = Object.normalize(activity)
-
- assert %{emojis: [%{shortcode: "blank"}]} = PollView.render("show.json", %{object: object})
- end
-
- test "detects vote status" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "Which input devices do you use?",
- poll: %{
- options: ["mouse", "trackball", "trackpoint"],
- multiple: true,
- expires_in: 20
- }
- })
-
- object = Object.normalize(activity)
-
- {:ok, _, object} = CommonAPI.vote(other_user, object, [1, 2])
-
- result = PollView.render("show.json", %{object: object, for: other_user})
-
- assert result[:voted] == true
- assert Enum.at(result[:options], 1)[:votes_count] == 1
- assert Enum.at(result[:options], 2)[:votes_count] == 1
- end
-
- test "does not crash on polls with no end date" do
- object = Object.normalize("https://skippers-bin.com/notes/7x9tmrp97i")
- result = PollView.render("show.json", %{object: object})
-
- assert result[:expires_at] == nil
- assert result[:expired] == false
- end
-
- test "doesn't strips HTML tags" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "What's with the smug face?",
- poll: %{
- options: [
- "<input type=\"date\">",
- "<input type=\"date\" >",
- "<input type=\"date\"/>",
- "<input type=\"date\"></input>"
- ],
- expires_in: 20
- }
- })
-
- object = Object.normalize(activity)
-
- assert %{
- options: [
- %{title: "<input type=\"date\">", votes_count: 0},
- %{title: "<input type=\"date\" >", votes_count: 0},
- %{title: "<input type=\"date\"/>", votes_count: 0},
- %{title: "<input type=\"date\"></input>", votes_count: 0}
- ]
- } = PollView.render("show.json", %{object: object})
- end
-end
diff --git a/test/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/web/mastodon_api/views/scheduled_activity_view_test.exs
deleted file mode 100644
index fbfd873ef..000000000
--- a/test/web/mastodon_api/views/scheduled_activity_view_test.exs
+++ /dev/null
@@ -1,68 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
- use Pleroma.DataCase
- alias Pleroma.ScheduledActivity
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.CommonAPI.Utils
- alias Pleroma.Web.MastodonAPI.ScheduledActivityView
- alias Pleroma.Web.MastodonAPI.StatusView
- import Pleroma.Factory
-
- test "A scheduled activity with a media attachment" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hi"})
-
- scheduled_at =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(10), :millisecond)
- |> NaiveDateTime.to_iso8601()
-
- 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)
-
- attrs = %{
- params: %{
- "media_ids" => [upload.id],
- "status" => "hi",
- "sensitive" => true,
- "spoiler_text" => "spoiler",
- "visibility" => "unlisted",
- "in_reply_to_id" => to_string(activity.id)
- },
- scheduled_at: scheduled_at
- }
-
- {:ok, scheduled_activity} = ScheduledActivity.create(user, attrs)
- result = ScheduledActivityView.render("show.json", %{scheduled_activity: scheduled_activity})
-
- expected = %{
- id: to_string(scheduled_activity.id),
- media_attachments:
- %{media_ids: [upload.id]}
- |> Utils.attachments_from_ids()
- |> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})),
- params: %{
- in_reply_to_id: to_string(activity.id),
- media_ids: [upload.id],
- poll: nil,
- scheduled_at: nil,
- sensitive: true,
- spoiler_text: "spoiler",
- text: "hi",
- visibility: "unlisted"
- },
- scheduled_at: Utils.to_masto_date(scheduled_activity.scheduled_at)
- }
-
- assert expected == result
- end
-end
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs
deleted file mode 100644
index 70d829979..000000000
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ /dev/null
@@ -1,664 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Activity
- alias Pleroma.Bookmark
- alias Pleroma.Conversation.Participation
- alias Pleroma.HTML
- alias Pleroma.Object
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.UserRelationship
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.CommonAPI.Utils
- alias Pleroma.Web.MastodonAPI.AccountView
- alias Pleroma.Web.MastodonAPI.StatusView
-
- import Pleroma.Factory
- import Tesla.Mock
- import OpenApiSpex.TestAssertions
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "has an emoji reaction list" do
- user = insert(:user)
- other_user = insert(:user)
- third_user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
-
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "☕")
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
- activity = Repo.get(Activity, activity.id)
- status = StatusView.render("show.json", activity: activity)
-
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
-
- assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 2, me: false},
- %{name: "🍵", count: 1, me: false}
- ]
-
- status = StatusView.render("show.json", activity: activity, for: user)
-
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
-
- assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 2, me: true},
- %{name: "🍵", count: 1, me: false}
- ]
- end
-
- test "works correctly with badly formatted emojis" do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "yo"})
-
- activity
- |> Object.normalize(false)
- |> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
-
- activity = Activity.get_by_id(activity.id)
-
- status = StatusView.render("show.json", activity: activity, for: user)
-
- assert status[:pleroma][:emoji_reactions] == [
- %{name: "☕", count: 1, me: true}
- ]
- end
-
- test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
- [participation] = Participation.for_user(user)
-
- status =
- StatusView.render("show.json",
- activity: activity,
- with_direct_conversation_id: true,
- for: user
- )
-
- assert status[:pleroma][:direct_conversation_id] == participation.id
-
- status = StatusView.render("show.json", activity: activity, for: user)
- assert status[:pleroma][:direct_conversation_id] == nil
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "returns the direct conversation id when given the `direct_conversation_id` option" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
- [participation] = Participation.for_user(user)
-
- status =
- StatusView.render("show.json",
- activity: activity,
- direct_conversation_id: participation.id,
- for: user
- )
-
- assert status[:pleroma][:direct_conversation_id] == participation.id
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "returns a temporary ap_id based user for activities missing db users" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
-
- Repo.delete(user)
- Cachex.clear(:user_cache)
-
- finger_url =
- "https://localhost/.well-known/webfinger?resource=acct:#{user.nickname}@localhost"
-
- Tesla.Mock.mock_global(fn
- %{method: :get, url: "http://localhost/.well-known/host-meta"} ->
- %Tesla.Env{status: 404, body: ""}
-
- %{method: :get, url: "https://localhost/.well-known/host-meta"} ->
- %Tesla.Env{status: 404, body: ""}
-
- %{
- method: :get,
- url: ^finger_url
- } ->
- %Tesla.Env{status: 404, body: ""}
- end)
-
- %{account: ms_user} = StatusView.render("show.json", activity: activity)
-
- assert ms_user.acct == "erroruser@example.com"
- end
-
- test "tries to get a user by nickname if fetching by ap_id doesn't work" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
-
- {:ok, user} =
- user
- |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"})
- |> Repo.update()
-
- Cachex.clear(:user_cache)
-
- result = StatusView.render("show.json", activity: activity)
-
- assert result[:account][:id] == to_string(user.id)
- assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "a note with null content" do
- note = insert(:note_activity)
- note_object = Object.normalize(note)
-
- data =
- note_object.data
- |> Map.put("content", nil)
-
- Object.change(note_object, %{data: data})
- |> Object.update_and_set_cache()
-
- User.get_cached_by_ap_id(note.data["actor"])
-
- status = StatusView.render("show.json", %{activity: note})
-
- assert status.content == ""
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "a note activity" do
- note = insert(:note_activity)
- object_data = Object.normalize(note).data
- user = User.get_cached_by_ap_id(note.data["actor"])
-
- convo_id = Utils.context_to_conversation_id(object_data["context"])
-
- status = StatusView.render("show.json", %{activity: note})
-
- created_at =
- (object_data["published"] || "")
- |> String.replace(~r/\.\d+Z/, ".000Z")
-
- expected = %{
- id: to_string(note.id),
- uri: object_data["id"],
- url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
- account: AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
- in_reply_to_id: nil,
- in_reply_to_account_id: nil,
- card: nil,
- reblog: nil,
- content: HTML.filter_tags(object_data["content"]),
- text: nil,
- created_at: created_at,
- reblogs_count: 0,
- replies_count: 0,
- favourites_count: 0,
- reblogged: false,
- bookmarked: false,
- favourited: false,
- muted: false,
- pinned: false,
- sensitive: false,
- poll: nil,
- spoiler_text: HTML.filter_tags(object_data["summary"]),
- visibility: "public",
- media_attachments: [],
- mentions: [],
- tags: [
- %{
- name: "#{object_data["tag"]}",
- url: "/tag/#{object_data["tag"]}"
- }
- ],
- application: %{
- name: "Web",
- website: nil
- },
- language: nil,
- emojis: [
- %{
- shortcode: "2hu",
- url: "corndog.png",
- static_url: "corndog.png",
- visible_in_picker: false
- }
- ],
- pleroma: %{
- local: true,
- conversation_id: convo_id,
- in_reply_to_account_acct: nil,
- content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
- spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
- expires_at: nil,
- direct_conversation_id: nil,
- thread_muted: false,
- emoji_reactions: [],
- parent_visible: false
- }
- }
-
- assert status == expected
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "tells if the message is muted for some reason" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, _user_relationships} = User.mute(user, other_user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "test"})
-
- relationships_opt = UserRelationship.view_relationships_option(user, [other_user])
-
- opts = %{activity: activity}
- status = StatusView.render("show.json", opts)
- assert status.muted == false
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
-
- status = StatusView.render("show.json", Map.put(opts, :relationships, relationships_opt))
- assert status.muted == false
-
- for_opts = %{activity: activity, for: user}
- status = StatusView.render("show.json", for_opts)
- assert status.muted == true
-
- status = StatusView.render("show.json", Map.put(for_opts, :relationships, relationships_opt))
- assert status.muted == true
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "tells if the message is thread muted" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, _user_relationships} = User.mute(user, other_user)
-
- {:ok, activity} = CommonAPI.post(other_user, %{status: "test"})
- 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("show.json", %{activity: activity, for: user})
-
- assert status.pleroma.thread_muted == true
- end
-
- test "tells if the status is bookmarked" do
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Cute girls doing cute things"})
- status = StatusView.render("show.json", %{activity: activity})
-
- assert status.bookmarked == false
-
- status = StatusView.render("show.json", %{activity: activity, for: user})
-
- assert status.bookmarked == false
-
- {:ok, _bookmark} = Bookmark.create(user.id, activity.id)
-
- activity = Activity.get_by_id_with_object(activity.id)
-
- status = StatusView.render("show.json", %{activity: activity, for: user})
-
- assert status.bookmarked == true
- end
-
- test "a reply" do
- note = insert(:note_activity)
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "he", in_reply_to_status_id: note.id})
-
- status = StatusView.render("show.json", %{activity: activity})
-
- assert status.in_reply_to_id == to_string(note.id)
-
- [status] = StatusView.render("index.json", %{activities: [activity], as: :activity})
-
- assert status.in_reply_to_id == to_string(note.id)
- end
-
- test "contains mentions" do
- user = insert(:user)
- mentioned = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "hi @#{mentioned.nickname}"})
-
- status = StatusView.render("show.json", %{activity: activity})
-
- assert status.mentions ==
- Enum.map([mentioned], fn u -> AccountView.render("mention.json", %{user: u}) end)
-
- assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "create mentions from the 'to' field" do
- %User{ap_id: recipient_ap_id} = insert(:user)
- cc = insert_pair(:user) |> Enum.map(& &1.ap_id)
-
- object =
- insert(:note, %{
- data: %{
- "to" => [recipient_ap_id],
- "cc" => cc
- }
- })
-
- activity =
- insert(:note_activity, %{
- note: object,
- recipients: [recipient_ap_id | cc]
- })
-
- assert length(activity.recipients) == 3
-
- %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
-
- assert length(mentions) == 1
- assert mention.url == recipient_ap_id
- end
-
- test "create mentions from the 'tag' field" do
- recipient = insert(:user)
- cc = insert_pair(:user) |> Enum.map(& &1.ap_id)
-
- object =
- insert(:note, %{
- data: %{
- "cc" => cc,
- "tag" => [
- %{
- "href" => recipient.ap_id,
- "name" => recipient.nickname,
- "type" => "Mention"
- },
- %{
- "href" => "https://example.com/search?tag=test",
- "name" => "#test",
- "type" => "Hashtag"
- }
- ]
- }
- })
-
- activity =
- insert(:note_activity, %{
- note: object,
- recipients: [recipient.ap_id | cc]
- })
-
- assert length(activity.recipients) == 3
-
- %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
-
- assert length(mentions) == 1
- assert mention.url == recipient.ap_id
- end
-
- test "attachments" do
- object = %{
- "type" => "Image",
- "url" => [
- %{
- "mediaType" => "image/png",
- "href" => "someurl"
- }
- ],
- "uuid" => 6
- }
-
- expected = %{
- id: "1638338801",
- type: "image",
- url: "someurl",
- remote_url: "someurl",
- preview_url: "someurl",
- text_url: "someurl",
- description: nil,
- pleroma: %{mime_type: "image/png"}
- }
-
- api_spec = Pleroma.Web.ApiSpec.spec()
-
- assert expected == StatusView.render("attachment.json", %{attachment: object})
- assert_schema(expected, "Attachment", api_spec)
-
- # If theres a "id", use that instead of the generated one
- object = Map.put(object, "id", 2)
- result = StatusView.render("attachment.json", %{attachment: object})
-
- assert %{id: "2"} = result
- assert_schema(result, "Attachment", api_spec)
- end
-
- test "put the url advertised in the Activity in to the url attribute" do
- id = "https://wedistribute.org/wp-json/pterotype/v1/object/85810"
- [activity] = Activity.search(nil, id)
-
- status = StatusView.render("show.json", %{activity: activity})
-
- assert status.uri == id
- assert status.url == "https://wedistribute.org/2019/07/mastodon-drops-ostatus/"
- end
-
- test "a reblog" do
- user = insert(:user)
- activity = insert(:note_activity)
-
- {:ok, reblog} = CommonAPI.repeat(activity.id, user)
-
- represented = StatusView.render("show.json", %{for: user, activity: reblog})
-
- assert represented[:id] == to_string(reblog.id)
- assert represented[:reblog][:id] == to_string(activity.id)
- assert represented[:emojis] == []
- assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "a peertube video" do
- user = insert(:user)
-
- {:ok, object} =
- Pleroma.Object.Fetcher.fetch_object_from_id(
- "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
- )
-
- %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
-
- represented = StatusView.render("show.json", %{for: user, activity: activity})
-
- assert represented[:id] == to_string(activity.id)
- assert length(represented[:media_attachments]) == 1
- assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "funkwhale audio" do
- user = insert(:user)
-
- {:ok, object} =
- Pleroma.Object.Fetcher.fetch_object_from_id(
- "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871"
- )
-
- %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
-
- represented = StatusView.render("show.json", %{for: user, activity: activity})
-
- assert represented[:id] == to_string(activity.id)
- assert length(represented[:media_attachments]) == 1
- end
-
- test "a Mobilizon event" do
- user = insert(:user)
-
- {:ok, object} =
- Pleroma.Object.Fetcher.fetch_object_from_id(
- "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
- )
-
- %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
-
- represented = StatusView.render("show.json", %{for: user, activity: activity})
-
- assert represented[:id] == to_string(activity.id)
-
- assert represented[:url] ==
- "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
-
- assert represented[:content] ==
- "<p><a href=\"https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39\">Mobilizon Launching Party</a></p><p>Mobilizon is now federated! 🎉</p><p></p><p>You can view this event from other instances if they are subscribed to mobilizon.org, and soon directly from Mastodon and Pleroma. It is possible that you may see some comments from other instances, including Mastodon ones, just below.</p><p></p><p>With a Mobilizon account on an instance, you may <strong>participate</strong> at events from other instances and <strong>add comments</strong> on events.</p><p></p><p>Of course, it&#39;s still <u>a work in progress</u>: if reports made from an instance on events and comments can be federated, you can&#39;t block people right now, and moderators actions are rather limited, but this <strong>will definitely get fixed over time</strong> until first stable version next year.</p><p></p><p>Anyway, if you want to come up with some feedback, head over to our forum or - if you feel you have technical skills and are familiar with it - on our Gitlab repository.</p><p></p><p>Also, to people that want to set Mobilizon themselves even though we really don&#39;t advise to do that for now, we have a little documentation but it&#39;s quite the early days and you&#39;ll probably need some help. No worries, you can chat with us on our Forum or though our Matrix channel.</p><p></p><p>Check our website for more informations and follow us on Twitter or Mastodon.</p>"
- end
-
- describe "build_tags/1" do
- test "it returns a a dictionary tags" do
- object_tags = [
- "fediverse",
- "mastodon",
- "nextcloud",
- %{
- "href" => "https://kawen.space/users/lain",
- "name" => "@lain@kawen.space",
- "type" => "Mention"
- }
- ]
-
- assert StatusView.build_tags(object_tags) == [
- %{name: "fediverse", url: "/tag/fediverse"},
- %{name: "mastodon", url: "/tag/mastodon"},
- %{name: "nextcloud", url: "/tag/nextcloud"}
- ]
- end
- end
-
- describe "rich media cards" do
- test "a rich media card without a site name renders correctly" do
- page_url = "http://example.com"
-
- card = %{
- url: page_url,
- image: page_url <> "/example.jpg",
- title: "Example website"
- }
-
- %{provider_name: "example.com"} =
- StatusView.render("card.json", %{page_url: page_url, rich_media: card})
- end
-
- test "a rich media card without a site name or image renders correctly" do
- page_url = "http://example.com"
-
- card = %{
- url: page_url,
- title: "Example website"
- }
-
- %{provider_name: "example.com"} =
- StatusView.render("card.json", %{page_url: page_url, rich_media: card})
- end
-
- test "a rich media card without an image renders correctly" do
- page_url = "http://example.com"
-
- card = %{
- url: page_url,
- site_name: "Example site name",
- title: "Example website"
- }
-
- %{provider_name: "example.com"} =
- StatusView.render("card.json", %{page_url: page_url, rich_media: card})
- end
-
- test "a rich media card with all relevant data renders correctly" do
- page_url = "http://example.com"
-
- card = %{
- url: page_url,
- site_name: "Example site name",
- title: "Example website",
- image: page_url <> "/example.jpg",
- description: "Example description"
- }
-
- %{provider_name: "example.com"} =
- StatusView.render("card.json", %{page_url: page_url, rich_media: card})
- end
- end
-
- test "does not embed a relationship in the account" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "drink more water"
- })
-
- result = StatusView.render("show.json", %{activity: activity, for: other_user})
-
- assert result[:account][:pleroma][:relationship] == %{}
- assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "does not embed a relationship in the account in reposts" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "˙˙ɐʎns"
- })
-
- {:ok, activity} = CommonAPI.repeat(activity.id, other_user)
-
- result = StatusView.render("show.json", %{activity: activity, for: user})
-
- assert result[:account][:pleroma][:relationship] == %{}
- assert result[:reblog][:account][:pleroma][:relationship] == %{}
- assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
- end
-
- test "visibility/list" do
- user = insert(:user)
-
- {:ok, list} = Pleroma.List.create("foo", user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
-
- status = StatusView.render("show.json", activity: activity)
-
- assert status.visibility == "list"
- end
-
- test "has a field for parent visibility" do
- user = insert(:user)
- poster = insert(:user)
-
- {:ok, invisible} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
-
- {:ok, visible} =
- CommonAPI.post(poster, %{status: "hey", visibility: "private", in_reply_to_id: invisible.id})
-
- status = StatusView.render("show.json", activity: visible, for: user)
- refute status.pleroma.parent_visible
-
- status = StatusView.render("show.json", activity: visible, for: poster)
- assert status.pleroma.parent_visible
- end
-end
diff --git a/test/web/mastodon_api/views/subscription_view_test.exs b/test/web/mastodon_api/views/subscription_view_test.exs
deleted file mode 100644
index 981524c0e..000000000
--- a/test/web/mastodon_api/views/subscription_view_test.exs
+++ /dev/null
@@ -1,23 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.SubscriptionViewTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.MastodonAPI.SubscriptionView, as: View
- alias Pleroma.Web.Push
-
- test "Represent a subscription" do
- subscription = insert(:push_subscription, data: %{"alerts" => %{"mention" => true}})
-
- expected = %{
- alerts: %{"mention" => true},
- endpoint: subscription.endpoint,
- id: to_string(subscription.id),
- server_key: Keyword.get(Push.vapid_config(), :public_key)
- }
-
- assert expected == View.render("show.json", %{subscription: subscription})
- end
-end
diff --git a/test/web/media_proxy/invalidation_test.exs b/test/web/media_proxy/invalidation_test.exs
deleted file mode 100644
index 926ae74ca..000000000
--- a/test/web/media_proxy/invalidation_test.exs
+++ /dev/null
@@ -1,64 +0,0 @@
-defmodule Pleroma.Web.MediaProxy.InvalidationTest do
- use ExUnit.Case
- use Pleroma.Tests.Helpers
-
- alias Pleroma.Config
- alias Pleroma.Web.MediaProxy.Invalidation
-
- import ExUnit.CaptureLog
- import Mock
- import Tesla.Mock
-
- setup do: clear_config([:media_proxy])
-
- setup do
- on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
- end
-
- describe "Invalidation.Http" do
- test "perform request to clear cache" do
- Config.put([:media_proxy, :enabled], false)
- Config.put([:media_proxy, :invalidation, :enabled], true)
- Config.put([:media_proxy, :invalidation, :provider], Invalidation.Http)
-
- Config.put([Invalidation.Http], method: :purge, headers: [{"x-refresh", 1}])
- image_url = "http://example.com/media/example.jpg"
- Pleroma.Web.MediaProxy.put_in_banned_urls(image_url)
-
- mock(fn
- %{
- method: :purge,
- url: "http://example.com/media/example.jpg",
- headers: [{"x-refresh", 1}]
- } ->
- %Tesla.Env{status: 200}
- end)
-
- assert capture_log(fn ->
- assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
- assert Invalidation.purge([image_url]) == {:ok, [image_url]}
- assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
- end) =~ "Running cache purge: [\"#{image_url}\"]"
- end
- end
-
- describe "Invalidation.Script" do
- test "run script to clear cache" do
- Config.put([:media_proxy, :enabled], false)
- Config.put([:media_proxy, :invalidation, :enabled], true)
- Config.put([:media_proxy, :invalidation, :provider], Invalidation.Script)
- Config.put([Invalidation.Script], script_path: "purge-nginx")
-
- image_url = "http://example.com/media/example.jpg"
- Pleroma.Web.MediaProxy.put_in_banned_urls(image_url)
-
- with_mocks [{System, [], [cmd: fn _, _ -> {"ok", 0} end]}] do
- assert capture_log(fn ->
- assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
- assert Invalidation.purge([image_url]) == {:ok, [image_url]}
- assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
- end) =~ "Running cache purge: [\"#{image_url}\"]"
- end
- end
- end
-end
diff --git a/test/web/media_proxy/invalidations/http_test.exs b/test/web/media_proxy/invalidations/http_test.exs
deleted file mode 100644
index a1bef5237..000000000
--- a/test/web/media_proxy/invalidations/http_test.exs
+++ /dev/null
@@ -1,39 +0,0 @@
-defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
- use ExUnit.Case
- alias Pleroma.Web.MediaProxy.Invalidation
-
- import ExUnit.CaptureLog
- import Tesla.Mock
-
- setup do
- on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
- end
-
- test "logs hasn't error message when request is valid" do
- mock(fn
- %{method: :purge, url: "http://example.com/media/example.jpg"} ->
- %Tesla.Env{status: 200}
- end)
-
- refute capture_log(fn ->
- assert Invalidation.Http.purge(
- ["http://example.com/media/example.jpg"],
- []
- ) == {:ok, ["http://example.com/media/example.jpg"]}
- end) =~ "Error while cache purge"
- end
-
- test "it write error message in logs when request invalid" do
- mock(fn
- %{method: :purge, url: "http://example.com/media/example1.jpg"} ->
- %Tesla.Env{status: 404}
- end)
-
- assert capture_log(fn ->
- assert Invalidation.Http.purge(
- ["http://example.com/media/example1.jpg"],
- []
- ) == {:ok, ["http://example.com/media/example1.jpg"]}
- end) =~ "Error while cache purge: url - http://example.com/media/example1.jpg"
- end
-end
diff --git a/test/web/media_proxy/invalidations/script_test.exs b/test/web/media_proxy/invalidations/script_test.exs
deleted file mode 100644
index 51833ab18..000000000
--- a/test/web/media_proxy/invalidations/script_test.exs
+++ /dev/null
@@ -1,26 +0,0 @@
-defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
- use ExUnit.Case
- alias Pleroma.Web.MediaProxy.Invalidation
-
- import ExUnit.CaptureLog
-
- setup do
- on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
- end
-
- test "it logger error when script not found" do
- assert capture_log(fn ->
- assert Invalidation.Script.purge(
- ["http://example.com/media/example.jpg"],
- script_path: "./example"
- ) == {:error, "%ErlangError{original: :enoent}"}
- end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
-
- capture_log(fn ->
- assert Invalidation.Script.purge(
- ["http://example.com/media/example.jpg"],
- []
- ) == {:error, "\"not found script path\""}
- end)
- end
-end
diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/web/media_proxy/media_proxy_controller_test.exs
deleted file mode 100644
index d4db44c63..000000000
--- a/test/web/media_proxy/media_proxy_controller_test.exs
+++ /dev/null
@@ -1,121 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
- use Pleroma.Web.ConnCase
-
- import Mock
-
- alias Pleroma.Web.MediaProxy
- alias Pleroma.Web.MediaProxy.MediaProxyController
- alias Plug.Conn
-
- setup do
- on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
- end
-
- test "it returns 404 when MediaProxy disabled", %{conn: conn} do
- clear_config([:media_proxy, :enabled], false)
-
- assert %Conn{
- status: 404,
- resp_body: "Not Found"
- } = get(conn, "/proxy/hhgfh/eeeee")
-
- assert %Conn{
- status: 404,
- resp_body: "Not Found"
- } = get(conn, "/proxy/hhgfh/eeee/fff")
- end
-
- describe "" do
- setup do
- clear_config([:media_proxy, :enabled], true)
- clear_config([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
- [url: MediaProxy.encode_url("https://google.fn/test.png")]
- end
-
- test "it returns 403 for invalid signature", %{conn: conn, url: url} do
- Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
- %{path: path} = URI.parse(url)
-
- assert %Conn{
- status: 403,
- resp_body: "Forbidden"
- } = get(conn, path)
-
- assert %Conn{
- status: 403,
- resp_body: "Forbidden"
- } = get(conn, "/proxy/hhgfh/eeee")
-
- assert %Conn{
- status: 403,
- resp_body: "Forbidden"
- } = get(conn, "/proxy/hhgfh/eeee/fff")
- end
-
- test "redirects on valid url when filename is invalidated", %{conn: conn, url: url} do
- invalid_url = String.replace(url, "test.png", "test-file.png")
- response = get(conn, invalid_url)
- assert response.status == 302
- assert redirected_to(response) == url
- end
-
- test "it performs ReverseProxy.call with valid signature", %{conn: conn, url: url} do
- with_mock Pleroma.ReverseProxy,
- call: fn _conn, _url, _opts -> %Conn{status: :success} end do
- assert %Conn{status: :success} = get(conn, url)
- end
- end
-
- test "it returns 404 when url is in banned_urls cache", %{conn: conn, url: url} do
- MediaProxy.put_in_banned_urls("https://google.fn/test.png")
-
- with_mock Pleroma.ReverseProxy,
- call: fn _conn, _url, _opts -> %Conn{status: :success} end do
- assert %Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
- end
- end
- end
-
- describe "filename_matches/3" do
- test "preserves the encoded or decoded path" do
- assert MediaProxyController.filename_matches(
- %{"filename" => "/Hello world.jpg"},
- "/Hello world.jpg",
- "http://pleroma.social/Hello world.jpg"
- ) == :ok
-
- assert MediaProxyController.filename_matches(
- %{"filename" => "/Hello%20world.jpg"},
- "/Hello%20world.jpg",
- "http://pleroma.social/Hello%20world.jpg"
- ) == :ok
-
- assert MediaProxyController.filename_matches(
- %{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"},
- "/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
- "http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
- ) == :ok
-
- assert MediaProxyController.filename_matches(
- %{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jp"},
- "/my%2Flong%2Furl%2F2019%2F07%2FS.jp",
- "http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
- ) == {:wrong_filename, "my%2Flong%2Furl%2F2019%2F07%2FS.jpg"}
- end
-
- test "encoded url are tried to match for proxy as `conn.request_path` encodes the url" do
- # conn.request_path will return encoded url
- request_path = "/ANALYSE-DAI-_-LE-STABLECOIN-100-D%C3%89CENTRALIS%C3%89-BQ.jpg"
-
- assert MediaProxyController.filename_matches(
- true,
- request_path,
- "https://mydomain.com/uploads/2019/07/ANALYSE-DAI-_-LE-STABLECOIN-100-DÉCENTRALISÉ-BQ.jpg"
- ) == :ok
- end
- end
-end
diff --git a/test/web/media_proxy/media_proxy_test.exs b/test/web/media_proxy/media_proxy_test.exs
deleted file mode 100644
index 72885cfdd..000000000
--- a/test/web/media_proxy/media_proxy_test.exs
+++ /dev/null
@@ -1,175 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MediaProxyTest do
- use ExUnit.Case
- use Pleroma.Tests.Helpers
-
- alias Pleroma.Web.Endpoint
- alias Pleroma.Web.MediaProxy
-
- describe "when enabled" do
- setup do: clear_config([:media_proxy, :enabled], true)
-
- test "ignores invalid url" do
- assert MediaProxy.url(nil) == nil
- assert MediaProxy.url("") == nil
- end
-
- test "ignores relative url" do
- assert MediaProxy.url("/local") == "/local"
- assert MediaProxy.url("/") == "/"
- end
-
- test "ignores local url" do
- local_url = Endpoint.url() <> "/hello"
- local_root = Endpoint.url()
- assert MediaProxy.url(local_url) == local_url
- assert MediaProxy.url(local_root) == local_root
- end
-
- test "encodes and decodes URL" do
- url = "https://pleroma.soykaf.com/static/logo.png"
- encoded = MediaProxy.url(url)
-
- assert String.starts_with?(
- encoded,
- Pleroma.Config.get([:media_proxy, :base_url], Pleroma.Web.base_url())
- )
-
- assert String.ends_with?(encoded, "/logo.png")
-
- assert decode_result(encoded) == url
- end
-
- test "encodes and decodes URL without a path" do
- url = "https://pleroma.soykaf.com"
- encoded = MediaProxy.url(url)
- assert decode_result(encoded) == url
- end
-
- test "encodes and decodes URL without an extension" do
- url = "https://pleroma.soykaf.com/path/"
- encoded = MediaProxy.url(url)
- assert String.ends_with?(encoded, "/path")
- assert decode_result(encoded) == url
- end
-
- test "encodes and decodes URL and ignores query params for the path" do
- url = "https://pleroma.soykaf.com/static/logo.png?93939393939&bunny=true"
- encoded = MediaProxy.url(url)
- assert String.ends_with?(encoded, "/logo.png")
- assert decode_result(encoded) == url
- end
-
- test "validates signature" do
- encoded = MediaProxy.url("https://pleroma.social")
-
- clear_config(
- [Endpoint, :secret_key_base],
- "00000000000000000000000000000000000000000000000"
- )
-
- [_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
- assert MediaProxy.decode_url(sig, base64) == {:error, :invalid_signature}
- end
-
- test "uses the configured base_url" do
- base_url = "https://cache.pleroma.social"
- clear_config([:media_proxy, :base_url], base_url)
-
- url = "https://pleroma.soykaf.com/static/logo.png"
- encoded = MediaProxy.url(url)
-
- assert String.starts_with?(encoded, base_url)
- end
-
- # Some sites expect ASCII encoded characters in the URL to be preserved even if
- # unnecessary.
- # Issues: https://git.pleroma.social/pleroma/pleroma/issues/580
- # https://git.pleroma.social/pleroma/pleroma/issues/1055
- test "preserve ASCII encoding" do
- url =
- "https://pleroma.com/%20/%21/%22/%23/%24/%25/%26/%27/%28/%29/%2A/%2B/%2C/%2D/%2E/%2F/%30/%31/%32/%33/%34/%35/%36/%37/%38/%39/%3A/%3B/%3C/%3D/%3E/%3F/%40/%41/%42/%43/%44/%45/%46/%47/%48/%49/%4A/%4B/%4C/%4D/%4E/%4F/%50/%51/%52/%53/%54/%55/%56/%57/%58/%59/%5A/%5B/%5C/%5D/%5E/%5F/%60/%61/%62/%63/%64/%65/%66/%67/%68/%69/%6A/%6B/%6C/%6D/%6E/%6F/%70/%71/%72/%73/%74/%75/%76/%77/%78/%79/%7A/%7B/%7C/%7D/%7E/%7F/%80/%81/%82/%83/%84/%85/%86/%87/%88/%89/%8A/%8B/%8C/%8D/%8E/%8F/%90/%91/%92/%93/%94/%95/%96/%97/%98/%99/%9A/%9B/%9C/%9D/%9E/%9F/%C2%A0/%A1/%A2/%A3/%A4/%A5/%A6/%A7/%A8/%A9/%AA/%AB/%AC/%C2%AD/%AE/%AF/%B0/%B1/%B2/%B3/%B4/%B5/%B6/%B7/%B8/%B9/%BA/%BB/%BC/%BD/%BE/%BF/%C0/%C1/%C2/%C3/%C4/%C5/%C6/%C7/%C8/%C9/%CA/%CB/%CC/%CD/%CE/%CF/%D0/%D1/%D2/%D3/%D4/%D5/%D6/%D7/%D8/%D9/%DA/%DB/%DC/%DD/%DE/%DF/%E0/%E1/%E2/%E3/%E4/%E5/%E6/%E7/%E8/%E9/%EA/%EB/%EC/%ED/%EE/%EF/%F0/%F1/%F2/%F3/%F4/%F5/%F6/%F7/%F8/%F9/%FA/%FB/%FC/%FD/%FE/%FF"
-
- encoded = MediaProxy.url(url)
- assert decode_result(encoded) == url
- end
-
- # This includes unsafe/reserved characters which are not interpreted as part of the URL
- # and would otherwise have to be ASCII encoded. It is our role to ensure the proxied URL
- # is unmodified, so we are testing these characters anyway.
- test "preserve non-unicode characters per RFC3986" do
- url =
- "https://pleroma.com/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-._~:/?#[]@!$&'()*+,;=|^`{}"
-
- encoded = MediaProxy.url(url)
- assert decode_result(encoded) == url
- end
-
- test "preserve unicode characters" do
- url = "https://ko.wikipedia.org/wiki/위키백과:대문"
-
- encoded = MediaProxy.url(url)
- assert decode_result(encoded) == url
- end
- end
-
- describe "when disabled" do
- setup do: clear_config([:media_proxy, :enabled], false)
-
- test "does not encode remote urls" do
- assert MediaProxy.url("https://google.fr") == "https://google.fr"
- end
- end
-
- defp decode_result(encoded) do
- [_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
- {:ok, decoded} = MediaProxy.decode_url(sig, base64)
- decoded
- end
-
- describe "whitelist" do
- setup do: clear_config([:media_proxy, :enabled], true)
-
- test "mediaproxy whitelist" do
- clear_config([:media_proxy, :whitelist], ["https://google.com", "https://feld.me"])
- url = "https://feld.me/foo.png"
-
- unencoded = MediaProxy.url(url)
- assert unencoded == url
- end
-
- # TODO: delete after removing support bare domains for media proxy whitelist
- test "mediaproxy whitelist bare domains whitelist (deprecated)" do
- clear_config([:media_proxy, :whitelist], ["google.com", "feld.me"])
- url = "https://feld.me/foo.png"
-
- unencoded = MediaProxy.url(url)
- assert unencoded == url
- end
-
- test "does not change whitelisted urls" do
- clear_config([:media_proxy, :whitelist], ["mycdn.akamai.com"])
- clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")
-
- media_url = "https://mycdn.akamai.com"
-
- url = "#{media_url}/static/logo.png"
- encoded = MediaProxy.url(url)
-
- assert String.starts_with?(encoded, media_url)
- end
-
- test "ensure Pleroma.Upload base_url is always whitelisted" do
- media_url = "https://media.pleroma.social"
- clear_config([Pleroma.Upload, :base_url], media_url)
-
- url = "#{media_url}/static/logo.png"
- encoded = MediaProxy.url(url)
-
- assert String.starts_with?(encoded, media_url)
- end
- end
-end
diff --git a/test/web/metadata/feed_test.exs b/test/web/metadata/feed_test.exs
deleted file mode 100644
index e6e5cc5ed..000000000
--- a/test/web/metadata/feed_test.exs
+++ /dev/null
@@ -1,18 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.Providers.FeedTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.Metadata.Providers.Feed
-
- test "it renders a link to user's atom feed" do
- user = insert(:user, nickname: "lain")
-
- assert Feed.build_tags(%{user: user}) == [
- {:link,
- [rel: "alternate", type: "application/atom+xml", href: "/users/lain/feed.atom"], []}
- ]
- end
-end
diff --git a/test/web/metadata/metadata_test.exs b/test/web/metadata/metadata_test.exs
deleted file mode 100644
index 9d3121b7b..000000000
--- a/test/web/metadata/metadata_test.exs
+++ /dev/null
@@ -1,34 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MetadataTest do
- use Pleroma.DataCase, async: true
-
- import Pleroma.Factory
-
- describe "restrict indexing remote users" do
- test "for remote user" do
- user = insert(:user, local: false)
-
- assert Pleroma.Web.Metadata.build_tags(%{user: user}) =~
- "<meta content=\"noindex, noarchive\" name=\"robots\">"
- end
-
- test "for local user" do
- user = insert(:user)
-
- refute Pleroma.Web.Metadata.build_tags(%{user: user}) =~
- "<meta content=\"noindex, noarchive\" name=\"robots\">"
- end
- end
-
- describe "no metadata for private instances" do
- test "for local user" do
- clear_config([:instance, :public], false)
- user = insert(:user, bio: "This is my secret fedi account bio")
-
- assert "" = Pleroma.Web.Metadata.build_tags(%{user: user})
- end
- end
-end
diff --git a/test/web/metadata/opengraph_test.exs b/test/web/metadata/opengraph_test.exs
deleted file mode 100644
index 218540e6c..000000000
--- a/test/web/metadata/opengraph_test.exs
+++ /dev/null
@@ -1,96 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.Providers.OpenGraphTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.Metadata.Providers.OpenGraph
-
- setup do: clear_config([Pleroma.Web.Metadata, :unfurl_nsfw])
-
- test "it renders all supported types of attachments and skips unknown types" do
- user = insert(:user)
-
- note =
- insert(:note, %{
- data: %{
- "actor" => user.ap_id,
- "tag" => [],
- "id" => "https://pleroma.gov/objects/whatever",
- "content" => "pleroma in a nutshell",
- "attachment" => [
- %{
- "url" => [
- %{"mediaType" => "image/png", "href" => "https://pleroma.gov/tenshi.png"}
- ]
- },
- %{
- "url" => [
- %{
- "mediaType" => "application/octet-stream",
- "href" => "https://pleroma.gov/fqa/badapple.sfc"
- }
- ]
- },
- %{
- "url" => [
- %{"mediaType" => "video/webm", "href" => "https://pleroma.gov/about/juche.webm"}
- ]
- },
- %{
- "url" => [
- %{
- "mediaType" => "audio/basic",
- "href" => "http://www.gnu.org/music/free-software-song.au"
- }
- ]
- }
- ]
- }
- })
-
- result = OpenGraph.build_tags(%{object: note, url: note.data["id"], user: user})
-
- assert Enum.all?(
- [
- {:meta, [property: "og:image", content: "https://pleroma.gov/tenshi.png"], []},
- {:meta,
- [property: "og:audio", content: "http://www.gnu.org/music/free-software-song.au"],
- []},
- {:meta, [property: "og:video", content: "https://pleroma.gov/about/juche.webm"],
- []}
- ],
- fn element -> element in result end
- )
- end
-
- test "it does not render attachments if post is nsfw" do
- Pleroma.Config.put([Pleroma.Web.Metadata, :unfurl_nsfw], false)
- user = insert(:user, avatar: %{"url" => [%{"href" => "https://pleroma.gov/tenshi.png"}]})
-
- note =
- insert(:note, %{
- data: %{
- "actor" => user.ap_id,
- "id" => "https://pleroma.gov/objects/whatever",
- "content" => "#cuteposting #nsfw #hambaga",
- "tag" => ["cuteposting", "nsfw", "hambaga"],
- "sensitive" => true,
- "attachment" => [
- %{
- "url" => [
- %{"mediaType" => "image/png", "href" => "https://misskey.microsoft/corndog.png"}
- ]
- }
- ]
- }
- })
-
- result = OpenGraph.build_tags(%{object: note, url: note.data["id"], user: user})
-
- assert {:meta, [property: "og:image", content: "https://pleroma.gov/tenshi.png"], []} in result
-
- refute {:meta, [property: "og:image", content: "https://misskey.microsoft/corndog.png"], []} in result
- end
-end
diff --git a/test/web/metadata/player_view_test.exs b/test/web/metadata/player_view_test.exs
deleted file mode 100644
index e6c990242..000000000
--- a/test/web/metadata/player_view_test.exs
+++ /dev/null
@@ -1,33 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.PlayerViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.Metadata.PlayerView
-
- test "it renders audio tag" do
- res =
- PlayerView.render(
- "player.html",
- %{"mediaType" => "audio", "href" => "test-href"}
- )
- |> Phoenix.HTML.safe_to_string()
-
- assert res ==
- "<audio controls><source src=\"test-href\" type=\"audio\">Your browser does not support audio playback.</audio>"
- end
-
- test "it renders videos tag" do
- res =
- PlayerView.render(
- "player.html",
- %{"mediaType" => "video", "href" => "test-href"}
- )
- |> Phoenix.HTML.safe_to_string()
-
- assert res ==
- "<video controls loop><source src=\"test-href\" type=\"video\">Your browser does not support video playback.</video>"
- end
-end
diff --git a/test/web/metadata/rel_me_test.exs b/test/web/metadata/rel_me_test.exs
deleted file mode 100644
index 2293d6e13..000000000
--- a/test/web/metadata/rel_me_test.exs
+++ /dev/null
@@ -1,21 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.Providers.RelMeTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.Metadata.Providers.RelMe
-
- test "it renders all links with rel='me' from user bio" do
- bio =
- ~s(<a href="https://some-link.com">https://some-link.com</a> <a rel="me" href="https://another-link.com">https://another-link.com</a> <link href="http://some.com"> <link rel="me" href="http://some3.com">)
-
- user = insert(:user, %{bio: bio})
-
- assert RelMe.build_tags(%{user: user}) == [
- {:link, [rel: "me", href: "http://some3.com"], []},
- {:link, [rel: "me", href: "https://another-link.com"], []}
- ]
- end
-end
diff --git a/test/web/metadata/restrict_indexing_test.exs b/test/web/metadata/restrict_indexing_test.exs
deleted file mode 100644
index aad0bac42..000000000
--- a/test/web/metadata/restrict_indexing_test.exs
+++ /dev/null
@@ -1,21 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.Providers.RestrictIndexingTest do
- use ExUnit.Case, async: true
-
- describe "build_tags/1" do
- test "for remote user" do
- assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
- user: %Pleroma.User{local: false}
- }) == [{:meta, [name: "robots", content: "noindex, noarchive"], []}]
- end
-
- test "for local user" do
- assert Pleroma.Web.Metadata.Providers.RestrictIndexing.build_tags(%{
- user: %Pleroma.User{local: true}
- }) == []
- end
- end
-end
diff --git a/test/web/metadata/twitter_card_test.exs b/test/web/metadata/twitter_card_test.exs
deleted file mode 100644
index 10931b5ba..000000000
--- a/test/web/metadata/twitter_card_test.exs
+++ /dev/null
@@ -1,150 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.Endpoint
- alias Pleroma.Web.Metadata.Providers.TwitterCard
- alias Pleroma.Web.Metadata.Utils
- alias Pleroma.Web.Router
-
- setup do: clear_config([Pleroma.Web.Metadata, :unfurl_nsfw])
-
- test "it renders twitter card for user info" do
- user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
- avatar_url = Utils.attachment_url(User.avatar_url(user))
- res = TwitterCard.build_tags(%{user: user})
-
- assert res == [
- {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
- {:meta, [property: "twitter:description", content: "born 19 March 1994"], []},
- {:meta, [property: "twitter:image", content: avatar_url], []},
- {:meta, [property: "twitter:card", content: "summary"], []}
- ]
- end
-
- test "it uses summary twittercard if post has no attachment" do
- user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
- {:ok, activity} = CommonAPI.post(user, %{status: "HI"})
-
- note =
- insert(:note, %{
- data: %{
- "actor" => user.ap_id,
- "tag" => [],
- "id" => "https://pleroma.gov/objects/whatever",
- "content" => "pleroma in a nutshell"
- }
- })
-
- result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
-
- assert [
- {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
- {:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []},
- {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
- []},
- {:meta, [property: "twitter:card", content: "summary"], []}
- ] == result
- end
-
- test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabled" do
- Pleroma.Config.put([Pleroma.Web.Metadata, :unfurl_nsfw], false)
- user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
- {:ok, activity} = CommonAPI.post(user, %{status: "HI"})
-
- note =
- insert(:note, %{
- data: %{
- "actor" => user.ap_id,
- "tag" => [],
- "id" => "https://pleroma.gov/objects/whatever",
- "content" => "pleroma in a nutshell",
- "sensitive" => true,
- "attachment" => [
- %{
- "url" => [%{"mediaType" => "image/png", "href" => "https://pleroma.gov/tenshi.png"}]
- },
- %{
- "url" => [
- %{
- "mediaType" => "application/octet-stream",
- "href" => "https://pleroma.gov/fqa/badapple.sfc"
- }
- ]
- },
- %{
- "url" => [
- %{"mediaType" => "video/webm", "href" => "https://pleroma.gov/about/juche.webm"}
- ]
- }
- ]
- }
- })
-
- result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
-
- assert [
- {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
- {:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []},
- {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
- []},
- {:meta, [property: "twitter:card", content: "summary"], []}
- ] == result
- end
-
- test "it renders supported types of attachments and skips unknown types" do
- user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
- {:ok, activity} = CommonAPI.post(user, %{status: "HI"})
-
- note =
- insert(:note, %{
- data: %{
- "actor" => user.ap_id,
- "tag" => [],
- "id" => "https://pleroma.gov/objects/whatever",
- "content" => "pleroma in a nutshell",
- "attachment" => [
- %{
- "url" => [%{"mediaType" => "image/png", "href" => "https://pleroma.gov/tenshi.png"}]
- },
- %{
- "url" => [
- %{
- "mediaType" => "application/octet-stream",
- "href" => "https://pleroma.gov/fqa/badapple.sfc"
- }
- ]
- },
- %{
- "url" => [
- %{"mediaType" => "video/webm", "href" => "https://pleroma.gov/about/juche.webm"}
- ]
- }
- ]
- }
- })
-
- result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
-
- assert [
- {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
- {:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []},
- {:meta, [property: "twitter:card", content: "summary_large_image"], []},
- {:meta, [property: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
- {:meta, [property: "twitter:card", content: "player"], []},
- {:meta,
- [
- property: "twitter:player",
- content: Router.Helpers.o_status_url(Endpoint, :notice_player, activity.id)
- ], []},
- {:meta, [property: "twitter:player:width", content: "480"], []},
- {:meta, [property: "twitter:player:height", content: "480"], []}
- ] == result
- end
-end
diff --git a/test/web/metadata/utils_test.exs b/test/web/metadata/utils_test.exs
deleted file mode 100644
index 8183256d8..000000000
--- a/test/web/metadata/utils_test.exs
+++ /dev/null
@@ -1,32 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Metadata.UtilsTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.Metadata.Utils
-
- describe "scrub_html_and_truncate/1" do
- test "it returns text without encode HTML" do
- user = insert(:user)
-
- note =
- insert(:note, %{
- data: %{
- "actor" => user.ap_id,
- "id" => "https://pleroma.gov/objects/whatever",
- "content" => "Pleroma's really cool!"
- }
- })
-
- assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
- end
- end
-
- describe "scrub_html_and_truncate/2" do
- test "it returns text without encode HTML" do
- assert Utils.scrub_html_and_truncate("Pleroma's really cool!") == "Pleroma's really cool!"
- end
- end
-end
diff --git a/test/web/mongooseim/mongoose_im_controller_test.exs b/test/web/mongooseim/mongoose_im_controller_test.exs
deleted file mode 100644
index 5176cde84..000000000
--- a/test/web/mongooseim/mongoose_im_controller_test.exs
+++ /dev/null
@@ -1,81 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MongooseIMController do
- use Pleroma.Web.ConnCase
- import Pleroma.Factory
-
- test "/user_exists", %{conn: conn} do
- _user = insert(:user, nickname: "lain")
- _remote_user = insert(:user, nickname: "alice", local: false)
- _deactivated_user = insert(:user, nickname: "konata", deactivated: true)
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "lain")
- |> json_response(200)
-
- assert res == true
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "alice")
- |> json_response(404)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "bob")
- |> json_response(404)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "konata")
- |> json_response(404)
-
- assert res == false
- end
-
- test "/check_password", %{conn: conn} do
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt("cool"))
-
- _deactivated_user =
- insert(:user,
- nickname: "konata",
- deactivated: true,
- password_hash: Pbkdf2.hash_pwd_salt("cool")
- )
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "cool")
- |> json_response(200)
-
- assert res == true
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "uncool")
- |> json_response(403)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: "konata", pass: "cool")
- |> json_response(404)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: "nobody", pass: "cool")
- |> json_response(404)
-
- assert res == false
- end
-end
diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs
deleted file mode 100644
index 06b33607f..000000000
--- a/test/web/node_info_test.exs
+++ /dev/null
@@ -1,188 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.NodeInfoTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Config
-
- setup do: clear_config([:mrf_simple])
- setup do: clear_config(:instance)
-
- test "GET /.well-known/nodeinfo", %{conn: conn} do
- links =
- conn
- |> get("/.well-known/nodeinfo")
- |> json_response(200)
- |> Map.fetch!("links")
-
- Enum.each(links, fn link ->
- href = Map.fetch!(link, "href")
-
- conn
- |> get(href)
- |> json_response(200)
- end)
- end
-
- test "nodeinfo shows staff accounts", %{conn: conn} do
- moderator = insert(:user, local: true, is_moderator: true)
- admin = insert(:user, local: true, is_admin: true)
-
- conn =
- conn
- |> get("/nodeinfo/2.1.json")
-
- assert result = json_response(conn, 200)
-
- assert moderator.ap_id in result["metadata"]["staffAccounts"]
- assert admin.ap_id in result["metadata"]["staffAccounts"]
- end
-
- test "nodeinfo shows restricted nicknames", %{conn: conn} do
- conn =
- conn
- |> get("/nodeinfo/2.1.json")
-
- assert result = json_response(conn, 200)
-
- assert Config.get([Pleroma.User, :restricted_nicknames]) ==
- result["metadata"]["restrictedNicknames"]
- end
-
- test "returns software.repository field in nodeinfo 2.1", %{conn: conn} do
- conn
- |> get("/.well-known/nodeinfo")
- |> json_response(200)
-
- conn =
- conn
- |> get("/nodeinfo/2.1.json")
-
- assert result = json_response(conn, 200)
- assert Pleroma.Application.repository() == result["software"]["repository"]
- end
-
- test "returns fieldsLimits field", %{conn: conn} do
- clear_config([:instance, :max_account_fields], 10)
- clear_config([:instance, :max_remote_account_fields], 15)
- clear_config([:instance, :account_field_name_length], 255)
- clear_config([:instance, :account_field_value_length], 2048)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- assert response["metadata"]["fieldsLimits"]["maxFields"] == 10
- assert response["metadata"]["fieldsLimits"]["maxRemoteFields"] == 15
- assert response["metadata"]["fieldsLimits"]["nameLength"] == 255
- assert response["metadata"]["fieldsLimits"]["valueLength"] == 2048
- end
-
- test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
- clear_config([:instance, :safe_dm_mentions], true)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- assert "safe_dm_mentions" in response["metadata"]["features"]
-
- Config.put([:instance, :safe_dm_mentions], false)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- refute "safe_dm_mentions" in response["metadata"]["features"]
- end
-
- describe "`metadata/federation/enabled`" do
- setup do: clear_config([:instance, :federating])
-
- test "it shows if federation is enabled/disabled", %{conn: conn} do
- Config.put([:instance, :federating], true)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- assert response["metadata"]["federation"]["enabled"] == true
-
- Config.put([:instance, :federating], false)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- assert response["metadata"]["federation"]["enabled"] == false
- end
- end
-
- test "it shows default features flags", %{conn: conn} do
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- default_features = [
- "pleroma_api",
- "mastodon_api",
- "mastodon_api_streaming",
- "polls",
- "pleroma_explicit_addressing",
- "shareable_emoji_packs",
- "multifetch",
- "pleroma_emoji_reactions",
- "pleroma:api/v1/notifications:include_types_filter",
- "pleroma_chat_messages"
- ]
-
- assert MapSet.subset?(
- MapSet.new(default_features),
- MapSet.new(response["metadata"]["features"])
- )
- end
-
- test "it shows MRF transparency data if enabled", %{conn: conn} do
- clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
- clear_config([:mrf, :transparency], true)
-
- simple_config = %{"reject" => ["example.com"]}
- clear_config(:mrf_simple, simple_config)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- assert response["metadata"]["federation"]["mrf_simple"] == simple_config
- end
-
- test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do
- clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
- clear_config([:mrf, :transparency], true)
- clear_config([:mrf, :transparency_exclusions], ["other.site"])
-
- simple_config = %{"reject" => ["example.com", "other.site"]}
- clear_config(:mrf_simple, simple_config)
-
- expected_config = %{"reject" => ["example.com"]}
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
-
- assert response["metadata"]["federation"]["mrf_simple"] == expected_config
- assert response["metadata"]["federation"]["exclusions"] == true
- end
-end
diff --git a/test/web/oauth/app_test.exs b/test/web/oauth/app_test.exs
deleted file mode 100644
index 993a490e0..000000000
--- a/test/web/oauth/app_test.exs
+++ /dev/null
@@ -1,44 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.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
-
- test "has unique client_id" do
- insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop")
-
- error =
- catch_error(insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop"))
-
- assert %Ecto.ConstraintError{} = error
- assert error.constraint == "apps_client_id_index"
- assert error.type == :unique
- end
- end
-end
diff --git a/test/web/oauth/authorization_test.exs b/test/web/oauth/authorization_test.exs
deleted file mode 100644
index d74b26cf8..000000000
--- a/test/web/oauth/authorization_test.exs
+++ /dev/null
@@ -1,77 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.OAuth.AuthorizationTest do
- use Pleroma.DataCase
- alias Pleroma.Web.OAuth.App
- alias Pleroma.Web.OAuth.Authorization
- import Pleroma.Factory
-
- setup do
- {:ok, app} =
- Repo.insert(
- App.register_changeset(%App{}, %{
- client_name: "client",
- scopes: ["read", "write"],
- redirect_uris: "url"
- })
- )
-
- %{app: app}
- end
-
- test "create an authorization token for a valid app", %{app: app} do
- user = insert(:user)
-
- {:ok, auth1} = Authorization.create_authorization(app, user)
- assert auth1.scopes == app.scopes
-
- {:ok, auth2} = Authorization.create_authorization(app, user, ["read"])
- assert auth2.scopes == ["read"]
-
- for auth <- [auth1, auth2] do
- assert auth.user_id == user.id
- assert auth.app_id == app.id
- assert String.length(auth.token) > 10
- assert auth.used == false
- end
- end
-
- test "use up a token", %{app: app} do
- user = insert(:user)
-
- {:ok, auth} = Authorization.create_authorization(app, user)
-
- {:ok, auth} = Authorization.use_token(auth)
-
- assert auth.used == true
-
- assert {:error, "already used"} == Authorization.use_token(auth)
-
- expired_auth = %Authorization{
- user_id: user.id,
- app_id: app.id,
- valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), -10),
- token: "mytoken",
- used: false
- }
-
- {:ok, expired_auth} = Repo.insert(expired_auth)
-
- assert {:error, "token expired"} == Authorization.use_token(expired_auth)
- end
-
- test "delete authorizations", %{app: app} do
- user = insert(:user)
-
- {:ok, auth} = Authorization.create_authorization(app, user)
- {:ok, auth} = Authorization.use_token(auth)
-
- Authorization.delete_user_authorizations(user)
-
- {_, invalid} = Authorization.use_token(auth)
-
- assert auth != invalid
- end
-end
diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/web/oauth/ldap_authorization_test.exs
deleted file mode 100644
index 63b1c0eb8..000000000
--- a/test/web/oauth/ldap_authorization_test.exs
+++ /dev/null
@@ -1,135 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
- use Pleroma.Web.ConnCase
- alias Pleroma.Repo
- alias Pleroma.Web.OAuth.Token
- import Pleroma.Factory
- import Mock
-
- @skip if !Code.ensure_loaded?(:eldap), do: :skip
-
- setup_all do: clear_config([:ldap, :enabled], true)
-
- setup_all do: clear_config(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator)
-
- @tag @skip
- test "authorizes the existing user using LDAP credentials" do
- password = "testpassword"
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password))
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
- port = Pleroma.Config.get([:ldap, :port])
-
- with_mocks [
- {:eldap, [],
- [
- open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
- simple_bind: fn _connection, _dn, ^password -> :ok end,
- close: fn _connection ->
- send(self(), :close_connection)
- :ok
- end
- ]}
- ] do
- 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 %{"access_token" => token} = json_response(conn, 200)
-
- token = Repo.get_by(Token, token: token)
-
- assert token.user_id == user.id
- assert_received :close_connection
- end
- end
-
- @tag @skip
- test "creates a new user after successful LDAP authorization" do
- password = "testpassword"
- user = build(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
- port = Pleroma.Config.get([:ldap, :port])
-
- with_mocks [
- {:eldap, [],
- [
- open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
- simple_bind: fn _connection, _dn, ^password -> :ok end,
- equalityMatch: fn _type, _value -> :ok end,
- wholeSubtree: fn -> :ok end,
- search: fn _connection, _options ->
- {:ok, {:eldap_search_result, [{:eldap_entry, '', []}], []}}
- end,
- close: fn _connection ->
- send(self(), :close_connection)
- :ok
- end
- ]}
- ] do
- 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 %{"access_token" => token} = json_response(conn, 200)
-
- token = Repo.get_by(Token, token: token) |> Repo.preload(:user)
-
- assert token.user.nickname == user.nickname
- assert_received :close_connection
- end
- end
-
- @tag @skip
- test "disallow authorization for wrong LDAP credentials" do
- password = "testpassword"
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password))
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
- port = Pleroma.Config.get([:ldap, :port])
-
- with_mocks [
- {:eldap, [],
- [
- open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:ok, self()} end,
- simple_bind: fn _connection, _dn, ^password -> {:error, :invalidCredentials} end,
- close: fn _connection ->
- send(self(), :close_connection)
- :ok
- end
- ]}
- ] do
- 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 %{"error" => "Invalid credentials"} = json_response(conn, 400)
- assert_received :close_connection
- end
- end
-end
diff --git a/test/web/oauth/mfa_controller_test.exs b/test/web/oauth/mfa_controller_test.exs
deleted file mode 100644
index 3c341facd..000000000
--- a/test/web/oauth/mfa_controller_test.exs
+++ /dev/null
@@ -1,306 +0,0 @@
-# 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.MFAControllerTest do
- use Pleroma.Web.ConnCase
- import Pleroma.Factory
-
- alias Pleroma.MFA
- alias Pleroma.MFA.BackupCodes
- alias Pleroma.MFA.TOTP
- alias Pleroma.Repo
- alias Pleroma.Web.OAuth.Authorization
- alias Pleroma.Web.OAuth.OAuthController
-
- setup %{conn: conn} do
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- backup_codes: [Pbkdf2.hash_pwd_salt("test-code")],
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- app = insert(:oauth_app)
- {:ok, conn: conn, user: user, app: app}
- end
-
- describe "show" do
- setup %{conn: conn, user: user, app: app} do
- mfa_token =
- insert(:mfa_token,
- user: user,
- authorization: build(:oauth_authorization, app: app, scopes: ["write"])
- )
-
- {:ok, conn: conn, mfa_token: mfa_token}
- end
-
- test "GET /oauth/mfa renders mfa forms", %{conn: conn, mfa_token: mfa_token} do
- conn =
- get(
- conn,
- "/oauth/mfa",
- %{
- "mfa_token" => mfa_token.token,
- "state" => "a_state",
- "redirect_uri" => "http://localhost:8080/callback"
- }
- )
-
- assert response = html_response(conn, 200)
- assert response =~ "Two-factor authentication"
- assert response =~ mfa_token.token
- assert response =~ "http://localhost:8080/callback"
- end
-
- test "GET /oauth/mfa renders mfa recovery forms", %{conn: conn, mfa_token: mfa_token} do
- conn =
- get(
- conn,
- "/oauth/mfa",
- %{
- "mfa_token" => mfa_token.token,
- "state" => "a_state",
- "redirect_uri" => "http://localhost:8080/callback",
- "challenge_type" => "recovery"
- }
- )
-
- assert response = html_response(conn, 200)
- assert response =~ "Two-factor recovery"
- assert response =~ mfa_token.token
- assert response =~ "http://localhost:8080/callback"
- end
- end
-
- describe "verify" do
- setup %{conn: conn, user: user, app: app} do
- mfa_token =
- insert(:mfa_token,
- user: user,
- authorization: build(:oauth_authorization, app: app, scopes: ["write"])
- )
-
- {:ok, conn: conn, user: user, mfa_token: mfa_token, app: app}
- end
-
- test "POST /oauth/mfa/verify, verify totp code", %{
- conn: conn,
- user: user,
- mfa_token: mfa_token,
- app: app
- } do
- otp_token = TOTP.generate_token(user.multi_factor_authentication_settings.totp.secret)
-
- conn =
- conn
- |> post("/oauth/mfa/verify", %{
- "mfa" => %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "totp",
- "code" => otp_token,
- "state" => "a_state",
- "redirect_uri" => OAuthController.default_redirect_uri(app)
- }
- })
-
- target = redirected_to(conn)
- target_url = %URI{URI.parse(target) | query: nil} |> URI.to_string()
- query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
- assert %{"state" => "a_state", "code" => code} = query
- assert target_url == OAuthController.default_redirect_uri(app)
- auth = Repo.get_by(Authorization, token: code)
- assert auth.scopes == ["write"]
- end
-
- test "POST /oauth/mfa/verify, verify recovery code", %{
- conn: conn,
- mfa_token: mfa_token,
- app: app
- } do
- conn =
- conn
- |> post("/oauth/mfa/verify", %{
- "mfa" => %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "recovery",
- "code" => "test-code",
- "state" => "a_state",
- "redirect_uri" => OAuthController.default_redirect_uri(app)
- }
- })
-
- target = redirected_to(conn)
- target_url = %URI{URI.parse(target) | query: nil} |> URI.to_string()
- query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
- assert %{"state" => "a_state", "code" => code} = query
- assert target_url == OAuthController.default_redirect_uri(app)
- auth = Repo.get_by(Authorization, token: code)
- assert auth.scopes == ["write"]
- end
- end
-
- describe "challenge/totp" do
- test "returns access token with valid code", %{conn: conn, user: user, app: app} do
- otp_token = TOTP.generate_token(user.multi_factor_authentication_settings.totp.secret)
-
- mfa_token =
- insert(:mfa_token,
- user: user,
- authorization: build(:oauth_authorization, app: app, scopes: ["write"])
- )
-
- response =
- conn
- |> post("/oauth/mfa/challenge", %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "totp",
- "code" => otp_token,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(:ok)
-
- ap_id = user.ap_id
-
- assert match?(
- %{
- "access_token" => _,
- "expires_in" => 600,
- "me" => ^ap_id,
- "refresh_token" => _,
- "scope" => "write",
- "token_type" => "Bearer"
- },
- response
- )
- end
-
- test "returns errors when mfa token invalid", %{conn: conn, user: user, app: app} do
- otp_token = TOTP.generate_token(user.multi_factor_authentication_settings.totp.secret)
-
- response =
- conn
- |> post("/oauth/mfa/challenge", %{
- "mfa_token" => "XXX",
- "challenge_type" => "totp",
- "code" => otp_token,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(400)
-
- assert response == %{"error" => "Invalid code"}
- end
-
- test "returns error when otp code is invalid", %{conn: conn, user: user, app: app} do
- mfa_token = insert(:mfa_token, user: user)
-
- response =
- conn
- |> post("/oauth/mfa/challenge", %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "totp",
- "code" => "XXX",
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(400)
-
- assert response == %{"error" => "Invalid code"}
- end
-
- test "returns error when client credentails is wrong ", %{conn: conn, user: user} do
- otp_token = TOTP.generate_token(user.multi_factor_authentication_settings.totp.secret)
- mfa_token = insert(:mfa_token, user: user)
-
- response =
- conn
- |> post("/oauth/mfa/challenge", %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "totp",
- "code" => otp_token,
- "client_id" => "xxx",
- "client_secret" => "xxx"
- })
- |> json_response(400)
-
- assert response == %{"error" => "Invalid code"}
- end
- end
-
- describe "challenge/recovery" do
- setup %{conn: conn} do
- app = insert(:oauth_app)
- {:ok, conn: conn, app: app}
- end
-
- test "returns access token with valid code", %{conn: conn, app: app} do
- otp_secret = TOTP.generate_secret()
-
- [code | _] = backup_codes = BackupCodes.generate()
-
- hashed_codes =
- backup_codes
- |> Enum.map(&Pbkdf2.hash_pwd_salt(&1))
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- backup_codes: hashed_codes,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- mfa_token =
- insert(:mfa_token,
- user: user,
- authorization: build(:oauth_authorization, app: app, scopes: ["write"])
- )
-
- response =
- conn
- |> post("/oauth/mfa/challenge", %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "recovery",
- "code" => code,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(:ok)
-
- ap_id = user.ap_id
-
- assert match?(
- %{
- "access_token" => _,
- "expires_in" => 600,
- "me" => ^ap_id,
- "refresh_token" => _,
- "scope" => "write",
- "token_type" => "Bearer"
- },
- response
- )
-
- error_response =
- conn
- |> post("/oauth/mfa/challenge", %{
- "mfa_token" => mfa_token.token,
- "challenge_type" => "recovery",
- "code" => code,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(400)
-
- assert error_response == %{"error" => "Invalid code"}
- end
- end
-end
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
deleted file mode 100644
index 1200126b8..000000000
--- a/test/web/oauth/oauth_controller_test.exs
+++ /dev/null
@@ -1,1232 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.OAuth.OAuthControllerTest do
- use Pleroma.Web.ConnCase
- import Pleroma.Factory
-
- alias Pleroma.MFA
- alias Pleroma.MFA.TOTP
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.OAuth.Authorization
- alias Pleroma.Web.OAuth.OAuthController
- alias Pleroma.Web.OAuth.Token
-
- @session_opts [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
- setup do
- clear_config([:instance, :account_activation_required])
- clear_config([:instance, :account_approval_required])
- end
-
- describe "in OAuth consumer mode, " do
- setup do
- [
- app: insert(:oauth_app),
- conn:
- build_conn()
- |> Plug.Session.call(Plug.Session.init(@session_opts))
- |> fetch_session()
- ]
- end
-
- setup do: clear_config([:auth, :oauth_consumer_strategies], ~w(twitter facebook))
-
- test "GET /oauth/authorize renders auth forms, including OAuth consumer form", %{
- app: app,
- conn: conn
- } do
- conn =
- get(
- conn,
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "scope" => "read"
- }
- )
-
- assert response = html_response(conn, 200)
- assert response =~ "Sign in with Twitter"
- assert response =~ o_auth_path(conn, :prepare_request)
- end
-
- test "GET /oauth/prepare_request encodes parameters as `state` and redirects", %{
- app: app,
- conn: conn
- } do
- conn =
- get(
- conn,
- "/oauth/prepare_request",
- %{
- "provider" => "twitter",
- "authorization" => %{
- "scope" => "read follow",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => "a_state"
- }
- }
- )
-
- assert response = html_response(conn, 302)
-
- redirect_query = URI.parse(redirected_to(conn)).query
- assert %{"state" => state_param} = URI.decode_query(redirect_query)
- assert {:ok, state_components} = Poison.decode(state_param)
-
- expected_client_id = app.client_id
- expected_redirect_uri = app.redirect_uris
-
- assert %{
- "scope" => "read follow",
- "client_id" => ^expected_client_id,
- "redirect_uri" => ^expected_redirect_uri,
- "state" => "a_state"
- } = state_components
- end
-
- test "with user-bound registration, GET /oauth/<provider>/callback redirects to `redirect_uri` with `code`",
- %{app: app, conn: conn} do
- registration = insert(:registration)
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- state_params = %{
- "scope" => Enum.join(app.scopes, " "),
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "state" => ""
- }
-
- conn =
- conn
- |> assign(:ueberauth_auth, %{provider: registration.provider, uid: registration.uid})
- |> get(
- "/oauth/twitter/callback",
- %{
- "oauth_token" => "G-5a3AAAAAAAwMH9AAABaektfSM",
- "oauth_verifier" => "QZl8vUqNvXMTKpdmUnGejJxuHG75WWWs",
- "provider" => "twitter",
- "state" => Poison.encode!(state_params)
- }
- )
-
- assert response = html_response(conn, 302)
- assert redirected_to(conn) =~ ~r/#{redirect_uri}\?code=.+/
- end
-
- test "with user-unbound registration, GET /oauth/<provider>/callback renders registration_details page",
- %{app: app, conn: conn} do
- user = insert(:user)
-
- state_params = %{
- "scope" => "read write",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => "a_state"
- }
-
- conn =
- conn
- |> assign(:ueberauth_auth, %{
- provider: "twitter",
- uid: "171799000",
- info: %{nickname: user.nickname, email: user.email, name: user.name, description: nil}
- })
- |> get(
- "/oauth/twitter/callback",
- %{
- "oauth_token" => "G-5a3AAAAAAAwMH9AAABaektfSM",
- "oauth_verifier" => "QZl8vUqNvXMTKpdmUnGejJxuHG75WWWs",
- "provider" => "twitter",
- "state" => Poison.encode!(state_params)
- }
- )
-
- assert response = html_response(conn, 200)
- assert response =~ ~r/name="op" type="submit" value="register"/
- assert response =~ ~r/name="op" type="submit" value="connect"/
- assert response =~ user.email
- assert response =~ user.nickname
- end
-
- test "on authentication error, GET /oauth/<provider>/callback redirects to `redirect_uri`", %{
- app: app,
- conn: conn
- } do
- state_params = %{
- "scope" => Enum.join(app.scopes, " "),
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => ""
- }
-
- conn =
- conn
- |> assign(:ueberauth_failure, %{errors: [%{message: "(error description)"}]})
- |> get(
- "/oauth/twitter/callback",
- %{
- "oauth_token" => "G-5a3AAAAAAAwMH9AAABaektfSM",
- "oauth_verifier" => "QZl8vUqNvXMTKpdmUnGejJxuHG75WWWs",
- "provider" => "twitter",
- "state" => Poison.encode!(state_params)
- }
- )
-
- assert response = html_response(conn, 302)
- assert redirected_to(conn) == app.redirect_uris
- assert get_flash(conn, :error) == "Failed to authenticate: (error description)."
- end
-
- test "GET /oauth/registration_details renders registration details form", %{
- app: app,
- conn: conn
- } do
- conn =
- get(
- conn,
- "/oauth/registration_details",
- %{
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => "a_state",
- "nickname" => nil,
- "email" => "john@doe.com"
- }
- }
- )
-
- assert response = html_response(conn, 200)
- assert response =~ ~r/name="op" type="submit" value="register"/
- assert response =~ ~r/name="op" type="submit" value="connect"/
- end
-
- test "with valid params, POST /oauth/register?op=register redirects to `redirect_uri` with `code`",
- %{
- app: app,
- conn: conn
- } do
- registration = insert(:registration, user: nil, info: %{"nickname" => nil, "email" => nil})
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- conn =
- conn
- |> put_session(:registration_id, registration.id)
- |> post(
- "/oauth/register",
- %{
- "op" => "register",
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "state" => "a_state",
- "nickname" => "availablenick",
- "email" => "available@email.com"
- }
- }
- )
-
- assert response = html_response(conn, 302)
- assert redirected_to(conn) =~ ~r/#{redirect_uri}\?code=.+/
- end
-
- test "with unlisted `redirect_uri`, POST /oauth/register?op=register results in HTTP 401",
- %{
- app: app,
- conn: conn
- } do
- registration = insert(:registration, user: nil, info: %{"nickname" => nil, "email" => nil})
- unlisted_redirect_uri = "http://cross-site-request.com"
-
- conn =
- conn
- |> put_session(:registration_id, registration.id)
- |> post(
- "/oauth/register",
- %{
- "op" => "register",
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => unlisted_redirect_uri,
- "state" => "a_state",
- "nickname" => "availablenick",
- "email" => "available@email.com"
- }
- }
- )
-
- assert response = html_response(conn, 401)
- end
-
- test "with invalid params, POST /oauth/register?op=register renders registration_details page",
- %{
- app: app,
- conn: conn
- } do
- another_user = insert(:user)
- registration = insert(:registration, user: nil, info: %{"nickname" => nil, "email" => nil})
-
- params = %{
- "op" => "register",
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => "a_state",
- "nickname" => "availablenickname",
- "email" => "available@email.com"
- }
- }
-
- for {bad_param, bad_param_value} <-
- [{"nickname", another_user.nickname}, {"email", another_user.email}] do
- bad_registration_attrs = %{
- "authorization" => Map.put(params["authorization"], bad_param, bad_param_value)
- }
-
- bad_params = Map.merge(params, bad_registration_attrs)
-
- conn =
- conn
- |> put_session(:registration_id, registration.id)
- |> post("/oauth/register", bad_params)
-
- assert html_response(conn, 403) =~ ~r/name="op" type="submit" value="register"/
- assert get_flash(conn, :error) == "Error: #{bad_param} has already been taken."
- end
- end
-
- test "with valid params, POST /oauth/register?op=connect redirects to `redirect_uri` with `code`",
- %{
- app: app,
- conn: conn
- } do
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt("testpassword"))
- registration = insert(:registration, user: nil)
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- conn =
- conn
- |> put_session(:registration_id, registration.id)
- |> post(
- "/oauth/register",
- %{
- "op" => "connect",
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "state" => "a_state",
- "name" => user.nickname,
- "password" => "testpassword"
- }
- }
- )
-
- assert response = html_response(conn, 302)
- assert redirected_to(conn) =~ ~r/#{redirect_uri}\?code=.+/
- end
-
- test "with unlisted `redirect_uri`, POST /oauth/register?op=connect results in HTTP 401`",
- %{
- app: app,
- conn: conn
- } do
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt("testpassword"))
- registration = insert(:registration, user: nil)
- unlisted_redirect_uri = "http://cross-site-request.com"
-
- conn =
- conn
- |> put_session(:registration_id, registration.id)
- |> post(
- "/oauth/register",
- %{
- "op" => "connect",
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => unlisted_redirect_uri,
- "state" => "a_state",
- "name" => user.nickname,
- "password" => "testpassword"
- }
- }
- )
-
- assert response = html_response(conn, 401)
- end
-
- test "with invalid params, POST /oauth/register?op=connect renders registration_details page",
- %{
- app: app,
- conn: conn
- } do
- user = insert(:user)
- registration = insert(:registration, user: nil)
-
- params = %{
- "op" => "connect",
- "authorization" => %{
- "scopes" => app.scopes,
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => "a_state",
- "name" => user.nickname,
- "password" => "wrong password"
- }
- }
-
- conn =
- conn
- |> put_session(:registration_id, registration.id)
- |> post("/oauth/register", params)
-
- assert html_response(conn, 401) =~ ~r/name="op" type="submit" value="connect"/
- assert get_flash(conn, :error) == "Invalid Username/Password"
- end
- end
-
- describe "GET /oauth/authorize" do
- setup do
- [
- app: insert(:oauth_app, redirect_uris: "https://redirect.url"),
- conn:
- build_conn()
- |> Plug.Session.call(Plug.Session.init(@session_opts))
- |> fetch_session()
- ]
- end
-
- test "renders authentication page", %{app: app, conn: conn} do
- conn =
- get(
- conn,
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "scope" => "read"
- }
- )
-
- assert html_response(conn, 200) =~ ~s(type="submit")
- end
-
- test "properly handles internal calls with `authorization`-wrapped params", %{
- app: app,
- conn: conn
- } do
- conn =
- get(
- conn,
- "/oauth/authorize",
- %{
- "authorization" => %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "scope" => "read"
- }
- }
- )
-
- assert html_response(conn, 200) =~ ~s(type="submit")
- end
-
- test "renders authentication page if user is already authenticated but `force_login` is tru-ish",
- %{app: app, conn: conn} do
- token = insert(:oauth_token, app: app)
-
- conn =
- conn
- |> put_session(:oauth_token, token.token)
- |> get(
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "scope" => "read",
- "force_login" => "true"
- }
- )
-
- assert html_response(conn, 200) =~ ~s(type="submit")
- end
-
- test "renders authentication page if user is already authenticated but user request with another client",
- %{
- app: app,
- conn: conn
- } do
- token = insert(:oauth_token, app: app)
-
- conn =
- conn
- |> put_session(:oauth_token, token.token)
- |> get(
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => "another_client_id",
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "scope" => "read"
- }
- )
-
- assert html_response(conn, 200) =~ ~s(type="submit")
- end
-
- test "with existing authentication and non-OOB `redirect_uri`, redirects to app with `token` and `state` params",
- %{
- app: app,
- conn: conn
- } do
- token = insert(:oauth_token, app: app)
-
- conn =
- conn
- |> put_session(:oauth_token, token.token)
- |> get(
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "state" => "specific_client_state",
- "scope" => "read"
- }
- )
-
- assert URI.decode(redirected_to(conn)) ==
- "https://redirect.url?access_token=#{token.token}&state=specific_client_state"
- end
-
- test "with existing authentication and unlisted non-OOB `redirect_uri`, redirects without credentials",
- %{
- app: app,
- conn: conn
- } do
- unlisted_redirect_uri = "http://cross-site-request.com"
- token = insert(:oauth_token, app: app)
-
- conn =
- conn
- |> put_session(:oauth_token, token.token)
- |> get(
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => unlisted_redirect_uri,
- "state" => "specific_client_state",
- "scope" => "read"
- }
- )
-
- assert redirected_to(conn) == unlisted_redirect_uri
- end
-
- test "with existing authentication and OOB `redirect_uri`, redirects to app with `token` and `state` params",
- %{
- app: app,
- conn: conn
- } do
- token = insert(:oauth_token, app: app)
-
- conn =
- conn
- |> put_session(:oauth_token, token.token)
- |> get(
- "/oauth/authorize",
- %{
- "response_type" => "code",
- "client_id" => app.client_id,
- "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
- "scope" => "read"
- }
- )
-
- assert html_response(conn, 200) =~ "Authorization exists"
- end
- end
-
- describe "POST /oauth/authorize" do
- test "redirects with oauth authorization, " <>
- "granting requested app-supported scopes to both admin- and non-admin users" do
- app_scopes = ["read", "write", "admin", "secret_scope"]
- app = insert(:oauth_app, scopes: app_scopes)
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- non_admin = insert(:user, is_admin: false)
- admin = insert(:user, is_admin: true)
- scopes_subset = ["read:subscope", "write", "admin"]
-
- # In case scope param is missing, expecting _all_ app-supported scopes to be granted
- for user <- [non_admin, admin],
- {requested_scopes, expected_scopes} <-
- %{scopes_subset => scopes_subset, nil: app_scopes} do
- conn =
- post(
- build_conn(),
- "/oauth/authorize",
- %{
- "authorization" => %{
- "name" => user.nickname,
- "password" => "test",
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "scope" => requested_scopes,
- "state" => "statepassed"
- }
- }
- )
-
- target = redirected_to(conn)
- assert target =~ redirect_uri
-
- query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
-
- assert %{"state" => "statepassed", "code" => code} = query
- auth = Repo.get_by(Authorization, token: code)
- assert auth
- assert auth.scopes == expected_scopes
- end
- end
-
- test "redirect to on two-factor auth page" do
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- app = insert(:oauth_app, scopes: ["read", "write", "follow"])
-
- conn =
- build_conn()
- |> post("/oauth/authorize", %{
- "authorization" => %{
- "name" => user.nickname,
- "password" => "test",
- "client_id" => app.client_id,
- "redirect_uri" => app.redirect_uris,
- "scope" => "read write",
- "state" => "statepassed"
- }
- })
-
- result = html_response(conn, 200)
-
- mfa_token = Repo.get_by(MFA.Token, user_id: user.id)
- assert result =~ app.redirect_uris
- assert result =~ "statepassed"
- assert result =~ mfa_token.token
- assert result =~ "Two-factor authentication"
- end
-
- test "returns 401 for wrong credentials", %{conn: conn} do
- user = insert(:user)
- app = insert(:oauth_app)
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- result =
- conn
- |> post("/oauth/authorize", %{
- "authorization" => %{
- "name" => user.nickname,
- "password" => "wrong",
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "state" => "statepassed",
- "scope" => Enum.join(app.scopes, " ")
- }
- })
- |> html_response(:unauthorized)
-
- # Keep the details
- assert result =~ app.client_id
- assert result =~ redirect_uri
-
- # Error message
- assert result =~ "Invalid Username/Password"
- end
-
- test "returns 401 for missing scopes" do
- user = insert(:user, is_admin: false)
- app = insert(:oauth_app, scopes: ["read", "write", "admin"])
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- result =
- build_conn()
- |> post("/oauth/authorize", %{
- "authorization" => %{
- "name" => user.nickname,
- "password" => "test",
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "state" => "statepassed",
- "scope" => ""
- }
- })
- |> html_response(:unauthorized)
-
- # Keep the details
- assert result =~ app.client_id
- assert result =~ redirect_uri
-
- # Error message
- assert result =~ "This action is outside the authorized scopes"
- end
-
- test "returns 401 for scopes beyond app scopes hierarchy", %{conn: conn} do
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
- redirect_uri = OAuthController.default_redirect_uri(app)
-
- result =
- conn
- |> post("/oauth/authorize", %{
- "authorization" => %{
- "name" => user.nickname,
- "password" => "test",
- "client_id" => app.client_id,
- "redirect_uri" => redirect_uri,
- "state" => "statepassed",
- "scope" => "read write follow"
- }
- })
- |> html_response(:unauthorized)
-
- # Keep the details
- assert result =~ app.client_id
- assert result =~ redirect_uri
-
- # Error message
- assert result =~ "This action is outside the authorized scopes"
- end
- end
-
- describe "POST /oauth/token" do
- test "issues a token for an all-body request" do
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["write"])
-
- conn =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "authorization_code",
- "code" => auth.token,
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
-
- assert %{"access_token" => token, "me" => ap_id} = json_response(conn, 200)
-
- token = Repo.get_by(Token, token: token)
- assert token
- assert token.scopes == auth.scopes
- assert user.ap_id == ap_id
- end
-
- test "issues a token for `password` grant_type with valid credentials, with full permissions by default" do
- password = "testpassword"
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password))
-
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- # Note: "scope" param is intentionally omitted
- 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 %{"access_token" => token} = json_response(conn, 200)
-
- token = Repo.get_by(Token, token: token)
- assert token
- assert token.scopes == app.scopes
- end
-
- test "issues a mfa token for `password` grant_type, when MFA enabled" do
- password = "testpassword"
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- password_hash: Pbkdf2.hash_pwd_salt(password),
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- response =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "password",
- "username" => user.nickname,
- "password" => password,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(403)
-
- assert match?(
- %{
- "supported_challenge_types" => "totp",
- "mfa_token" => _,
- "error" => "mfa_required"
- },
- response
- )
-
- token = Repo.get_by(MFA.Token, token: response["mfa_token"])
- assert token.user_id == user.id
- assert token.authorization_id
- end
-
- test "issues a token for request with HTTP basic auth client credentials" do
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["scope1", "scope2", "scope3"])
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["scope1", "scope2"])
- assert auth.scopes == ["scope1", "scope2"]
-
- app_encoded =
- (URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
- |> Base.encode64()
-
- conn =
- build_conn()
- |> put_req_header("authorization", "Basic " <> app_encoded)
- |> post("/oauth/token", %{
- "grant_type" => "authorization_code",
- "code" => auth.token,
- "redirect_uri" => OAuthController.default_redirect_uri(app)
- })
-
- assert %{"access_token" => token, "scope" => scope} = json_response(conn, 200)
-
- assert scope == "scope1 scope2"
-
- token = Repo.get_by(Token, token: token)
- assert token
- assert token.scopes == ["scope1", "scope2"]
- end
-
- test "issue a token for client_credentials grant type" do
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- conn =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "client_credentials",
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
-
- assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
- json_response(conn, 200)
-
- assert token
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- assert refresh
- assert scope == "read write"
- end
-
- test "rejects token exchange with invalid client credentials" do
- user = insert(:user)
- app = insert(:oauth_app)
-
- {:ok, auth} = Authorization.create_authorization(app, user)
-
- conn =
- build_conn()
- |> put_req_header("authorization", "Basic JTIxOiVGMCU5RiVBNCVCNwo=")
- |> post("/oauth/token", %{
- "grant_type" => "authorization_code",
- "code" => auth.token,
- "redirect_uri" => OAuthController.default_redirect_uri(app)
- })
-
- assert resp = json_response(conn, 400)
- assert %{"error" => _} = resp
- refute Map.has_key?(resp, "access_token")
- end
-
- 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"
-
- {:ok, user} =
- insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password))
- |> User.confirmation_changeset(need_confirmation: true)
- |> User.update_and_set_cache()
-
- refute Pleroma.User.account_status(user) == :active
-
- app = insert(:oauth_app)
-
- 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 %{"error" => _} = resp
- refute Map.has_key?(resp, "access_token")
- end
-
- test "rejects token exchange for valid credentials belonging to deactivated user" do
- password = "testpassword"
-
- user =
- insert(:user,
- password_hash: Pbkdf2.hash_pwd_salt(password),
- deactivated: true
- )
-
- app = insert(:oauth_app)
-
- resp =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "password",
- "username" => user.nickname,
- "password" => password,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(403)
-
- assert resp == %{
- "error" => "Your account is currently disabled",
- "identifier" => "account_is_disabled"
- }
- end
-
- test "rejects token exchange for user with password_reset_pending set to true" do
- password = "testpassword"
-
- user =
- insert(:user,
- password_hash: Pbkdf2.hash_pwd_salt(password),
- password_reset_pending: true
- )
-
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- resp =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "password",
- "username" => user.nickname,
- "password" => password,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(403)
-
- assert resp == %{
- "error" => "Password reset is required",
- "identifier" => "password_reset_required"
- }
- end
-
- test "rejects token exchange for user with confirmation_pending set to true" do
- Pleroma.Config.put([:instance, :account_activation_required], true)
- password = "testpassword"
-
- user =
- insert(:user,
- password_hash: Pbkdf2.hash_pwd_salt(password),
- confirmation_pending: true
- )
-
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- resp =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "password",
- "username" => user.nickname,
- "password" => password,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(403)
-
- assert resp == %{
- "error" => "Your login is missing a confirmed e-mail address",
- "identifier" => "missing_confirmed_email"
- }
- end
-
- test "rejects token exchange for valid credentials belonging to an unapproved user" do
- password = "testpassword"
-
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password), approval_pending: true)
-
- refute Pleroma.User.account_status(user) == :active
-
- app = insert(:oauth_app)
-
- 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 %{"error" => _} = resp
- refute Map.has_key?(resp, "access_token")
- end
-
- test "rejects an invalid authorization code" do
- app = insert(:oauth_app)
-
- conn =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "authorization_code",
- "code" => "Imobviouslyinvalid",
- "redirect_uri" => OAuthController.default_redirect_uri(app),
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
-
- assert resp = json_response(conn, 400)
- assert %{"error" => _} = json_response(conn, 400)
- refute Map.has_key?(resp, "access_token")
- end
- end
-
- describe "POST /oauth/token - refresh token" do
- setup do: clear_config([:oauth2, :issue_new_refresh_token])
-
- test "issues a new access token with keep fresh token" do
- Pleroma.Config.put([:oauth2, :issue_new_refresh_token], true)
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["write"])
- {:ok, token} = Token.exchange_token(app, auth)
-
- response =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "refresh_token",
- "refresh_token" => token.refresh_token,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(200)
-
- ap_id = user.ap_id
-
- assert match?(
- %{
- "scope" => "write",
- "token_type" => "Bearer",
- "expires_in" => 600,
- "access_token" => _,
- "refresh_token" => _,
- "me" => ^ap_id
- },
- response
- )
-
- refute Repo.get_by(Token, token: token.token)
- new_token = Repo.get_by(Token, token: response["access_token"])
- assert new_token.refresh_token == token.refresh_token
- assert new_token.scopes == auth.scopes
- assert new_token.user_id == user.id
- assert new_token.app_id == app.id
- end
-
- test "issues a new access token with new fresh token" do
- Pleroma.Config.put([:oauth2, :issue_new_refresh_token], false)
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["write"])
- {:ok, token} = Token.exchange_token(app, auth)
-
- response =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "refresh_token",
- "refresh_token" => token.refresh_token,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(200)
-
- ap_id = user.ap_id
-
- assert match?(
- %{
- "scope" => "write",
- "token_type" => "Bearer",
- "expires_in" => 600,
- "access_token" => _,
- "refresh_token" => _,
- "me" => ^ap_id
- },
- response
- )
-
- refute Repo.get_by(Token, token: token.token)
- new_token = Repo.get_by(Token, token: response["access_token"])
- refute new_token.refresh_token == token.refresh_token
- assert new_token.scopes == auth.scopes
- assert new_token.user_id == user.id
- assert new_token.app_id == app.id
- end
-
- test "returns 400 if we try use access token" do
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["write"])
- {:ok, token} = Token.exchange_token(app, auth)
-
- response =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "refresh_token",
- "refresh_token" => token.token,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(400)
-
- assert %{"error" => "Invalid credentials"} == response
- end
-
- test "returns 400 if refresh_token invalid" do
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- response =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "refresh_token",
- "refresh_token" => "token.refresh_token",
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(400)
-
- assert %{"error" => "Invalid credentials"} == response
- end
-
- test "issues a new token if token expired" do
- user = insert(:user)
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["write"])
- {:ok, token} = Token.exchange_token(app, auth)
-
- change =
- Ecto.Changeset.change(
- token,
- %{valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), -86_400 * 30)}
- )
-
- {:ok, access_token} = Repo.update(change)
-
- response =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "refresh_token",
- "refresh_token" => access_token.refresh_token,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
- |> json_response(200)
-
- ap_id = user.ap_id
-
- assert match?(
- %{
- "scope" => "write",
- "token_type" => "Bearer",
- "expires_in" => 600,
- "access_token" => _,
- "refresh_token" => _,
- "me" => ^ap_id
- },
- response
- )
-
- refute Repo.get_by(Token, token: token.token)
- token = Repo.get_by(Token, token: response["access_token"])
- assert token
- assert token.scopes == auth.scopes
- assert token.user_id == user.id
- assert token.app_id == app.id
- end
- end
-
- describe "POST /oauth/token - bad request" do
- test "returns 500" do
- response =
- build_conn()
- |> post("/oauth/token", %{})
- |> json_response(500)
-
- assert %{"error" => "Bad request"} == response
- end
- end
-
- describe "POST /oauth/revoke - bad request" do
- test "returns 500" do
- response =
- build_conn()
- |> post("/oauth/revoke", %{})
- |> json_response(500)
-
- assert %{"error" => "Bad request"} == response
- end
- end
-end
diff --git a/test/web/oauth/token/utils_test.exs b/test/web/oauth/token/utils_test.exs
deleted file mode 100644
index a610d92f8..000000000
--- a/test/web/oauth/token/utils_test.exs
+++ /dev/null
@@ -1,53 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.OAuth.Token.UtilsTest do
- use Pleroma.DataCase
- alias Pleroma.Web.OAuth.Token.Utils
- import Pleroma.Factory
-
- describe "fetch_app/1" do
- test "returns error when credentials is invalid" do
- assert {:error, :not_found} =
- Utils.fetch_app(%Plug.Conn{params: %{"client_id" => 1, "client_secret" => "x"}})
- end
-
- test "returns App by params credentails" do
- app = insert(:oauth_app)
-
- assert {:ok, load_app} =
- Utils.fetch_app(%Plug.Conn{
- params: %{"client_id" => app.client_id, "client_secret" => app.client_secret}
- })
-
- assert load_app == app
- end
-
- test "returns App by header credentails" do
- app = insert(:oauth_app)
- header = "Basic " <> Base.encode64("#{app.client_id}:#{app.client_secret}")
-
- conn =
- %Plug.Conn{}
- |> Plug.Conn.put_req_header("authorization", header)
-
- assert {:ok, load_app} = Utils.fetch_app(conn)
- assert load_app == app
- end
- end
-
- describe "format_created_at/1" do
- test "returns formatted created at" do
- token = insert(:oauth_token)
- date = Utils.format_created_at(token)
-
- token_date =
- token.inserted_at
- |> DateTime.from_naive!("Etc/UTC")
- |> DateTime.to_unix()
-
- assert token_date == date
- end
- end
-end
diff --git a/test/web/oauth/token_test.exs b/test/web/oauth/token_test.exs
deleted file mode 100644
index 40d71eb59..000000000
--- a/test/web/oauth/token_test.exs
+++ /dev/null
@@ -1,85 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.OAuth.TokenTest do
- use Pleroma.DataCase
- alias Pleroma.Repo
- alias Pleroma.Web.OAuth.App
- alias Pleroma.Web.OAuth.Authorization
- alias Pleroma.Web.OAuth.Token
-
- import Pleroma.Factory
-
- test "exchanges a auth token for an access token, preserving `scopes`" do
- {:ok, app} =
- Repo.insert(
- App.register_changeset(%App{}, %{
- client_name: "client",
- scopes: ["read", "write"],
- redirect_uris: "url"
- })
- )
-
- user = insert(:user)
-
- {:ok, auth} = Authorization.create_authorization(app, user, ["read"])
- assert auth.scopes == ["read"]
-
- {:ok, token} = Token.exchange_token(app, auth)
-
- assert token.app_id == app.id
- assert token.user_id == user.id
- assert token.scopes == auth.scopes
- assert String.length(token.token) > 10
- assert String.length(token.refresh_token) > 10
-
- auth = Repo.get(Authorization, auth.id)
- {:error, "already used"} = Token.exchange_token(app, auth)
- end
-
- test "deletes all tokens of a user" do
- {:ok, app1} =
- Repo.insert(
- App.register_changeset(%App{}, %{
- client_name: "client1",
- scopes: ["scope"],
- redirect_uris: "url"
- })
- )
-
- {:ok, app2} =
- Repo.insert(
- App.register_changeset(%App{}, %{
- client_name: "client2",
- scopes: ["scope"],
- redirect_uris: "url"
- })
- )
-
- user = insert(:user)
-
- {:ok, auth1} = Authorization.create_authorization(app1, user)
- {:ok, auth2} = Authorization.create_authorization(app2, user)
-
- {:ok, _token1} = Token.exchange_token(app1, auth1)
- {:ok, _token2} = Token.exchange_token(app2, auth2)
-
- {tokens, _} = Token.delete_user_tokens(user)
-
- assert tokens == 2
- end
-
- test "deletes expired tokens" do
- insert(:oauth_token, valid_until: Timex.shift(Timex.now(), days: -3))
- insert(:oauth_token, valid_until: Timex.shift(Timex.now(), days: -3))
- t3 = insert(:oauth_token)
- t4 = insert(:oauth_token, valid_until: Timex.shift(Timex.now(), minutes: 10))
- {tokens, _} = Token.delete_expired_tokens()
- assert tokens == 2
- available_tokens = Pleroma.Repo.all(Token)
-
- token_ids = available_tokens |> Enum.map(& &1.id)
- assert token_ids == [t3.id, t4.id]
- end
-end
diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs
deleted file mode 100644
index ee498f4b5..000000000
--- a/test/web/ostatus/ostatus_controller_test.exs
+++ /dev/null
@@ -1,338 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.OStatus.OStatusControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Config
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.Endpoint
-
- require Pleroma.Constants
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup do: clear_config([:instance, :federating], true)
-
- describe "Mastodon compatibility routes" do
- setup %{conn: conn} do
- conn = put_req_header(conn, "accept", "text/html")
-
- {:ok, object} =
- %{
- "type" => "Note",
- "content" => "hey",
- "id" => Endpoint.url() <> "/users/raymoo/statuses/999999999",
- "actor" => Endpoint.url() <> "/users/raymoo",
- "to" => [Pleroma.Constants.as_public()]
- }
- |> Object.create()
-
- {:ok, activity, _} =
- %{
- "id" => object.data["id"] <> "/activity",
- "type" => "Create",
- "object" => object.data["id"],
- "actor" => object.data["actor"],
- "to" => object.data["to"]
- }
- |> ActivityPub.persist(local: true)
-
- %{conn: conn, activity: activity}
- end
-
- test "redirects to /notice/:id for html format", %{conn: conn, activity: activity} do
- conn = get(conn, "/users/raymoo/statuses/999999999")
- assert redirected_to(conn) == "/notice/#{activity.id}"
- end
-
- test "redirects to /notice/:id for html format for activity", %{
- conn: conn,
- activity: activity
- } do
- conn = get(conn, "/users/raymoo/statuses/999999999/activity")
- assert redirected_to(conn) == "/notice/#{activity.id}"
- end
- end
-
- # Note: see ActivityPubControllerTest for JSON format tests
- describe "GET /objects/:uuid (text/html)" do
- setup %{conn: conn} do
- conn = put_req_header(conn, "accept", "text/html")
- %{conn: conn}
- end
-
- test "redirects to /notice/id for html format", %{conn: conn} do
- note_activity = insert(:note_activity)
- object = Object.normalize(note_activity)
- [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
- url = "/objects/#{uuid}"
-
- conn = get(conn, url)
- assert redirected_to(conn) == "/notice/#{note_activity.id}"
- end
-
- test "404s on private objects", %{conn: conn} do
- note_activity = insert(:direct_note_activity)
- object = Object.normalize(note_activity)
- [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
-
- conn
- |> get("/objects/#{uuid}")
- |> response(404)
- end
-
- test "404s on non-existing objects", %{conn: conn} do
- conn
- |> get("/objects/123")
- |> response(404)
- end
- end
-
- # Note: see ActivityPubControllerTest for JSON format tests
- describe "GET /activities/:uuid (text/html)" do
- setup %{conn: conn} do
- conn = put_req_header(conn, "accept", "text/html")
- %{conn: conn}
- end
-
- test "redirects to /notice/id for html format", %{conn: conn} do
- note_activity = insert(:note_activity)
- [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"]))
-
- conn = get(conn, "/activities/#{uuid}")
- assert redirected_to(conn) == "/notice/#{note_activity.id}"
- end
-
- test "404s on private activities", %{conn: conn} do
- note_activity = insert(:direct_note_activity)
- [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"]))
-
- conn
- |> get("/activities/#{uuid}")
- |> response(404)
- end
-
- test "404s on nonexistent activities", %{conn: conn} do
- conn
- |> get("/activities/123")
- |> response(404)
- end
- end
-
- describe "GET notice/2" do
- test "redirects to a proper object URL when json requested and the object is local", %{
- conn: conn
- } do
- note_activity = insert(:note_activity)
- expected_redirect_url = Object.normalize(note_activity).data["id"]
-
- redirect_url =
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/notice/#{note_activity.id}")
- |> redirected_to()
-
- assert redirect_url == expected_redirect_url
- end
-
- test "returns a 404 on remote notice when json requested", %{conn: conn} do
- note_activity = insert(:note_activity, local: false)
-
- conn
- |> put_req_header("accept", "application/activity+json")
- |> get("/notice/#{note_activity.id}")
- |> response(404)
- end
-
- test "500s when actor not found", %{conn: conn} do
- note_activity = insert(:note_activity)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
- User.invalidate_cache(user)
- Pleroma.Repo.delete(user)
-
- conn =
- conn
- |> get("/notice/#{note_activity.id}")
-
- assert response(conn, 500) == ~S({"error":"Something went wrong"})
- end
-
- test "render html for redirect for html format", %{conn: conn} do
- note_activity = insert(:note_activity)
-
- resp =
- conn
- |> put_req_header("accept", "text/html")
- |> get("/notice/#{note_activity.id}")
- |> response(200)
-
- assert resp =~
- "<meta content=\"#{Pleroma.Web.base_url()}/notice/#{note_activity.id}\" property=\"og:url\">"
-
- user = insert(:user)
-
- {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id)
-
- assert like_activity.data["type"] == "Like"
-
- resp =
- conn
- |> put_req_header("accept", "text/html")
- |> get("/notice/#{like_activity.id}")
- |> response(200)
-
- assert resp =~ "<!--server-generated-meta-->"
- end
-
- test "404s a private notice", %{conn: conn} do
- note_activity = insert(:direct_note_activity)
- url = "/notice/#{note_activity.id}"
-
- conn =
- conn
- |> get(url)
-
- assert response(conn, 404)
- end
-
- test "404s a non-existing notice", %{conn: conn} do
- url = "/notice/123"
-
- conn =
- conn
- |> get(url)
-
- assert response(conn, 404)
- end
-
- test "it requires authentication if instance is NOT federating", %{
- conn: conn
- } do
- user = insert(:user)
- note_activity = insert(:note_activity)
-
- conn = put_req_header(conn, "accept", "text/html")
-
- ensure_federating_or_authenticated(conn, "/notice/#{note_activity.id}", user)
- end
- end
-
- describe "GET /notice/:id/embed_player" do
- setup do
- note_activity = insert(:note_activity)
- object = Pleroma.Object.normalize(note_activity)
-
- object_data =
- Map.put(object.data, "attachment", [
- %{
- "url" => [
- %{
- "href" =>
- "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
- "mediaType" => "video/mp4",
- "type" => "Link"
- }
- ]
- }
- ])
-
- object
- |> Ecto.Changeset.change(data: object_data)
- |> Pleroma.Repo.update()
-
- %{note_activity: note_activity}
- end
-
- test "renders embed player", %{conn: conn, note_activity: note_activity} do
- conn = get(conn, "/notice/#{note_activity.id}/embed_player")
-
- assert Plug.Conn.get_resp_header(conn, "x-frame-options") == ["ALLOW"]
-
- assert Plug.Conn.get_resp_header(
- conn,
- "content-security-policy"
- ) == [
- "default-src 'none';style-src 'self' 'unsafe-inline';img-src 'self' data: https:; media-src 'self' https:;"
- ]
-
- assert response(conn, 200) =~
- "<video controls loop><source src=\"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4\" type=\"video/mp4\">Your browser does not support video/mp4 playback.</video>"
- end
-
- test "404s when activity isn't create", %{conn: conn} do
- note_activity = insert(:note_activity, data_attrs: %{"type" => "Like"})
-
- assert conn
- |> get("/notice/#{note_activity.id}/embed_player")
- |> response(404)
- end
-
- test "404s when activity is direct message", %{conn: conn} do
- note_activity = insert(:note_activity, data_attrs: %{"directMessage" => true})
-
- assert conn
- |> get("/notice/#{note_activity.id}/embed_player")
- |> response(404)
- end
-
- test "404s when attachment is empty", %{conn: conn} do
- note_activity = insert(:note_activity)
- object = Pleroma.Object.normalize(note_activity)
- object_data = Map.put(object.data, "attachment", [])
-
- object
- |> Ecto.Changeset.change(data: object_data)
- |> Pleroma.Repo.update()
-
- assert conn
- |> get("/notice/#{note_activity.id}/embed_player")
- |> response(404)
- end
-
- test "404s when attachment isn't audio or video", %{conn: conn} do
- note_activity = insert(:note_activity)
- object = Pleroma.Object.normalize(note_activity)
-
- object_data =
- Map.put(object.data, "attachment", [
- %{
- "url" => [
- %{
- "href" => "https://peertube.moe/static/webseed/480.jpg",
- "mediaType" => "image/jpg",
- "type" => "Link"
- }
- ]
- }
- ])
-
- object
- |> Ecto.Changeset.change(data: object_data)
- |> Pleroma.Repo.update()
-
- conn
- |> get("/notice/#{note_activity.id}/embed_player")
- |> response(404)
- end
-
- test "it requires authentication if instance is NOT federating", %{
- conn: conn,
- note_activity: note_activity
- } do
- user = insert(:user)
- conn = put_req_header(conn, "accept", "text/html")
-
- ensure_federating_or_authenticated(conn, "/notice/#{note_activity.id}/embed_player", user)
- end
- end
-end
diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs
deleted file mode 100644
index 07909d48b..000000000
--- a/test/web/pleroma_api/controllers/account_controller_test.exs
+++ /dev/null
@@ -1,284 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Config
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
- import Swoosh.TestAssertions
-
- describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
- setup do
- {:ok, user} =
- insert(:user)
- |> User.confirmation_changeset(need_confirmation: true)
- |> User.update_and_set_cache()
-
- assert user.confirmation_pending
-
- [user: user]
- end
-
- setup do: clear_config([:instance, :account_activation_required], true)
-
- test "resend account confirmation email", %{conn: conn, user: user} do
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}")
- |> json_response_and_validate_schema(: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])
-
- assert_email_sent(
- from: {instance_name, notify_email},
- to: {user.name, user.email},
- html_body: email.html_body
- )
- end
-
- test "resend account confirmation email (with nickname)", %{conn: conn, user: user} do
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/accounts/confirmation_resend?nickname=#{user.nickname}")
- |> json_response_and_validate_schema(: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])
-
- assert_email_sent(
- from: {instance_name, notify_email},
- to: {user.name, user.email},
- html_body: email.html_body
- )
- end
- end
-
- describe "getting favorites timeline of specified user" do
- setup do
- [current_user, user] = insert_pair(:user, hide_favorites: false)
- %{user: current_user, conn: conn} = oauth_access(["read:favourites"], user: current_user)
- [current_user: current_user, user: user, conn: conn]
- end
-
- test "returns list of statuses favorited by specified user", %{
- conn: conn,
- user: user
- } do
- [activity | _] = insert_pair(:note_activity)
- CommonAPI.favorite(user, activity.id)
-
- response =
- conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response_and_validate_schema(:ok)
-
- [like] = response
-
- assert length(response) == 1
- assert like["id"] == activity.id
- end
-
- test "returns favorites for specified user_id when requester is not logged in", %{
- user: user
- } do
- activity = insert(:note_activity)
- CommonAPI.favorite(user, activity.id)
-
- response =
- build_conn()
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response_and_validate_schema(200)
-
- assert length(response) == 1
- end
-
- test "returns favorited DM only when user is logged in and he is one of recipients", %{
- current_user: current_user,
- user: user
- } do
- {:ok, direct} =
- CommonAPI.post(current_user, %{
- status: "Hi @#{user.nickname}!",
- visibility: "direct"
- })
-
- CommonAPI.favorite(user, direct.id)
-
- for u <- [user, current_user] do
- response =
- build_conn()
- |> assign(:user, u)
- |> assign(:token, insert(:oauth_token, user: u, scopes: ["read:favourites"]))
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response_and_validate_schema(:ok)
-
- assert length(response) == 1
- end
-
- response =
- build_conn()
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response_and_validate_schema(200)
-
- assert length(response) == 0
- end
-
- test "does not return others' favorited DM when user is not one of recipients", %{
- conn: conn,
- user: user
- } do
- user_two = insert(:user)
-
- {:ok, direct} =
- CommonAPI.post(user_two, %{
- status: "Hi @#{user.nickname}!",
- visibility: "direct"
- })
-
- CommonAPI.favorite(user, direct.id)
-
- response =
- conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "paginates favorites using since_id and max_id", %{
- conn: conn,
- user: user
- } do
- activities = insert_list(10, :note_activity)
-
- Enum.each(activities, fn activity ->
- CommonAPI.favorite(user, activity.id)
- end)
-
- third_activity = Enum.at(activities, 2)
- seventh_activity = Enum.at(activities, 6)
-
- response =
- conn
- |> get(
- "/api/v1/pleroma/accounts/#{user.id}/favourites?since_id=#{third_activity.id}&max_id=#{
- seventh_activity.id
- }"
- )
- |> json_response_and_validate_schema(:ok)
-
- assert length(response) == 3
- refute third_activity in response
- refute seventh_activity in response
- end
-
- test "limits favorites using limit parameter", %{
- conn: conn,
- user: user
- } do
- 7
- |> insert_list(:note_activity)
- |> Enum.each(fn activity ->
- CommonAPI.favorite(user, activity.id)
- end)
-
- response =
- conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites?limit=3")
- |> json_response_and_validate_schema(:ok)
-
- assert length(response) == 3
- end
-
- test "returns empty response when user does not have any favorited statuses", %{
- conn: conn,
- user: user
- } do
- response =
- conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response_and_validate_schema(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "returns 404 error when specified user is not exist", %{conn: conn} do
- conn = get(conn, "/api/v1/pleroma/accounts/test/favourites")
-
- assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
- end
-
- test "returns 403 error when user has hidden own favorites", %{conn: conn} do
- user = insert(:user, hide_favorites: true)
- activity = insert(:note_activity)
- CommonAPI.favorite(user, activity.id)
-
- conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites")
-
- assert json_response_and_validate_schema(conn, 403) == %{"error" => "Can't get favorites"}
- end
-
- test "hides favorites for new users by default", %{conn: conn} do
- user = insert(:user)
- activity = insert(:note_activity)
- CommonAPI.favorite(user, activity.id)
-
- assert user.hide_favorites
- conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites")
-
- assert json_response_and_validate_schema(conn, 403) == %{"error" => "Can't get favorites"}
- end
- end
-
- describe "subscribing / unsubscribing" do
- test "subscribing / unsubscribing to a user" do
- %{user: user, conn: conn} = oauth_access(["follow"])
- subscription_target = insert(:user)
-
- ret_conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe")
-
- assert %{"id" => _id, "subscribing" => true} =
- json_response_and_validate_schema(ret_conn, 200)
-
- conn = post(conn, "/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe")
-
- assert %{"id" => _id, "subscribing" => false} = json_response_and_validate_schema(conn, 200)
- end
- end
-
- describe "subscribing" do
- test "returns 404 when subscription_target not found" do
- %{conn: conn} = oauth_access(["write:follows"])
-
- conn = post(conn, "/api/v1/pleroma/accounts/target_id/subscribe")
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404)
- end
- end
-
- describe "unsubscribing" do
- test "returns 404 when subscription_target not found" do
- %{conn: conn} = oauth_access(["follow"])
-
- conn = post(conn, "/api/v1/pleroma/accounts/target_id/unsubscribe")
-
- assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404)
- end
- end
-end
diff --git a/test/web/pleroma_api/controllers/chat_controller_test.exs b/test/web/pleroma_api/controllers/chat_controller_test.exs
deleted file mode 100644
index 44a78a738..000000000
--- a/test/web/pleroma_api/controllers/chat_controller_test.exs
+++ /dev/null
@@ -1,390 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "POST /api/v1/pleroma/chats/:id/messages/:message_id/read" do
- setup do: oauth_access(["write:chats"])
-
- test "it marks one message as read", %{conn: conn, user: user} do
- other_user = insert(:user)
-
- {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
- {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
- object = Object.normalize(create, false)
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- assert cm_ref.unread == true
-
- result =
- conn
- |> post("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}/read")
- |> json_response_and_validate_schema(200)
-
- assert result["unread"] == false
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- assert cm_ref.unread == false
- end
- end
-
- describe "POST /api/v1/pleroma/chats/:id/read" do
- setup do: oauth_access(["write:chats"])
-
- test "given a `last_read_id`, it marks everything until then as read", %{
- conn: conn,
- user: user
- } do
- other_user = insert(:user)
-
- {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
- {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
- object = Object.normalize(create, false)
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- assert cm_ref.unread == true
-
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/chats/#{chat.id}/read", %{"last_read_id" => cm_ref.id})
- |> json_response_and_validate_schema(200)
-
- assert result["unread"] == 1
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- assert cm_ref.unread == false
- end
- end
-
- describe "POST /api/v1/pleroma/chats/:id/messages" do
- setup do: oauth_access(["write:chats"])
-
- test "it posts a message to the chat", %{conn: conn, user: user} do
- other_user = insert(:user)
-
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "Hallo!!"})
- |> json_response_and_validate_schema(200)
-
- assert result["content"] == "Hallo!!"
- assert result["chat_id"] == chat.id |> to_string()
- end
-
- test "it fails if there is no content", %{conn: conn, user: user} do
- other_user = insert(:user)
-
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/chats/#{chat.id}/messages")
- |> json_response_and_validate_schema(400)
-
- assert %{"error" => "no_content"} == result
- end
-
- test "it works with an attachment", %{conn: conn, user: user} do
- 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)
-
- other_user = insert(:user)
-
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{
- "media_id" => to_string(upload.id)
- })
- |> json_response_and_validate_schema(200)
-
- assert result["attachment"]
- end
-
- test "gets MRF reason when rejected", %{conn: conn, user: user} do
- clear_config([:mrf_keyword, :reject], ["GNO"])
- clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
-
- other_user = insert(:user)
-
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "GNO/Linux"})
- |> json_response_and_validate_schema(422)
-
- assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} == result
- end
- end
-
- describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
- setup do: oauth_access(["write:chats"])
-
- test "it deletes a message from the chat", %{conn: conn, user: user} do
- recipient = insert(:user)
-
- {:ok, message} =
- CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend")
-
- {:ok, other_message} = CommonAPI.post_chat_message(recipient, user, "nico nico ni")
-
- object = Object.normalize(message, false)
-
- chat = Chat.get(user.id, recipient.ap_id)
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- # Deleting your own message removes the message and the reference
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}")
- |> json_response_and_validate_schema(200)
-
- assert result["id"] == cm_ref.id
- refute MessageReference.get_by_id(cm_ref.id)
- assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id)
-
- # Deleting other people's messages just removes the reference
- object = Object.normalize(other_message, false)
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- result =
- conn
- |> put_req_header("content-type", "application/json")
- |> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}")
- |> json_response_and_validate_schema(200)
-
- assert result["id"] == cm_ref.id
- refute MessageReference.get_by_id(cm_ref.id)
- assert Object.get_by_id(object.id)
- end
- end
-
- describe "GET /api/v1/pleroma/chats/:id/messages" do
- setup do: oauth_access(["read:chats"])
-
- test "it paginates", %{conn: conn, user: user} do
- recipient = insert(:user)
-
- Enum.each(1..30, fn _ ->
- {:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey")
- end)
-
- chat = Chat.get(user.id, recipient.ap_id)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats/#{chat.id}/messages")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 20
-
- result =
- conn
- |> get("/api/v1/pleroma/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 10
- end
-
- test "it returns the messages for a given chat", %{conn: conn, user: user} do
- other_user = insert(:user)
- third_user = insert(:user)
-
- {:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey")
- {:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey")
- {:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?")
- {:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?")
-
- chat = Chat.get(user.id, other_user.ap_id)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats/#{chat.id}/messages")
- |> json_response_and_validate_schema(200)
-
- result
- |> Enum.each(fn message ->
- assert message["chat_id"] == chat.id |> to_string()
- end)
-
- assert length(result) == 3
-
- # Trying to get the chat of a different user
- result =
- conn
- |> assign(:user, other_user)
- |> get("/api/v1/pleroma/chats/#{chat.id}/messages")
-
- assert result |> json_response(404)
- end
- end
-
- describe "POST /api/v1/pleroma/chats/by-account-id/:id" do
- setup do: oauth_access(["write:chats"])
-
- test "it creates or returns a chat", %{conn: conn} do
- other_user = insert(:user)
-
- result =
- conn
- |> post("/api/v1/pleroma/chats/by-account-id/#{other_user.id}")
- |> json_response_and_validate_schema(200)
-
- assert result["id"]
- end
- end
-
- describe "GET /api/v1/pleroma/chats/:id" do
- setup do: oauth_access(["read:chats"])
-
- test "it returns a chat", %{conn: conn, user: user} do
- other_user = insert(:user)
-
- {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats/#{chat.id}")
- |> json_response_and_validate_schema(200)
-
- assert result["id"] == to_string(chat.id)
- end
- end
-
- describe "GET /api/v1/pleroma/chats" do
- setup do: oauth_access(["read:chats"])
-
- test "it does not return chats with deleted users", %{conn: conn, user: user} do
- recipient = insert(:user)
- {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
-
- Pleroma.Repo.delete(recipient)
- User.invalidate_cache(recipient)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 0
- end
-
- test "it does not return chats with users you blocked", %{conn: conn, user: user} do
- recipient = insert(:user)
-
- {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 1
-
- User.block(user, recipient)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 0
- end
-
- test "it returns all chats", %{conn: conn, user: user} do
- Enum.each(1..30, fn _ ->
- recipient = insert(:user)
- {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
- end)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 30
- end
-
- test "it return a list of chats the current user is participating in, in descending order of updates",
- %{conn: conn, user: user} do
- har = insert(:user)
- jafnhar = insert(:user)
- tridi = insert(:user)
-
- {:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id)
- :timer.sleep(1000)
- {:ok, _chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
- :timer.sleep(1000)
- {:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id)
- :timer.sleep(1000)
-
- # bump the second one
- {:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats")
- |> json_response_and_validate_schema(200)
-
- ids = Enum.map(result, & &1["id"])
-
- assert ids == [
- chat_2.id |> to_string(),
- chat_3.id |> to_string(),
- chat_1.id |> to_string()
- ]
- end
-
- test "it is not affected by :restrict_unauthenticated setting (issue #1973)", %{
- conn: conn,
- user: user
- } do
- clear_config([:restrict_unauthenticated, :profiles, :local], true)
- clear_config([:restrict_unauthenticated, :profiles, :remote], true)
-
- user2 = insert(:user)
- user3 = insert(:user, local: false)
-
- {:ok, _chat_12} = Chat.get_or_create(user.id, user2.ap_id)
- {:ok, _chat_13} = Chat.get_or_create(user.id, user3.ap_id)
-
- result =
- conn
- |> get("/api/v1/pleroma/chats")
- |> json_response_and_validate_schema(200)
-
- account_ids = Enum.map(result, &get_in(&1, ["account", "id"]))
- assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id])
- end
- end
-end
diff --git a/test/web/pleroma_api/controllers/conversation_controller_test.exs b/test/web/pleroma_api/controllers/conversation_controller_test.exs
deleted file mode 100644
index e6d0b3e37..000000000
--- a/test/web/pleroma_api/controllers/conversation_controller_test.exs
+++ /dev/null
@@ -1,136 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.ConversationControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Conversation.Participation
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "/api/v1/pleroma/conversations/:id" do
- user = insert(:user)
- %{user: other_user, conn: conn} = oauth_access(["read:statuses"])
-
- {:ok, _activity} =
- CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"})
-
- [participation] = Participation.for_user(other_user)
-
- result =
- conn
- |> get("/api/v1/pleroma/conversations/#{participation.id}")
- |> json_response_and_validate_schema(200)
-
- assert result["id"] == participation.id |> to_string()
- end
-
- test "/api/v1/pleroma/conversations/:id/statuses" do
- user = insert(:user)
- %{user: other_user, conn: conn} = oauth_access(["read:statuses"])
- third_user = insert(:user)
-
- {:ok, _activity} =
- CommonAPI.post(user, %{status: "Hi @#{third_user.nickname}!", visibility: "direct"})
-
- {:ok, activity} =
- CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"})
-
- [participation] = Participation.for_user(other_user)
-
- {:ok, activity_two} =
- CommonAPI.post(other_user, %{
- status: "Hi!",
- in_reply_to_status_id: activity.id,
- in_reply_to_conversation_id: participation.id
- })
-
- result =
- conn
- |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses")
- |> json_response_and_validate_schema(200)
-
- assert length(result) == 2
-
- id_one = activity.id
- id_two = activity_two.id
- assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result
-
- {:ok, %{id: id_three}} =
- CommonAPI.post(other_user, %{
- status: "Bye!",
- in_reply_to_status_id: activity.id,
- in_reply_to_conversation_id: participation.id
- })
-
- assert [%{"id" => ^id_two}, %{"id" => ^id_three}] =
- conn
- |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?limit=2")
- |> json_response_and_validate_schema(:ok)
-
- assert [%{"id" => ^id_three}] =
- conn
- |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?min_id=#{id_two}")
- |> json_response_and_validate_schema(:ok)
- end
-
- test "PATCH /api/v1/pleroma/conversations/:id" do
- %{user: user, conn: conn} = oauth_access(["write:conversations"])
- other_user = insert(:user)
-
- {:ok, _activity} = CommonAPI.post(user, %{status: "Hi", visibility: "direct"})
-
- [participation] = Participation.for_user(user)
-
- participation = Repo.preload(participation, :recipients)
-
- user = User.get_cached_by_id(user.id)
- assert [user] == participation.recipients
- assert other_user not in participation.recipients
-
- query = "recipients[]=#{user.id}&recipients[]=#{other_user.id}"
-
- result =
- conn
- |> patch("/api/v1/pleroma/conversations/#{participation.id}?#{query}")
- |> json_response_and_validate_schema(200)
-
- assert result["id"] == participation.id |> to_string
-
- [participation] = Participation.for_user(user)
- participation = Repo.preload(participation, :recipients)
-
- assert user in participation.recipients
- assert other_user in participation.recipients
- end
-
- test "POST /api/v1/pleroma/conversations/read" do
- user = insert(:user)
- %{user: other_user, conn: conn} = oauth_access(["write:conversations"])
-
- {:ok, _activity} =
- CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"})
-
- {:ok, _activity} =
- CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"})
-
- [participation2, participation1] = Participation.for_user(other_user)
- assert Participation.get(participation2.id).read == false
- assert Participation.get(participation1.id).read == false
- assert User.get_cached_by_id(other_user.id).unread_conversation_count == 2
-
- [%{"unread" => false}, %{"unread" => false}] =
- conn
- |> post("/api/v1/pleroma/conversations/read", %{})
- |> json_response_and_validate_schema(200)
-
- [participation2, participation1] = Participation.for_user(other_user)
- assert Participation.get(participation2.id).read == true
- assert Participation.get(participation1.id).read == true
- assert User.get_cached_by_id(other_user.id).unread_conversation_count == 0
- end
-end
diff --git a/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs b/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs
deleted file mode 100644
index e113bb15f..000000000
--- a/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs
+++ /dev/null
@@ -1,861 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
- use Pleroma.Web.ConnCase
-
- import Tesla.Mock
- import Pleroma.Factory
-
- @emoji_path Path.join(
- Pleroma.Config.get!([:instance, :static_dir]),
- "emoji"
- )
- setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
-
- setup do: clear_config([:instance, :public], true)
-
- setup do
- admin = insert(:user, is_admin: true)
- token = insert(:oauth_admin_token, user: admin)
-
- admin_conn =
- build_conn()
- |> assign(:user, admin)
- |> assign(:token, token)
-
- Pleroma.Emoji.reload()
- {:ok, %{admin_conn: admin_conn}}
- end
-
- test "GET /api/pleroma/emoji/packs when :public: false", %{conn: conn} do
- Config.put([:instance, :public], false)
- conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
- end
-
- test "GET /api/pleroma/emoji/packs", %{conn: conn} do
- resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
-
- assert resp["count"] == 3
-
- assert resp["packs"]
- |> Map.keys()
- |> length() == 3
-
- shared = resp["packs"]["test_pack"]
- assert shared["files"] == %{"blank" => "blank.png", "blank2" => "blank2.png"}
- assert Map.has_key?(shared["pack"], "download-sha256")
- assert shared["pack"]["can-download"]
- assert shared["pack"]["share-files"]
-
- non_shared = resp["packs"]["test_pack_nonshared"]
- assert non_shared["pack"]["share-files"] == false
- assert non_shared["pack"]["can-download"] == false
-
- resp =
- conn
- |> get("/api/pleroma/emoji/packs?page_size=1")
- |> json_response_and_validate_schema(200)
-
- assert resp["count"] == 3
-
- packs = Map.keys(resp["packs"])
-
- assert length(packs) == 1
-
- [pack1] = packs
-
- resp =
- conn
- |> get("/api/pleroma/emoji/packs?page_size=1&page=2")
- |> json_response_and_validate_schema(200)
-
- assert resp["count"] == 3
- packs = Map.keys(resp["packs"])
- assert length(packs) == 1
- [pack2] = packs
-
- resp =
- conn
- |> get("/api/pleroma/emoji/packs?page_size=1&page=3")
- |> json_response_and_validate_schema(200)
-
- assert resp["count"] == 3
- packs = Map.keys(resp["packs"])
- assert length(packs) == 1
- [pack3] = packs
- assert [pack1, pack2, pack3] |> Enum.uniq() |> length() == 3
- end
-
- describe "GET /api/pleroma/emoji/packs/remote" do
- test "shareable instance", %{admin_conn: admin_conn, conn: conn} do
- resp =
- conn
- |> get("/api/pleroma/emoji/packs")
- |> json_response_and_validate_schema(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 admin_conn
- |> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
- |> json_response_and_validate_schema(200) == resp
- end
-
- test "non shareable instance", %{admin_conn: admin_conn} do
- 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: []}})
- end)
-
- assert admin_conn
- |> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
- |> json_response_and_validate_schema(500) == %{
- "error" => "The requested instance does not support sharing emoji packs"
- }
- end
- end
-
- describe "GET /api/pleroma/emoji/packs/:name/archive" do
- test "download shared pack", %{conn: conn} do
- resp =
- conn
- |> get("/api/pleroma/emoji/packs/test_pack/archive")
- |> 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 "non existing pack", %{conn: conn} do
- assert conn
- |> get("/api/pleroma/emoji/packs/test_pack_for_import/archive")
- |> json_response_and_validate_schema(:not_found) == %{
- "error" => "Pack test_pack_for_import does not exist"
- }
- end
-
- test "non downloadable pack", %{conn: conn} do
- assert conn
- |> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive")
- |> json_response_and_validate_schema(:forbidden) == %{
- "error" =>
- "Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
- }
- end
- end
-
- describe "POST /api/pleroma/emoji/packs/download" do
- test "shared pack from remote and non shared from fallback-src", %{
- admin_conn: admin_conn,
- conn: conn
- } do
- 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/test_pack"
- } ->
- conn
- |> get("/api/pleroma/emoji/packs/test_pack")
- |> json_response_and_validate_schema(200)
- |> json()
-
- %{
- method: :get,
- url: "https://example.com/api/pleroma/emoji/packs/test_pack/archive"
- } ->
- conn
- |> get("/api/pleroma/emoji/packs/test_pack/archive")
- |> response(200)
- |> text()
-
- %{
- method: :get,
- url: "https://example.com/api/pleroma/emoji/packs/test_pack_nonshared"
- } ->
- conn
- |> get("/api/pleroma/emoji/packs/test_pack_nonshared")
- |> json_response_and_validate_schema(200)
- |> json()
-
- %{
- method: :get,
- url: "https://nonshared-pack"
- } ->
- text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip"))
- end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/download", %{
- url: "https://example.com",
- name: "test_pack",
- as: "test_pack2"
- })
- |> json_response_and_validate_schema(200) == "ok"
-
- assert File.exists?("#{@emoji_path}/test_pack2/pack.json")
- assert File.exists?("#{@emoji_path}/test_pack2/blank.png")
-
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/test_pack2")
- |> json_response_and_validate_schema(200) == "ok"
-
- refute File.exists?("#{@emoji_path}/test_pack2")
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post(
- "/api/pleroma/emoji/packs/download",
- %{
- url: "https://example.com",
- name: "test_pack_nonshared",
- as: "test_pack_nonshared2"
- }
- )
- |> json_response_and_validate_schema(200) == "ok"
-
- assert File.exists?("#{@emoji_path}/test_pack_nonshared2/pack.json")
- assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png")
-
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/test_pack_nonshared2")
- |> json_response_and_validate_schema(200) == "ok"
-
- refute File.exists?("#{@emoji_path}/test_pack_nonshared2")
- end
-
- test "nonshareable instance", %{admin_conn: admin_conn} do
- 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: []}})
- end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post(
- "/api/pleroma/emoji/packs/download",
- %{
- url: "https://old-instance",
- name: "test_pack",
- as: "test_pack2"
- }
- )
- |> json_response_and_validate_schema(500) == %{
- "error" => "The requested instance does not support sharing emoji packs"
- }
- end
-
- test "checksum fail", %{admin_conn: admin_conn} do
- 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/pack_bad_sha"
- } ->
- {:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
- %Tesla.Env{status: 200, body: Jason.encode!(pack)}
-
- %{
- method: :get,
- url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha/archive"
- } ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/instance_static/emoji/pack_bad_sha/pack_bad_sha.zip")
- }
- end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/download", %{
- url: "https://example.com",
- name: "pack_bad_sha",
- as: "pack_bad_sha2"
- })
- |> json_response_and_validate_schema(:internal_server_error) == %{
- "error" => "SHA256 for the pack doesn't match the one sent by the server"
- }
- end
-
- test "other error", %{admin_conn: admin_conn} do
- 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/test_pack"
- } ->
- {:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
- %Tesla.Env{status: 200, body: Jason.encode!(pack)}
- end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/download", %{
- url: "https://example.com",
- name: "test_pack",
- as: "test_pack2"
- })
- |> json_response_and_validate_schema(:internal_server_error) == %{
- "error" =>
- "The pack was not set as shared and there is no fallback src to download from"
- }
- end
- end
-
- describe "PATCH /api/pleroma/emoji/packs/:name" do
- setup do
- pack_file = "#{@emoji_path}/test_pack/pack.json"
- original_content = File.read!(pack_file)
-
- on_exit(fn ->
- File.write!(pack_file, original_content)
- end)
-
- {:ok,
- 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
- assert ctx[:admin_conn]
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]})
- |> json_response_and_validate_schema(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_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",
- "1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D"
- )
-
- assert ctx[:admin_conn]
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
- |> json_response_and_validate_schema(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")
-
- assert ctx[:admin_conn]
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "The fallback archive does not have all files specified in pack.json"
- }
- end
- end
-
- describe "POST/PATCH/DELETE /api/pleroma/emoji/packs/:name/files" do
- setup do
- pack_file = "#{@emoji_path}/test_pack/pack.json"
- original_content = File.read!(pack_file)
-
- on_exit(fn ->
- File.write!(pack_file, original_content)
- end)
-
- :ok
- end
-
- test "create shortcode exists", %{admin_conn: admin_conn} do
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank",
- filename: "dir/blank.png",
- file: %Plug.Upload{
- filename: "blank.png",
- path: "#{@emoji_path}/test_pack/blank.png"
- }
- })
- |> json_response_and_validate_schema(:conflict) == %{
- "error" => "An emoji with the \"blank\" shortcode already exists"
- }
- end
-
- test "don't rewrite old emoji", %{admin_conn: admin_conn} do
- on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank3",
- filename: "dir/blank.png",
- file: %Plug.Upload{
- filename: "blank.png",
- path: "#{@emoji_path}/test_pack/blank.png"
- }
- })
- |> json_response_and_validate_schema(200) == %{
- "blank" => "blank.png",
- "blank2" => "blank2.png",
- "blank3" => "dir/blank.png"
- }
-
- assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank",
- new_shortcode: "blank2",
- new_filename: "dir_2/blank_3.png"
- })
- |> json_response_and_validate_schema(:conflict) == %{
- "error" =>
- "New shortcode \"blank2\" is already used. If you want to override emoji use 'force' option"
- }
- end
-
- test "rewrite old emoji with force option", %{admin_conn: admin_conn} do
- on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank3",
- filename: "dir/blank.png",
- file: %Plug.Upload{
- filename: "blank.png",
- path: "#{@emoji_path}/test_pack/blank.png"
- }
- })
- |> json_response_and_validate_schema(200) == %{
- "blank" => "blank.png",
- "blank2" => "blank2.png",
- "blank3" => "dir/blank.png"
- }
-
- assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank3",
- new_shortcode: "blank4",
- new_filename: "dir_2/blank_3.png",
- force: true
- })
- |> json_response_and_validate_schema(200) == %{
- "blank" => "blank.png",
- "blank2" => "blank2.png",
- "blank4" => "dir_2/blank_3.png"
- }
-
- assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
- end
-
- test "with empty filename", %{admin_conn: admin_conn} do
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank2",
- filename: "",
- file: %Plug.Upload{
- filename: "blank.png",
- path: "#{@emoji_path}/test_pack/blank.png"
- }
- })
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack name, shortcode or filename cannot be empty"
- }
- end
-
- test "add file with not loaded pack", %{admin_conn: admin_conn} do
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/not_loaded/files", %{
- shortcode: "blank3",
- filename: "dir/blank.png",
- file: %Plug.Upload{
- filename: "blank.png",
- path: "#{@emoji_path}/test_pack/blank.png"
- }
- })
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack \"not_loaded\" is not found"
- }
- end
-
- test "remove file with not loaded pack", %{admin_conn: admin_conn} do
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/not_loaded/files?shortcode=blank3")
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack \"not_loaded\" is not found"
- }
- end
-
- test "remove file with empty shortcode", %{admin_conn: admin_conn} do
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/not_loaded/files?shortcode=")
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack name or shortcode cannot be empty"
- }
- end
-
- test "update file with not loaded pack", %{admin_conn: admin_conn} do
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/not_loaded/files", %{
- shortcode: "blank4",
- new_shortcode: "blank3",
- new_filename: "dir_2/blank_3.png"
- })
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack \"not_loaded\" is not found"
- }
- end
-
- test "new with shortcode as file with update", %{admin_conn: admin_conn} do
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank4",
- filename: "dir/blank.png",
- file: %Plug.Upload{
- filename: "blank.png",
- path: "#{@emoji_path}/test_pack/blank.png"
- }
- })
- |> json_response_and_validate_schema(200) == %{
- "blank" => "blank.png",
- "blank4" => "dir/blank.png",
- "blank2" => "blank2.png"
- }
-
- assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank4",
- new_shortcode: "blank3",
- new_filename: "dir_2/blank_3.png"
- })
- |> json_response_and_validate_schema(200) == %{
- "blank3" => "dir_2/blank_3.png",
- "blank" => "blank.png",
- "blank2" => "blank2.png"
- }
-
- refute File.exists?("#{@emoji_path}/test_pack/dir/")
- assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
-
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3")
- |> json_response_and_validate_schema(200) == %{
- "blank" => "blank.png",
- "blank2" => "blank2.png"
- }
-
- refute File.exists?("#{@emoji_path}/test_pack/dir_2/")
-
- on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir") end)
- end
-
- test "new with shortcode from url", %{admin_conn: admin_conn} do
- mock(fn
- %{
- method: :get,
- url: "https://test-blank/blank_url.png"
- } ->
- text(File.read!("#{@emoji_path}/test_pack/blank.png"))
- end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank_url",
- file: "https://test-blank/blank_url.png"
- })
- |> json_response_and_validate_schema(200) == %{
- "blank_url" => "blank_url.png",
- "blank" => "blank.png",
- "blank2" => "blank2.png"
- }
-
- assert File.exists?("#{@emoji_path}/test_pack/blank_url.png")
-
- on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/blank_url.png") end)
- end
-
- test "new without shortcode", %{admin_conn: admin_conn} do
- on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end)
-
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> post("/api/pleroma/emoji/packs/test_pack/files", %{
- file: %Plug.Upload{
- filename: "shortcode.png",
- path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"
- }
- })
- |> json_response_and_validate_schema(200) == %{
- "shortcode" => "shortcode.png",
- "blank" => "blank.png",
- "blank2" => "blank2.png"
- }
- end
-
- test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3")
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "Emoji \"blank3\" does not exist"
- }
- end
-
- test "update non existing emoji", %{admin_conn: admin_conn} do
- assert admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank3",
- new_shortcode: "blank4",
- new_filename: "dir_2/blank_3.png"
- })
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "Emoji \"blank3\" does not exist"
- }
- end
-
- test "update with empty shortcode", %{admin_conn: admin_conn} do
- assert %{
- "error" => "Missing field: new_shortcode."
- } =
- admin_conn
- |> put_req_header("content-type", "multipart/form-data")
- |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
- shortcode: "blank",
- new_filename: "dir_2/blank_3.png"
- })
- |> json_response_and_validate_schema(:bad_request)
- end
- end
-
- describe "POST/DELETE /api/pleroma/emoji/packs/:name" do
- test "creating and deleting a pack", %{admin_conn: admin_conn} do
- assert admin_conn
- |> post("/api/pleroma/emoji/packs/test_created")
- |> json_response_and_validate_schema(200) == "ok"
-
- assert File.exists?("#{@emoji_path}/test_created/pack.json")
-
- assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{
- "pack" => %{},
- "files" => %{},
- "files_count" => 0
- }
-
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/test_created")
- |> json_response_and_validate_schema(200) == "ok"
-
- refute File.exists?("#{@emoji_path}/test_created/pack.json")
- end
-
- test "if pack exists", %{admin_conn: admin_conn} do
- path = Path.join(@emoji_path, "test_created")
- File.mkdir(path)
- pack_file = Jason.encode!(%{files: %{}, pack: %{}})
- File.write!(Path.join(path, "pack.json"), pack_file)
-
- assert admin_conn
- |> post("/api/pleroma/emoji/packs/test_created")
- |> json_response_and_validate_schema(:conflict) == %{
- "error" => "A pack named \"test_created\" already exists"
- }
-
- on_exit(fn -> File.rm_rf(path) end)
- end
-
- test "with empty name", %{admin_conn: admin_conn} do
- assert admin_conn
- |> post("/api/pleroma/emoji/packs/ ")
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack name cannot be empty"
- }
- end
- end
-
- test "deleting nonexisting pack", %{admin_conn: admin_conn} do
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/non_existing")
- |> json_response_and_validate_schema(:not_found) == %{
- "error" => "Pack non_existing does not exist"
- }
- end
-
- test "deleting with empty name", %{admin_conn: admin_conn} do
- assert admin_conn
- |> delete("/api/pleroma/emoji/packs/ ")
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack name cannot be empty"
- }
- end
-
- test "filesystem import", %{admin_conn: admin_conn, conn: conn} do
- on_exit(fn ->
- File.rm!("#{@emoji_path}/test_pack_for_import/emoji.txt")
- File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
- end)
-
- resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
-
- refute Map.has_key?(resp["packs"], "test_pack_for_import")
-
- assert admin_conn
- |> get("/api/pleroma/emoji/packs/import")
- |> json_response_and_validate_schema(200) == ["test_pack_for_import"]
-
- resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
- assert resp["packs"]["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
-
- File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
- refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json")
-
- emoji_txt_content = """
- blank, blank.png, Fun
- blank2, blank.png
- foo, /emoji/test_pack_for_import/blank.png
- bar
- """
-
- File.write!("#{@emoji_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
-
- assert admin_conn
- |> get("/api/pleroma/emoji/packs/import")
- |> json_response_and_validate_schema(200) == ["test_pack_for_import"]
-
- resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
-
- assert resp["packs"]["test_pack_for_import"]["files"] == %{
- "blank" => "blank.png",
- "blank2" => "blank.png",
- "foo" => "blank.png"
- }
- end
-
- describe "GET /api/pleroma/emoji/packs/:name" do
- test "shows pack.json", %{conn: conn} do
- assert %{
- "files" => files,
- "files_count" => 2,
- "pack" => %{
- "can-download" => true,
- "description" => "Test description",
- "download-sha256" => _,
- "homepage" => "https://pleroma.social",
- "license" => "Test license",
- "share-files" => true
- }
- } =
- conn
- |> get("/api/pleroma/emoji/packs/test_pack")
- |> json_response_and_validate_schema(200)
-
- assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"}
-
- assert %{
- "files" => files,
- "files_count" => 2
- } =
- conn
- |> get("/api/pleroma/emoji/packs/test_pack?page_size=1")
- |> json_response_and_validate_schema(200)
-
- assert files |> Map.keys() |> length() == 1
-
- assert %{
- "files" => files,
- "files_count" => 2
- } =
- conn
- |> get("/api/pleroma/emoji/packs/test_pack?page_size=1&page=2")
- |> json_response_and_validate_schema(200)
-
- assert files |> Map.keys() |> length() == 1
- end
-
- test "non existing pack", %{conn: conn} do
- assert conn
- |> get("/api/pleroma/emoji/packs/non_existing")
- |> json_response_and_validate_schema(:not_found) == %{
- "error" => "Pack non_existing does not exist"
- }
- end
-
- test "error name", %{conn: conn} do
- assert conn
- |> get("/api/pleroma/emoji/packs/ ")
- |> json_response_and_validate_schema(:bad_request) == %{
- "error" => "pack name cannot be empty"
- }
- end
- end
-end
diff --git a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
deleted file mode 100644
index 3deab30d1..000000000
--- a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
+++ /dev/null
@@ -1,149 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
- use Oban.Testing, repo: Pleroma.Repo
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Object
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
-
- result =
- conn
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
- |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
- |> json_response_and_validate_schema(200)
-
- # We return the status, but this our implementation detail.
- assert %{"id" => id} = result
- assert to_string(activity.id) == id
-
- assert result["pleroma"]["emoji_reactions"] == [
- %{"name" => "☕", "count" => 1, "me" => true}
- ]
-
- # Reacting with a non-emoji
- assert conn
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
- |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/x")
- |> json_response_and_validate_schema(400)
- end
-
- test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
- {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
-
- ObanHelpers.perform_all()
-
- result =
- conn
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
- |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
-
- assert %{"id" => id} = json_response_and_validate_schema(result, 200)
- assert to_string(activity.id) == id
-
- ObanHelpers.perform_all()
-
- object = Object.get_by_ap_id(activity.data["object"])
-
- assert object.data["reaction_count"] == 0
- end
-
- test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
- doomed_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
-
- result =
- conn
- |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
- |> json_response_and_validate_schema(200)
-
- assert result == []
-
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅")
-
- User.perform(:delete, doomed_user)
-
- result =
- conn
- |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
- |> json_response_and_validate_schema(200)
-
- [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result
-
- assert represented_user["id"] == other_user.id
-
- result =
- conn
- |> assign(:user, other_user)
- |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:statuses"]))
- |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
- |> json_response_and_validate_schema(200)
-
- assert [%{"name" => "🎅", "count" => 1, "accounts" => [_represented_user], "me" => true}] =
- result
- end
-
- test "GET /api/v1/pleroma/statuses/:id/reactions with :show_reactions disabled", %{conn: conn} do
- clear_config([:instance, :show_reactions], false)
-
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
-
- result =
- conn
- |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
- |> json_response_and_validate_schema(200)
-
- assert result == []
- end
-
- test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
-
- result =
- conn
- |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
- |> json_response_and_validate_schema(200)
-
- assert result == []
-
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
- {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
-
- assert [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] =
- conn
- |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
- |> json_response_and_validate_schema(200)
-
- assert represented_user["id"] == other_user.id
- end
-end
diff --git a/test/web/pleroma_api/controllers/mascot_controller_test.exs b/test/web/pleroma_api/controllers/mascot_controller_test.exs
deleted file mode 100644
index e2ead6e15..000000000
--- a/test/web/pleroma_api/controllers/mascot_controller_test.exs
+++ /dev/null
@@ -1,73 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.User
-
- test "mascot upload" do
- %{conn: conn} = oauth_access(["write:accounts"])
-
- non_image_file = %Plug.Upload{
- content_type: "audio/mpeg",
- path: Path.absname("test/fixtures/sound.mp3"),
- filename: "sound.mp3"
- }
-
- ret_conn =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> put("/api/v1/pleroma/mascot", %{"file" => non_image_file})
-
- assert json_response_and_validate_schema(ret_conn, 415)
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- conn =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> put("/api/v1/pleroma/mascot", %{"file" => file})
-
- assert %{"id" => _, "type" => image} = json_response_and_validate_schema(conn, 200)
- end
-
- test "mascot retrieving" do
- %{user: user, conn: conn} = oauth_access(["read:accounts", "write:accounts"])
-
- # When user hasn't set a mascot, we should just get pleroma tan back
- ret_conn = get(conn, "/api/v1/pleroma/mascot")
-
- assert %{"url" => url} = json_response_and_validate_schema(ret_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"
- }
-
- ret_conn =
- conn
- |> put_req_header("content-type", "multipart/form-data")
- |> put("/api/v1/pleroma/mascot", %{"file" => file})
-
- assert json_response_and_validate_schema(ret_conn, 200)
-
- user = User.get_cached_by_id(user.id)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/pleroma/mascot")
-
- assert %{"url" => url, "type" => "image"} = json_response_and_validate_schema(conn, 200)
- assert url =~ "an_image"
- end
-end
diff --git a/test/web/pleroma_api/controllers/notification_controller_test.exs b/test/web/pleroma_api/controllers/notification_controller_test.exs
deleted file mode 100644
index bb4fe6c49..000000000
--- a/test/web/pleroma_api/controllers/notification_controller_test.exs
+++ /dev/null
@@ -1,68 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.NotificationControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Notification
- alias Pleroma.Repo
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- describe "POST /api/v1/pleroma/notifications/read" do
- setup do: oauth_access(["write:notifications"])
-
- test "it marks a single notification as read", %{user: user1, conn: conn} do
- user2 = insert(:user)
- {:ok, activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
- {:ok, activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
- {:ok, [notification1]} = Notification.create_notifications(activity1)
- {:ok, [notification2]} = Notification.create_notifications(activity2)
-
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/notifications/read", %{id: notification1.id})
- |> json_response_and_validate_schema(:ok)
-
- assert %{"pleroma" => %{"is_seen" => true}} = response
- assert Repo.get(Notification, notification1.id).seen
- refute Repo.get(Notification, notification2.id).seen
- end
-
- test "it marks multiple notifications as read", %{user: user1, conn: conn} do
- user2 = insert(:user)
- {:ok, _activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
- {:ok, _activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
- {:ok, _activity3} = CommonAPI.post(user2, %{status: "HIE @#{user1.nickname}"})
-
- [notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
-
- [response1, response2] =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/notifications/read", %{max_id: notification2.id})
- |> json_response_and_validate_schema(:ok)
-
- assert %{"pleroma" => %{"is_seen" => true}} = response1
- assert %{"pleroma" => %{"is_seen" => true}} = response2
- assert Repo.get(Notification, notification1.id).seen
- assert Repo.get(Notification, notification2.id).seen
- refute Repo.get(Notification, notification3.id).seen
- end
-
- test "it returns error when notification not found", %{conn: conn} do
- response =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/pleroma/notifications/read", %{
- id: 22_222_222_222_222
- })
- |> json_response_and_validate_schema(:bad_request)
-
- assert response == %{"error" => "Cannot get notification"}
- 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
deleted file mode 100644
index f39c07ac6..000000000
--- a/test/web/pleroma_api/controllers/scrobble_controller_test.exs
+++ /dev/null
@@ -1,60 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Web.CommonAPI
-
- describe "POST /api/v1/pleroma/scrobble" do
- test "works correctly" do
- %{conn: conn} = oauth_access(["write"])
-
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> 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_and_validate_schema(conn, 200)
- end
- end
-
- describe "GET /api/v1/pleroma/accounts/:id/scrobbles" do
- test "works correctly" do
- %{user: user, conn: conn} = oauth_access(["read"])
-
- {: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 = get(conn, "/api/v1/pleroma/accounts/#{user.id}/scrobbles")
-
- result = json_response_and_validate_schema(conn, 200)
-
- assert length(result) == 3
- end
- end
-end
diff --git a/test/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs b/test/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
deleted file mode 100644
index d23d08a00..000000000
--- a/test/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
+++ /dev/null
@@ -1,260 +0,0 @@
-defmodule Pleroma.Web.PleromaAPI.TwoFactorAuthenticationControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
- alias Pleroma.MFA.Settings
- alias Pleroma.MFA.TOTP
-
- describe "GET /api/pleroma/accounts/mfa/settings" do
- test "returns user mfa settings for new user", %{conn: conn} do
- token = insert(:oauth_token, scopes: ["read", "follow"])
- token2 = insert(:oauth_token, scopes: ["write"])
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> get("/api/pleroma/accounts/mfa")
- |> json_response(:ok) == %{
- "settings" => %{"enabled" => false, "totp" => false}
- }
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token2.token}")
- |> get("/api/pleroma/accounts/mfa")
- |> json_response(403) == %{
- "error" => "Insufficient permissions: read:security."
- }
- end
-
- test "returns user mfa settings with enabled totp", %{conn: conn} do
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{
- enabled: true,
- totp: %Settings.TOTP{secret: "XXX", delivery_type: "app", confirmed: true}
- }
- )
-
- token = insert(:oauth_token, scopes: ["read", "follow"], user: user)
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> get("/api/pleroma/accounts/mfa")
- |> json_response(:ok) == %{
- "settings" => %{"enabled" => true, "totp" => true}
- }
- end
- end
-
- describe "GET /api/pleroma/accounts/mfa/backup_codes" do
- test "returns backup codes", %{conn: conn} do
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{
- backup_codes: ["1", "2", "3"],
- totp: %Settings.TOTP{secret: "secret"}
- }
- )
-
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
- token2 = insert(:oauth_token, scopes: ["read"])
-
- response =
- conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> get("/api/pleroma/accounts/mfa/backup_codes")
- |> json_response(:ok)
-
- assert [<<_::bytes-size(6)>>, <<_::bytes-size(6)>>] = response["codes"]
- user = refresh_record(user)
- mfa_settings = user.multi_factor_authentication_settings
- assert mfa_settings.totp.secret == "secret"
- refute mfa_settings.backup_codes == ["1", "2", "3"]
- refute mfa_settings.backup_codes == []
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token2.token}")
- |> get("/api/pleroma/accounts/mfa/backup_codes")
- |> json_response(403) == %{
- "error" => "Insufficient permissions: write:security."
- }
- end
- end
-
- describe "GET /api/pleroma/accounts/mfa/setup/totp" do
- test "return errors when method is invalid", %{conn: conn} do
- user = insert(:user)
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
-
- response =
- conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> get("/api/pleroma/accounts/mfa/setup/torf")
- |> json_response(400)
-
- assert response == %{"error" => "undefined method"}
- end
-
- test "returns key and provisioning_uri", %{conn: conn} do
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{backup_codes: ["1", "2", "3"]}
- )
-
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
- token2 = insert(:oauth_token, scopes: ["read"])
-
- response =
- conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> get("/api/pleroma/accounts/mfa/setup/totp")
- |> json_response(:ok)
-
- user = refresh_record(user)
- mfa_settings = user.multi_factor_authentication_settings
- secret = mfa_settings.totp.secret
- refute mfa_settings.enabled
- assert mfa_settings.backup_codes == ["1", "2", "3"]
-
- assert response == %{
- "key" => secret,
- "provisioning_uri" => TOTP.provisioning_uri(secret, "#{user.email}")
- }
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token2.token}")
- |> get("/api/pleroma/accounts/mfa/setup/totp")
- |> json_response(403) == %{
- "error" => "Insufficient permissions: write:security."
- }
- end
- end
-
- describe "GET /api/pleroma/accounts/mfa/confirm/totp" do
- test "returns success result", %{conn: conn} do
- secret = TOTP.generate_secret()
- code = TOTP.generate_token(secret)
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{
- backup_codes: ["1", "2", "3"],
- totp: %Settings.TOTP{secret: secret}
- }
- )
-
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
- token2 = insert(:oauth_token, scopes: ["read"])
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: code})
- |> json_response(:ok)
-
- settings = refresh_record(user).multi_factor_authentication_settings
- assert settings.enabled
- assert settings.totp.secret == secret
- assert settings.totp.confirmed
- assert settings.backup_codes == ["1", "2", "3"]
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token2.token}")
- |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: code})
- |> json_response(403) == %{
- "error" => "Insufficient permissions: write:security."
- }
- end
-
- test "returns error if password incorrect", %{conn: conn} do
- secret = TOTP.generate_secret()
- code = TOTP.generate_token(secret)
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{
- backup_codes: ["1", "2", "3"],
- totp: %Settings.TOTP{secret: secret}
- }
- )
-
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
-
- response =
- conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "xxx", code: code})
- |> json_response(422)
-
- settings = refresh_record(user).multi_factor_authentication_settings
- refute settings.enabled
- refute settings.totp.confirmed
- assert settings.backup_codes == ["1", "2", "3"]
- assert response == %{"error" => "Invalid password."}
- end
-
- test "returns error if code incorrect", %{conn: conn} do
- secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{
- backup_codes: ["1", "2", "3"],
- totp: %Settings.TOTP{secret: secret}
- }
- )
-
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
- token2 = insert(:oauth_token, scopes: ["read"])
-
- response =
- conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: "code"})
- |> json_response(422)
-
- settings = refresh_record(user).multi_factor_authentication_settings
- refute settings.enabled
- refute settings.totp.confirmed
- assert settings.backup_codes == ["1", "2", "3"]
- assert response == %{"error" => "invalid_token"}
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token2.token}")
- |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: "code"})
- |> json_response(403) == %{
- "error" => "Insufficient permissions: write:security."
- }
- end
- end
-
- describe "DELETE /api/pleroma/accounts/mfa/totp" do
- test "returns success result", %{conn: conn} do
- user =
- insert(:user,
- multi_factor_authentication_settings: %Settings{
- backup_codes: ["1", "2", "3"],
- totp: %Settings.TOTP{secret: "secret"}
- }
- )
-
- token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
- token2 = insert(:oauth_token, scopes: ["read"])
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> delete("/api/pleroma/accounts/mfa/totp", %{password: "test"})
- |> json_response(:ok)
-
- settings = refresh_record(user).multi_factor_authentication_settings
- refute settings.enabled
- assert settings.totp.secret == nil
- refute settings.totp.confirmed
-
- assert conn
- |> put_req_header("authorization", "Bearer #{token2.token}")
- |> delete("/api/pleroma/accounts/mfa/totp", %{password: "test"})
- |> json_response(403) == %{
- "error" => "Insufficient permissions: write:security."
- }
- end
- end
-end
diff --git a/test/web/pleroma_api/views/chat/message_reference_view_test.exs b/test/web/pleroma_api/views/chat/message_reference_view_test.exs
deleted file mode 100644
index 40dbae3cd..000000000
--- a/test/web/pleroma_api/views/chat/message_reference_view_test.exs
+++ /dev/null
@@ -1,72 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
-
- import Pleroma.Factory
-
- test "it displays a chat message" do
- user = insert(:user)
- recipient = 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)
- {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "kippis :firefox:")
-
- chat = Chat.get(user.id, recipient.ap_id)
-
- object = Object.normalize(activity)
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
-
- assert chat_message[:id] == cm_ref.id
- assert chat_message[:content] == "kippis :firefox:"
- assert chat_message[:account_id] == user.id
- assert chat_message[:chat_id]
- assert chat_message[:created_at]
- assert chat_message[:unread] == false
- assert match?([%{shortcode: "firefox"}], chat_message[:emojis])
-
- clear_config([:rich_media, :enabled], true)
-
- Tesla.Mock.mock(fn
- %{url: "https://example.com/ogp"} ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
- end)
-
- {:ok, activity} =
- CommonAPI.post_chat_message(recipient, user, "gkgkgk https://example.com/ogp",
- media_id: upload.id
- )
-
- object = Object.normalize(activity)
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
-
- assert chat_message_two[:id] == cm_ref.id
- assert chat_message_two[:content] == object.data["content"]
- assert chat_message_two[:account_id] == recipient.id
- assert chat_message_two[:chat_id] == chat_message[:chat_id]
- assert chat_message_two[:attachment]
- assert chat_message_two[:unread] == true
- assert chat_message_two[:card]
- end
-end
diff --git a/test/web/pleroma_api/views/chat_view_test.exs b/test/web/pleroma_api/views/chat_view_test.exs
deleted file mode 100644
index 02484b705..000000000
--- a/test/web/pleroma_api/views/chat_view_test.exs
+++ /dev/null
@@ -1,49 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Object
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.CommonAPI.Utils
- alias Pleroma.Web.MastodonAPI.AccountView
- alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
- alias Pleroma.Web.PleromaAPI.ChatView
-
- import Pleroma.Factory
-
- test "it represents a chat" do
- user = insert(:user)
- recipient = insert(:user)
-
- {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
-
- represented_chat = ChatView.render("show.json", chat: chat)
-
- assert represented_chat == %{
- id: "#{chat.id}",
- account:
- AccountView.render("show.json", user: recipient, skip_visibility_check: true),
- unread: 0,
- last_message: nil,
- updated_at: Utils.to_masto_date(chat.updated_at)
- }
-
- {:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello")
-
- chat_message = Object.normalize(chat_message_creation, false)
-
- {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
-
- represented_chat = ChatView.render("show.json", chat: chat)
-
- cm_ref = MessageReference.for_chat_and_object(chat, chat_message)
-
- assert represented_chat[:last_message] ==
- MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
- end
-end
diff --git a/test/web/pleroma_api/views/scrobble_view_test.exs b/test/web/pleroma_api/views/scrobble_view_test.exs
deleted file mode 100644
index 6bdb56509..000000000
--- a/test/web/pleroma_api/views/scrobble_view_test.exs
+++ /dev/null
@@ -1,20 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.StatusViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.PleromaAPI.ScrobbleView
-
- import Pleroma.Factory
-
- test "successfully renders a Listen activity (pleroma extension)" do
- listen_activity = insert(:listen)
-
- status = ScrobbleView.render("show.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/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs
deleted file mode 100644
index 2f8aadadc..000000000
--- a/test/web/plugs/federating_plug_test.exs
+++ /dev/null
@@ -1,31 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.FederatingPlugTest do
- use Pleroma.Web.ConnCase
-
- setup do: clear_config([:instance, :federating])
-
- test "returns and halt the conn when federating is disabled" do
- Pleroma.Config.put([:instance, :federating], false)
-
- conn =
- build_conn()
- |> Pleroma.Web.FederatingPlug.call(%{})
-
- assert conn.status == 404
- assert conn.halted
- end
-
- test "does nothing when federating is enabled" do
- Pleroma.Config.put([:instance, :federating], true)
-
- conn =
- build_conn()
- |> Pleroma.Web.FederatingPlug.call(%{})
-
- refute conn.status
- refute conn.halted
- end
-end
diff --git a/test/web/plugs/plug_test.exs b/test/web/plugs/plug_test.exs
deleted file mode 100644
index 943e484e7..000000000
--- a/test/web/plugs/plug_test.exs
+++ /dev/null
@@ -1,91 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PlugTest do
- @moduledoc "Tests for the functionality added via `use Pleroma.Web, :plug`"
-
- alias Pleroma.Plugs.ExpectAuthenticatedCheckPlug
- alias Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug
- alias Pleroma.Plugs.PlugHelper
-
- import Mock
-
- use Pleroma.Web.ConnCase
-
- describe "when plug is skipped, " do
- setup_with_mocks(
- [
- {ExpectPublicOrAuthenticatedCheckPlug, [:passthrough], []}
- ],
- %{conn: conn}
- ) do
- conn = ExpectPublicOrAuthenticatedCheckPlug.skip_plug(conn)
- %{conn: conn}
- end
-
- test "it neither adds plug to called plugs list nor calls `perform/2`, " <>
- "regardless of :if_func / :unless_func options",
- %{conn: conn} do
- for opts <- [%{}, %{if_func: fn _ -> true end}, %{unless_func: fn _ -> false end}] do
- ret_conn = ExpectPublicOrAuthenticatedCheckPlug.call(conn, opts)
-
- refute called(ExpectPublicOrAuthenticatedCheckPlug.perform(:_, :_))
- refute PlugHelper.plug_called?(ret_conn, ExpectPublicOrAuthenticatedCheckPlug)
- end
- end
- end
-
- describe "when plug is NOT skipped, " do
- setup_with_mocks([{ExpectAuthenticatedCheckPlug, [:passthrough], []}]) do
- :ok
- end
-
- test "with no pre-run checks, adds plug to called plugs list and calls `perform/2`", %{
- conn: conn
- } do
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{})
-
- assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
- assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
- end
-
- test "when :if_func option is given, calls the plug only if provided function evals tru-ish",
- %{conn: conn} do
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{if_func: fn _ -> false end})
-
- refute called(ExpectAuthenticatedCheckPlug.perform(:_, :_))
- refute PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
-
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{if_func: fn _ -> true end})
-
- assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
- assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
- end
-
- test "if :unless_func option is given, calls the plug only if provided function evals falsy",
- %{conn: conn} do
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{unless_func: fn _ -> true end})
-
- refute called(ExpectAuthenticatedCheckPlug.perform(:_, :_))
- refute PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
-
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{unless_func: fn _ -> false end})
-
- assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
- assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
- end
-
- test "allows a plug to be called multiple times (even if it's in called plugs list)", %{
- conn: conn
- } do
- conn = ExpectAuthenticatedCheckPlug.call(conn, %{an_option: :value1})
- assert called(ExpectAuthenticatedCheckPlug.perform(conn, %{an_option: :value1}))
-
- assert PlugHelper.plug_called?(conn, ExpectAuthenticatedCheckPlug)
-
- conn = ExpectAuthenticatedCheckPlug.call(conn, %{an_option: :value2})
- assert called(ExpectAuthenticatedCheckPlug.perform(conn, %{an_option: :value2}))
- end
- end
-end
diff --git a/test/web/preload/instance_test.exs b/test/web/preload/instance_test.exs
deleted file mode 100644
index a46f28312..000000000
--- a/test/web/preload/instance_test.exs
+++ /dev/null
@@ -1,48 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Preload.Providers.InstanceTest do
- use Pleroma.DataCase
- alias Pleroma.Web.Preload.Providers.Instance
-
- setup do: {:ok, Instance.generate_terms(nil)}
-
- test "it renders the info", %{"/api/v1/instance" => info} do
- assert %{
- description: description,
- email: "admin@example.com",
- registrations: true
- } = info
-
- assert String.equivalent?(description, "Pleroma: An efficient and flexible fediverse server")
- end
-
- test "it renders the panel", %{"/instance/panel.html" => panel} do
- assert String.contains?(
- panel,
- "<p>Welcome to <a href=\"https://pleroma.social\" target=\"_blank\">Pleroma!</a></p>"
- )
- end
-
- test "it works with overrides" do
- clear_config([:instance, :static_dir], "test/fixtures/preload_static")
-
- %{"/instance/panel.html" => panel} = Instance.generate_terms(nil)
-
- assert String.contains?(
- panel,
- "HEY!"
- )
- end
-
- test "it renders the node_info", %{"/nodeinfo/2.0.json" => nodeinfo} do
- %{
- metadata: metadata,
- version: "2.0"
- } = nodeinfo
-
- assert metadata.private == false
- assert metadata.suggestions == %{enabled: false}
- end
-end
diff --git a/test/web/preload/timeline_test.exs b/test/web/preload/timeline_test.exs
deleted file mode 100644
index 3b1f2f1aa..000000000
--- a/test/web/preload/timeline_test.exs
+++ /dev/null
@@ -1,56 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Preload.Providers.TimelineTest do
- use Pleroma.DataCase
- import Pleroma.Factory
-
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.Preload.Providers.Timelines
-
- @public_url "/api/v1/timelines/public"
-
- describe "unauthenticated timeliness when restricted" do
- setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true)
- setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true)
-
- test "return nothing" do
- tl_data = Timelines.generate_terms(%{})
-
- refute Map.has_key?(tl_data, "/api/v1/timelines/public")
- end
- end
-
- describe "unauthenticated timeliness when unrestricted" do
- setup do: clear_config([:restrict_unauthenticated, :timelines, :local], false)
- setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], false)
-
- setup do: {:ok, user: insert(:user)}
-
- test "returns the timeline when not restricted" do
- assert Timelines.generate_terms(%{})
- |> Map.has_key?(@public_url)
- end
-
- test "returns public items", %{user: user} do
- {:ok, _} = CommonAPI.post(user, %{status: "it's post 1!"})
- {:ok, _} = CommonAPI.post(user, %{status: "it's post 2!"})
- {:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
-
- assert Timelines.generate_terms(%{})
- |> Map.fetch!(@public_url)
- |> Enum.count() == 3
- end
-
- test "does not return non-public items", %{user: user} do
- {:ok, _} = CommonAPI.post(user, %{status: "it's post 1!", visibility: "unlisted"})
- {:ok, _} = CommonAPI.post(user, %{status: "it's post 2!", visibility: "direct"})
- {:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
-
- assert Timelines.generate_terms(%{})
- |> Map.fetch!(@public_url)
- |> Enum.count() == 1
- end
- end
-end
diff --git a/test/web/preload/user_test.exs b/test/web/preload/user_test.exs
deleted file mode 100644
index 83f065e27..000000000
--- a/test/web/preload/user_test.exs
+++ /dev/null
@@ -1,33 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Preload.Providers.UserTest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Web.Preload.Providers.User
-
- describe "returns empty when user doesn't exist" do
- test "nil user specified" do
- assert User.generate_terms(%{user: nil}) == %{}
- end
-
- test "missing user specified" do
- assert User.generate_terms(%{user: :not_a_user}) == %{}
- end
- end
-
- describe "specified user exists" do
- setup do
- user = insert(:user)
-
- terms = User.generate_terms(%{user: user})
- %{terms: terms, user: user}
- end
-
- test "account is rendered", %{terms: terms, user: user} do
- account = terms["/api/v1/accounts/#{user.id}"]
- assert %{acct: user, username: user} = account
- end
- end
-end
diff --git a/test/web/push/impl_test.exs b/test/web/push/impl_test.exs
deleted file mode 100644
index aeb5c1fbd..000000000
--- a/test/web/push/impl_test.exs
+++ /dev/null
@@ -1,344 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.Push.ImplTest do
- use Pleroma.DataCase
-
- alias Pleroma.Notification
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.Push.Impl
- alias Pleroma.Web.Push.Subscription
-
- import Pleroma.Factory
-
- setup do
- Tesla.Mock.mock(fn
- %{method: :post, url: "https://example.com/example/1234"} ->
- %Tesla.Env{status: 200}
-
- %{method: :post, url: "https://example.com/example/not_found"} ->
- %Tesla.Env{status: 400}
-
- %{method: :post, url: "https://example.com/example/bad"} ->
- %Tesla.Env{status: 100}
- end)
-
- :ok
- end
-
- @sub %{
- endpoint: "https://example.com/example/1234",
- keys: %{
- auth: "8eDyX_uCN0XRhSbY5hs7Hg==",
- p256dh:
- "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA="
- }
- }
- @api_key "BASgACIHpN1GYgzSRp"
- @message "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
-
- test "performs sending notifications" do
- user = insert(:user)
- user2 = insert(:user)
- insert(:push_subscription, user: user, data: %{alerts: %{"mention" => true}})
- insert(:push_subscription, user: user2, data: %{alerts: %{"mention" => true}})
-
- insert(:push_subscription,
- user: user,
- data: %{alerts: %{"follow" => true, "mention" => true}}
- )
-
- insert(:push_subscription,
- user: user,
- data: %{alerts: %{"follow" => true, "mention" => false}}
- )
-
- {:ok, activity} = CommonAPI.post(user, %{status: "<Lorem ipsum dolor sit amet."})
-
- notif =
- insert(:notification,
- user: user,
- activity: activity,
- type: "mention"
- )
-
- assert Impl.perform(notif) == {:ok, [:ok, :ok]}
- end
-
- @tag capture_log: true
- test "returns error if notif does not match " do
- assert Impl.perform(%{}) == {:error, :unknown_type}
- end
-
- test "successful message sending" do
- assert Impl.push_message(@message, @sub, @api_key, %Subscription{}) == :ok
- end
-
- @tag capture_log: true
- test "fail message sending" do
- assert Impl.push_message(
- @message,
- Map.merge(@sub, %{endpoint: "https://example.com/example/bad"}),
- @api_key,
- %Subscription{}
- ) == :error
- end
-
- test "delete subscription if result send message between 400..500" do
- subscription = insert(:push_subscription)
-
- assert Impl.push_message(
- @message,
- Map.merge(@sub, %{endpoint: "https://example.com/example/not_found"}),
- @api_key,
- subscription
- ) == :ok
-
- refute Pleroma.Repo.get(Subscription, subscription.id)
- end
-
- test "deletes subscription when token has been deleted" do
- subscription = insert(:push_subscription)
-
- Pleroma.Repo.delete(subscription.token)
-
- refute Pleroma.Repo.get(Subscription, subscription.id)
- end
-
- test "renders title and body for create activity" do
- user = insert(:user, nickname: "Bob")
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status:
- "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
- })
-
- object = Object.normalize(activity)
-
- assert Impl.format_body(
- %{
- activity: activity
- },
- user,
- object
- ) ==
- "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
-
- assert Impl.format_title(%{activity: activity, type: "mention"}) ==
- "New Mention"
- end
-
- test "renders title and body for follow activity" do
- user = insert(:user, nickname: "Bob")
- other_user = insert(:user)
- {:ok, _, _, activity} = CommonAPI.follow(user, other_user)
- object = Object.normalize(activity, false)
-
- assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
- "@Bob has followed you"
-
- assert Impl.format_title(%{activity: activity, type: "follow"}) ==
- "New Follower"
- end
-
- test "renders title and body for announce activity" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status:
- "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
- })
-
- {:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
- object = Object.normalize(activity)
-
- assert Impl.format_body(%{activity: announce_activity}, user, object) ==
- "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
-
- assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) ==
- "New Repeat"
- end
-
- test "renders title and body for like activity" do
- user = insert(:user, nickname: "Bob")
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status:
- "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
- })
-
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
- object = Object.normalize(activity)
-
- assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
- "@Bob has favorited your post"
-
- assert Impl.format_title(%{activity: activity, type: "favourite"}) ==
- "New Favorite"
- end
-
- test "renders title for create activity with direct visibility" do
- user = insert(:user, nickname: "Bob")
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- visibility: "direct",
- status: "This is just between you and me, pal"
- })
-
- assert Impl.format_title(%{activity: activity}) ==
- "New Direct Message"
- end
-
- describe "build_content/3" do
- test "builds content for chat messages" do
- user = insert(:user)
- recipient = insert(:user)
-
- {:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey")
- object = Object.normalize(chat, false)
- [notification] = Notification.for_user(recipient)
-
- res = Impl.build_content(notification, user, object)
-
- assert res == %{
- body: "@#{user.nickname}: hey",
- title: "New Chat Message"
- }
- end
-
- test "builds content for chat messages with no content" do
- user = insert(:user)
- recipient = 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)
-
- {:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id)
- object = Object.normalize(chat, false)
- [notification] = Notification.for_user(recipient)
-
- res = Impl.build_content(notification, user, object)
-
- assert res == %{
- body: "@#{user.nickname}: (Attachment)",
- title: "New Chat Message"
- }
- end
-
- test "hides contents of notifications when option enabled" do
- user = insert(:user, nickname: "Bob")
-
- user2 =
- insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: true})
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- visibility: "direct",
- status: "<Lorem ipsum dolor sit amet."
- })
-
- notif = insert(:notification, user: user2, activity: activity)
-
- actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
- object = Object.normalize(activity)
-
- assert Impl.build_content(notif, actor, object) == %{
- body: "New Direct Message"
- }
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- visibility: "public",
- status: "<Lorem ipsum dolor sit amet."
- })
-
- notif = insert(:notification, user: user2, activity: activity, type: "mention")
-
- actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
- object = Object.normalize(activity)
-
- assert Impl.build_content(notif, actor, object) == %{
- body: "New Mention"
- }
-
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
-
- notif = insert(:notification, user: user2, activity: activity, type: "favourite")
-
- actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
- object = Object.normalize(activity)
-
- assert Impl.build_content(notif, actor, object) == %{
- body: "New Favorite"
- }
- end
-
- test "returns regular content when hiding contents option disabled" do
- user = insert(:user, nickname: "Bob")
-
- user2 =
- insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: false})
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- visibility: "direct",
- status:
- "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
- })
-
- notif = insert(:notification, user: user2, activity: activity)
-
- actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
- object = Object.normalize(activity)
-
- assert Impl.build_content(notif, actor, object) == %{
- body:
- "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...",
- title: "New Direct Message"
- }
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- visibility: "public",
- status:
- "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
- })
-
- notif = insert(:notification, user: user2, activity: activity, type: "mention")
-
- actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
- object = Object.normalize(activity)
-
- assert Impl.build_content(notif, actor, object) == %{
- body:
- "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...",
- title: "New Mention"
- }
-
- {:ok, activity} = CommonAPI.favorite(user, activity.id)
-
- notif = insert(:notification, user: user2, activity: activity, type: "favourite")
-
- actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
- object = Object.normalize(activity)
-
- assert Impl.build_content(notif, actor, object) == %{
- body: "@Bob has favorited your post",
- title: "New Favorite"
- }
- end
- end
-end
diff --git a/test/web/rel_me_test.exs b/test/web/rel_me_test.exs
deleted file mode 100644
index 65255916d..000000000
--- a/test/web/rel_me_test.exs
+++ /dev/null
@@ -1,48 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.RelMeTest do
- use ExUnit.Case
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "parse/1" do
- hrefs = ["https://social.example.org/users/lain"]
-
- assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/null") == {:ok, []}
-
- assert {:ok, %Tesla.Env{status: 404}} =
- Pleroma.Web.RelMe.parse("http://example.com/rel_me/error")
-
- assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/link") == {:ok, hrefs}
- assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/anchor") == {:ok, hrefs}
- assert Pleroma.Web.RelMe.parse("http://example.com/rel_me/anchor_nofollow") == {:ok, hrefs}
- end
-
- test "maybe_put_rel_me/2" do
- profile_urls = ["https://social.example.org/users/lain"]
- attr = "me"
- fallback = nil
-
- assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/null", profile_urls) ==
- fallback
-
- assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/error", profile_urls) ==
- fallback
-
- assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/anchor", profile_urls) ==
- attr
-
- assert Pleroma.Web.RelMe.maybe_put_rel_me(
- "http://example.com/rel_me/anchor_nofollow",
- profile_urls
- ) == attr
-
- assert Pleroma.Web.RelMe.maybe_put_rel_me("http://example.com/rel_me/link", profile_urls) ==
- attr
- end
-end
diff --git a/test/web/rich_media/aws_signed_url_test.exs b/test/web/rich_media/aws_signed_url_test.exs
deleted file mode 100644
index 1ceae1a31..000000000
--- a/test/web/rich_media/aws_signed_url_test.exs
+++ /dev/null
@@ -1,82 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.RichMedia.TTL.AwsSignedUrlTest do
- use ExUnit.Case, async: true
-
- test "s3 signed url is parsed correct for expiration time" do
- url = "https://pleroma.social/amz"
-
- {:ok, timestamp} =
- Timex.now()
- |> DateTime.truncate(:second)
- |> Timex.format("{ISO:Basic:Z}")
-
- # in seconds
- valid_till = 30
-
- metadata = construct_metadata(timestamp, valid_till, url)
-
- expire_time =
- Timex.parse!(timestamp, "{ISO:Basic:Z}") |> Timex.to_unix() |> Kernel.+(valid_till)
-
- assert {:ok, expire_time} == Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl.ttl(metadata, url)
- end
-
- test "s3 signed url is parsed and correct ttl is set for rich media" do
- url = "https://pleroma.social/amz"
-
- {:ok, timestamp} =
- Timex.now()
- |> DateTime.truncate(:second)
- |> Timex.format("{ISO:Basic:Z}")
-
- # in seconds
- valid_till = 30
-
- metadata = construct_metadata(timestamp, valid_till, url)
-
- body = """
- <meta name="twitter:card" content="Pleroma" />
- <meta name="twitter:site" content="Pleroma" />
- <meta name="twitter:title" content="Pleroma" />
- <meta name="twitter:description" content="Pleroma" />
- <meta name="twitter:image" content="#{Map.get(metadata, :image)}" />
- """
-
- Tesla.Mock.mock(fn
- %{
- method: :get,
- url: "https://pleroma.social/amz"
- } ->
- %Tesla.Env{status: 200, body: body}
- end)
-
- Cachex.put(:rich_media_cache, url, metadata)
-
- Pleroma.Web.RichMedia.Parser.set_ttl_based_on_image(metadata, url)
-
- {:ok, cache_ttl} = Cachex.ttl(:rich_media_cache, url)
-
- # as there is delay in setting and pulling the data from cache we ignore 1 second
- # make it 2 seconds for flakyness
- assert_in_delta(valid_till * 1000, cache_ttl, 2000)
- end
-
- defp construct_s3_url(timestamp, valid_till) do
- "https://pleroma.s3.ap-southeast-1.amazonaws.com/sachin%20%281%29%20_a%20-%25%2Aasdasd%20BNN%20bnnn%20.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIBLWWK6RGDQXDLJQ%2F20190716%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=#{
- timestamp
- }&X-Amz-Expires=#{valid_till}&X-Amz-Signature=04ffd6b98634f4b1bbabc62e0fac4879093cd54a6eed24fe8eb38e8369526bbf&X-Amz-SignedHeaders=host"
- end
-
- defp construct_metadata(timestamp, valid_till, url) do
- %{
- image: construct_s3_url(timestamp, valid_till),
- site: "Pleroma",
- title: "Pleroma",
- description: "Pleroma",
- url: url
- }
- end
-end
diff --git a/test/web/rich_media/helpers_test.exs b/test/web/rich_media/helpers_test.exs
deleted file mode 100644
index 8264a9c41..000000000
--- a/test/web/rich_media/helpers_test.exs
+++ /dev/null
@@ -1,121 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.RichMedia.HelpersTest do
- use Pleroma.DataCase
-
- alias Pleroma.Config
- alias Pleroma.Object
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.RichMedia.Helpers
-
- import Pleroma.Factory
- import Tesla.Mock
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
-
- :ok
- end
-
- setup do: clear_config([:rich_media, :enabled])
-
- test "refuses to crawl incomplete URLs" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "[test](example.com/ogp)",
- content_type: "text/markdown"
- })
-
- Config.put([:rich_media, :enabled], true)
-
- assert %{} == Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
- end
-
- test "refuses to crawl malformed URLs" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "[test](example.com[]/ogp)",
- content_type: "text/markdown"
- })
-
- Config.put([:rich_media, :enabled], true)
-
- assert %{} == Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
- end
-
- test "crawls valid, complete URLs" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "[test](https://example.com/ogp)",
- content_type: "text/markdown"
- })
-
- Config.put([:rich_media, :enabled], true)
-
- assert %{page_url: "https://example.com/ogp", rich_media: _} =
- Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
- end
-
- test "refuses to crawl URLs from posts marked sensitive" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "http://example.com/ogp",
- sensitive: true
- })
-
- %Object{} = object = Object.normalize(activity)
-
- assert object.data["sensitive"]
-
- Config.put([:rich_media, :enabled], true)
-
- assert %{} = Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
- end
-
- test "refuses to crawl URLs from posts tagged NSFW" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "http://example.com/ogp #nsfw"
- })
-
- %Object{} = object = Object.normalize(activity)
-
- assert object.data["sensitive"]
-
- Config.put([:rich_media, :enabled], true)
-
- assert %{} = Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
- end
-
- test "refuses to crawl URLs of private network from posts" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{status: "http://127.0.0.1:4000/notice/9kCP7VNyPJXFOXDrgO"})
-
- {:ok, activity2} = CommonAPI.post(user, %{status: "https://10.111.10.1/notice/9kCP7V"})
- {:ok, activity3} = CommonAPI.post(user, %{status: "https://172.16.32.40/notice/9kCP7V"})
- {:ok, activity4} = CommonAPI.post(user, %{status: "https://192.168.10.40/notice/9kCP7V"})
- {:ok, activity5} = CommonAPI.post(user, %{status: "https://pleroma.local/notice/9kCP7V"})
-
- Config.put([:rich_media, :enabled], true)
-
- assert %{} = Helpers.fetch_data_for_activity(activity)
- assert %{} = Helpers.fetch_data_for_activity(activity2)
- assert %{} = Helpers.fetch_data_for_activity(activity3)
- assert %{} = Helpers.fetch_data_for_activity(activity4)
- assert %{} = Helpers.fetch_data_for_activity(activity5)
- end
-end
diff --git a/test/web/rich_media/parser_test.exs b/test/web/rich_media/parser_test.exs
deleted file mode 100644
index b8ef2cccf..000000000
--- a/test/web/rich_media/parser_test.exs
+++ /dev/null
@@ -1,178 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.RichMedia.ParserTest do
- use ExUnit.Case, async: true
-
- alias Pleroma.Web.RichMedia.Parser
-
- setup do
- Tesla.Mock.mock(fn
- %{
- method: :get,
- url: "http://example.com/ogp"
- } ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
-
- %{
- method: :get,
- url: "http://example.com/non-ogp"
- } ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/non_ogp_embed.html")}
-
- %{
- method: :get,
- url: "http://example.com/ogp-missing-title"
- } ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/fixtures/rich_media/ogp-missing-title.html")
- }
-
- %{
- method: :get,
- url: "http://example.com/twitter-card"
- } ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}
-
- %{
- method: :get,
- url: "http://example.com/oembed"
- } ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.html")}
-
- %{
- method: :get,
- url: "http://example.com/oembed.json"
- } ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.json")}
-
- %{method: :get, url: "http://example.com/empty"} ->
- %Tesla.Env{status: 200, body: "hello"}
-
- %{method: :get, url: "http://example.com/malformed"} ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/malformed-data.html")}
-
- %{method: :get, url: "http://example.com/error"} ->
- {:error, :overload}
-
- %{
- method: :head,
- url: "http://example.com/huge-page"
- } ->
- %Tesla.Env{
- status: 200,
- headers: [{"content-length", "2000001"}, {"content-type", "text/html"}]
- }
-
- %{
- method: :head,
- url: "http://example.com/pdf-file"
- } ->
- %Tesla.Env{
- status: 200,
- headers: [{"content-length", "1000000"}, {"content-type", "application/pdf"}]
- }
-
- %{method: :head} ->
- %Tesla.Env{status: 404, body: "", headers: []}
- end)
-
- :ok
- end
-
- test "returns error when no metadata present" do
- assert {:error, _} = Parser.parse("http://example.com/empty")
- end
-
- test "doesn't just add a title" do
- assert Parser.parse("http://example.com/non-ogp") ==
- {:error,
- "Found metadata was invalid or incomplete: %{\"url\" => \"http://example.com/non-ogp\"}"}
- end
-
- test "parses ogp" do
- assert Parser.parse("http://example.com/ogp") ==
- {:ok,
- %{
- "image" => "http://ia.media-imdb.com/images/rock.jpg",
- "title" => "The Rock",
- "description" =>
- "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
- "type" => "video.movie",
- "url" => "http://example.com/ogp"
- }}
- end
-
- test "falls back to <title> when ogp:title is missing" do
- assert Parser.parse("http://example.com/ogp-missing-title") ==
- {:ok,
- %{
- "image" => "http://ia.media-imdb.com/images/rock.jpg",
- "title" => "The Rock (1996)",
- "description" =>
- "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
- "type" => "video.movie",
- "url" => "http://example.com/ogp-missing-title"
- }}
- end
-
- test "parses twitter card" do
- assert Parser.parse("http://example.com/twitter-card") ==
- {:ok,
- %{
- "card" => "summary",
- "site" => "@flickr",
- "image" => "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
- "title" => "Small Island Developing States Photo Submission",
- "description" => "View the album on Flickr.",
- "url" => "http://example.com/twitter-card"
- }}
- end
-
- test "parses OEmbed" do
- assert Parser.parse("http://example.com/oembed") ==
- {:ok,
- %{
- "author_name" => "‮‭‬bees‬",
- "author_url" => "https://www.flickr.com/photos/bees/",
- "cache_age" => 3600,
- "flickr_type" => "photo",
- "height" => "768",
- "html" =>
- "<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by ‮‭‬bees‬, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>",
- "license" => "All Rights Reserved",
- "license_id" => 0,
- "provider_name" => "Flickr",
- "provider_url" => "https://www.flickr.com/",
- "thumbnail_height" => 150,
- "thumbnail_url" =>
- "https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_q.jpg",
- "thumbnail_width" => 150,
- "title" => "Bacon Lollys",
- "type" => "photo",
- "url" => "http://example.com/oembed",
- "version" => "1.0",
- "web_page" => "https://www.flickr.com/photos/bees/2362225867/",
- "web_page_short_url" => "https://flic.kr/p/4AK2sc",
- "width" => "1024"
- }}
- end
-
- test "rejects invalid OGP data" do
- assert {:error, _} = Parser.parse("http://example.com/malformed")
- end
-
- test "returns error if getting page was not successful" do
- assert {:error, :overload} = Parser.parse("http://example.com/error")
- end
-
- test "does a HEAD request to check if the body is too large" do
- assert {:error, :body_too_large} = Parser.parse("http://example.com/huge-page")
- end
-
- test "does a HEAD request to check if the body is html" do
- assert {:error, {:content_type, _}} = Parser.parse("http://example.com/pdf-file")
- end
-end
diff --git a/test/web/rich_media/parsers/twitter_card_test.exs b/test/web/rich_media/parsers/twitter_card_test.exs
deleted file mode 100644
index 219f005a2..000000000
--- a/test/web/rich_media/parsers/twitter_card_test.exs
+++ /dev/null
@@ -1,127 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
- use ExUnit.Case, async: true
- alias Pleroma.Web.RichMedia.Parsers.TwitterCard
-
- test "returns error when html not contains twitter card" do
- assert TwitterCard.parse([{"html", [], [{"head", [], []}, {"body", [], []}]}], %{}) == %{}
- end
-
- test "parses twitter card with only name attributes" do
- html =
- File.read!("test/fixtures/nypd-facial-recognition-children-teenagers3.html")
- |> Floki.parse_document!()
-
- assert TwitterCard.parse(html, %{}) ==
- %{
- "app:id:googleplay" => "com.nytimes.android",
- "app:name:googleplay" => "NYTimes",
- "app:url:googleplay" => "nytimes://reader/id/100000006583622",
- "site" => nil,
- "description" =>
- "With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
- "image" =>
- "https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-facebookJumbo.jpg",
- "type" => "article",
- "url" =>
- "https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
- "title" =>
- "She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database."
- }
- end
-
- test "parses twitter card with only property attributes" do
- html =
- File.read!("test/fixtures/nypd-facial-recognition-children-teenagers2.html")
- |> Floki.parse_document!()
-
- assert TwitterCard.parse(html, %{}) ==
- %{
- "card" => "summary_large_image",
- "description" =>
- "With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
- "image" =>
- "https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
- "image:alt" => "",
- "title" =>
- "She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
- "url" =>
- "https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
- "type" => "article"
- }
- end
-
- test "parses twitter card with name & property attributes" do
- html =
- File.read!("test/fixtures/nypd-facial-recognition-children-teenagers.html")
- |> Floki.parse_document!()
-
- assert TwitterCard.parse(html, %{}) ==
- %{
- "app:id:googleplay" => "com.nytimes.android",
- "app:name:googleplay" => "NYTimes",
- "app:url:googleplay" => "nytimes://reader/id/100000006583622",
- "card" => "summary_large_image",
- "description" =>
- "With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
- "image" =>
- "https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
- "image:alt" => "",
- "site" => nil,
- "title" =>
- "She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
- "url" =>
- "https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
- "type" => "article"
- }
- end
-
- test "respect only first title tag on the page" do
- image_path =
- "https://assets.atlasobscura.com/media/W1siZiIsInVwbG9hZHMvYXNzZXRzLzkwYzgyMzI4LThlMDUtNGRiNS05MDg3LTUzMGUxZTM5N2RmMmVkOTM5ZDM4MGM4OTIx" <>
- "YTQ5MF9EQVIgZXhodW1hdGlvbiBvZiBNYXJnYXJldCBDb3JiaW4gZ3JhdmUgMTkyNi5qcGciXSxbInAiLCJjb252ZXJ0IiwiIl0sWyJwIiwiY29udmVydCIsIi1xdWFsaXR5IDgxIC1hdXRvLW9" <>
- "yaWVudCJdLFsicCIsInRodW1iIiwiNjAweD4iXV0/DAR%20exhumation%20of%20Margaret%20Corbin%20grave%201926.jpg"
-
- html =
- File.read!("test/fixtures/margaret-corbin-grave-west-point.html") |> Floki.parse_document!()
-
- assert TwitterCard.parse(html, %{}) ==
- %{
- "site" => "@atlasobscura",
- "title" => "The Missing Grave of Margaret Corbin, Revolutionary War Veteran",
- "card" => "summary_large_image",
- "image" => image_path,
- "description" =>
- "She's the only woman veteran honored with a monument at West Point. But where was she buried?",
- "site_name" => "Atlas Obscura",
- "type" => "article",
- "url" => "http://www.atlasobscura.com/articles/margaret-corbin-grave-west-point"
- }
- end
-
- test "takes first founded title in html head if there is html markup error" do
- html =
- File.read!("test/fixtures/nypd-facial-recognition-children-teenagers4.html")
- |> Floki.parse_document!()
-
- assert TwitterCard.parse(html, %{}) ==
- %{
- "site" => nil,
- "title" =>
- "She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
- "app:id:googleplay" => "com.nytimes.android",
- "app:name:googleplay" => "NYTimes",
- "app:url:googleplay" => "nytimes://reader/id/100000006583622",
- "description" =>
- "With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
- "image" =>
- "https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-facebookJumbo.jpg",
- "type" => "article",
- "url" =>
- "https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
- }
- end
-end
diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/web/static_fe/static_fe_controller_test.exs
deleted file mode 100644
index 1598bf675..000000000
--- a/test/web/static_fe/static_fe_controller_test.exs
+++ /dev/null
@@ -1,192 +0,0 @@
-defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Activity
- alias Pleroma.Config
- alias Pleroma.Web.ActivityPub.Transmogrifier
- alias Pleroma.Web.CommonAPI
-
- import Pleroma.Factory
-
- setup_all do: clear_config([:static_fe, :enabled], true)
- setup do: clear_config([:instance, :federating], true)
-
- setup %{conn: conn} do
- conn = put_req_header(conn, "accept", "text/html")
- user = insert(:user)
-
- %{conn: conn, user: user}
- end
-
- describe "user profile html" do
- test "just the profile as HTML", %{conn: conn, user: user} do
- conn = get(conn, "/users/#{user.nickname}")
-
- assert html_response(conn, 200) =~ user.nickname
- end
-
- test "404 when user not found", %{conn: conn} do
- conn = get(conn, "/users/limpopo")
-
- assert html_response(conn, 404) =~ "not found"
- end
-
- test "profile does not include private messages", %{conn: conn, user: user} do
- CommonAPI.post(user, %{status: "public"})
- CommonAPI.post(user, %{status: "private", visibility: "private"})
-
- conn = get(conn, "/users/#{user.nickname}")
-
- html = html_response(conn, 200)
-
- assert html =~ ">public<"
- refute html =~ ">private<"
- end
-
- test "pagination", %{conn: conn, user: user} do
- Enum.map(1..30, fn i -> CommonAPI.post(user, %{status: "test#{i}"}) end)
-
- conn = get(conn, "/users/#{user.nickname}")
-
- html = html_response(conn, 200)
-
- assert html =~ ">test30<"
- assert html =~ ">test11<"
- refute html =~ ">test10<"
- refute html =~ ">test1<"
- end
-
- test "pagination, page 2", %{conn: conn, user: user} do
- activities = Enum.map(1..30, fn i -> CommonAPI.post(user, %{status: "test#{i}"}) end)
- {:ok, a11} = Enum.at(activities, 11)
-
- conn = get(conn, "/users/#{user.nickname}?max_id=#{a11.id}")
-
- html = html_response(conn, 200)
-
- assert html =~ ">test1<"
- assert html =~ ">test10<"
- refute html =~ ">test20<"
- refute html =~ ">test29<"
- end
-
- test "it requires authentication if instance is NOT federating", %{conn: conn, user: user} do
- ensure_federating_or_authenticated(conn, "/users/#{user.nickname}", user)
- end
- end
-
- describe "notice html" do
- test "single notice page", %{conn: conn, user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
-
- conn = get(conn, "/notice/#{activity.id}")
-
- html = html_response(conn, 200)
- assert html =~ "<header>"
- assert html =~ user.nickname
- assert html =~ "testing a thing!"
- end
-
- test "redirects to json if requested", %{conn: conn, user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
-
- conn =
- conn
- |> put_req_header(
- "accept",
- "Accept: application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", text/html"
- )
- |> get("/notice/#{activity.id}")
-
- assert redirected_to(conn, 302) =~ activity.data["object"]
- end
-
- test "filters HTML tags", %{conn: conn} do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "<script>alert('xss')</script>"})
-
- conn =
- conn
- |> put_req_header("accept", "text/html")
- |> get("/notice/#{activity.id}")
-
- html = html_response(conn, 200)
- assert html =~ ~s[&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;]
- end
-
- test "shows the whole thread", %{conn: conn, user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "space: the final frontier"})
-
- CommonAPI.post(user, %{
- status: "these are the voyages or something",
- in_reply_to_status_id: activity.id
- })
-
- conn = get(conn, "/notice/#{activity.id}")
-
- html = html_response(conn, 200)
- assert html =~ "the final frontier"
- assert html =~ "voyages"
- end
-
- test "redirect by AP object ID", %{conn: conn, user: user} do
- {:ok, %Activity{data: %{"object" => object_url}}} =
- CommonAPI.post(user, %{status: "beam me up"})
-
- conn = get(conn, URI.parse(object_url).path)
-
- assert html_response(conn, 302) =~ "redirected"
- end
-
- test "redirect by activity ID", %{conn: conn, user: user} do
- {:ok, %Activity{data: %{"id" => id}}} =
- CommonAPI.post(user, %{status: "I'm a doctor, not a devops!"})
-
- conn = get(conn, URI.parse(id).path)
-
- assert html_response(conn, 302) =~ "redirected"
- end
-
- test "404 when notice not found", %{conn: conn} do
- conn = get(conn, "/notice/88c9c317")
-
- assert html_response(conn, 404) =~ "not found"
- end
-
- test "404 for private status", %{conn: conn, user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "don't show me!", visibility: "private"})
-
- conn = get(conn, "/notice/#{activity.id}")
-
- assert html_response(conn, 404) =~ "not found"
- end
-
- test "302 for remote cached status", %{conn: conn, user: user} do
- message = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => user.follower_address,
- "cc" => "https://www.w3.org/ns/activitystreams#Public",
- "type" => "Create",
- "object" => %{
- "content" => "blah blah blah",
- "type" => "Note",
- "attributedTo" => user.ap_id,
- "inReplyTo" => nil
- },
- "actor" => user.ap_id
- }
-
- assert {:ok, activity} = Transmogrifier.handle_incoming(message)
-
- conn = get(conn, "/notice/#{activity.id}")
-
- assert html_response(conn, 302) =~ "redirected"
- end
-
- test "it requires authentication if instance is NOT federating", %{conn: conn, user: user} do
- {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
-
- ensure_federating_or_authenticated(conn, "/notice/#{activity.id}", user)
- end
- end
-end
diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs
deleted file mode 100644
index d56d74464..000000000
--- a/test/web/streamer/streamer_test.exs
+++ /dev/null
@@ -1,671 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.StreamerTest do
- use Pleroma.DataCase
-
- import Pleroma.Factory
-
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Conversation.Participation
- alias Pleroma.List
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.Streamer
- alias Pleroma.Web.StreamerView
-
- @moduletag needs_streamer: true, capture_log: true
-
- setup do: clear_config([:instance, :skip_thread_containment])
-
- describe "get_topic without an user" do
- test "allows public" do
- assert {:ok, "public"} = Streamer.get_topic("public", nil)
- assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil)
- assert {:ok, "public:media"} = Streamer.get_topic("public:media", nil)
- assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil)
- end
-
- test "allows hashtag streams" do
- assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", nil, %{"tag" => "cofe"})
- end
-
- test "disallows user streams" do
- assert {:error, _} = Streamer.get_topic("user", nil)
- assert {:error, _} = Streamer.get_topic("user:notification", nil)
- assert {:error, _} = Streamer.get_topic("direct", nil)
- end
-
- test "disallows list streams" do
- assert {:error, _} = Streamer.get_topic("list", nil, %{"list" => 42})
- end
- end
-
- describe "get_topic with an user" do
- setup do
- user = insert(:user)
- {:ok, %{user: user}}
- end
-
- test "allows public streams", %{user: user} do
- assert {:ok, "public"} = Streamer.get_topic("public", user)
- assert {:ok, "public:local"} = Streamer.get_topic("public:local", user)
- assert {:ok, "public:media"} = Streamer.get_topic("public:media", user)
- assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", user)
- end
-
- test "allows user streams", %{user: user} do
- expected_user_topic = "user:#{user.id}"
- expected_notif_topic = "user:notification:#{user.id}"
- expected_direct_topic = "direct:#{user.id}"
- assert {:ok, ^expected_user_topic} = Streamer.get_topic("user", user)
- assert {:ok, ^expected_notif_topic} = Streamer.get_topic("user:notification", user)
- assert {:ok, ^expected_direct_topic} = Streamer.get_topic("direct", user)
- end
-
- test "allows hashtag streams", %{user: user} do
- assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", user, %{"tag" => "cofe"})
- end
-
- test "disallows registering to an user stream", %{user: user} do
- another_user = insert(:user)
- assert {:error, _} = Streamer.get_topic("user:#{another_user.id}", user)
- assert {:error, _} = Streamer.get_topic("user:notification:#{another_user.id}", user)
- assert {:error, _} = Streamer.get_topic("direct:#{another_user.id}", user)
- end
-
- test "allows list stream that are owned by the user", %{user: user} do
- {:ok, list} = List.create("Test", user)
- assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
- assert {:ok, _} = Streamer.get_topic("list", user, %{"list" => list.id})
- end
-
- test "disallows list stream that are not owned by the user", %{user: user} do
- another_user = insert(:user)
- {:ok, list} = List.create("Test", another_user)
- assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
- assert {:error, _} = Streamer.get_topic("list", user, %{"list" => list.id})
- end
- end
-
- describe "user streams" do
- setup do
- user = insert(:user)
- notify = insert(:notification, user: user, activity: build(:note_activity))
- {:ok, %{user: user, notify: notify}}
- end
-
- test "it streams the user's post in the 'user' stream", %{user: user} do
- Streamer.get_topic_and_add_socket("user", user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
- assert_receive {:render_with_user, _, _, ^activity}
- refute Streamer.filtered_by_user?(user, activity)
- end
-
- test "it streams boosts of the user in the 'user' stream", %{user: user} do
- Streamer.get_topic_and_add_socket("user", user)
-
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
- {:ok, announce} = CommonAPI.repeat(activity.id, user)
-
- assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
- refute Streamer.filtered_by_user?(user, announce)
- end
-
- test "it does not stream announces of the user's own posts in the 'user' stream", %{
- user: user
- } do
- Streamer.get_topic_and_add_socket("user", user)
-
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, announce} = CommonAPI.repeat(activity.id, other_user)
-
- assert Streamer.filtered_by_user?(user, announce)
- end
-
- test "it does stream notifications announces of the user's own posts in the 'user' stream", %{
- user: user
- } do
- Streamer.get_topic_and_add_socket("user", user)
-
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
- {:ok, announce} = CommonAPI.repeat(activity.id, other_user)
-
- notification =
- Pleroma.Notification
- |> Repo.get_by(%{user_id: user.id, activity_id: announce.id})
- |> Repo.preload(:activity)
-
- refute Streamer.filtered_by_user?(user, notification)
- end
-
- test "it streams boosts of mastodon user in the 'user' stream", %{user: user} do
- Streamer.get_topic_and_add_socket("user", user)
-
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
-
- data =
- File.read!("test/fixtures/mastodon-announce.json")
- |> Poison.decode!()
- |> Map.put("object", activity.data["object"])
- |> Map.put("actor", user.ap_id)
-
- {:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
- Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
-
- assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
- refute Streamer.filtered_by_user?(user, announce)
- end
-
- test "it sends notify to in the 'user' stream", %{user: user, notify: notify} do
- Streamer.get_topic_and_add_socket("user", user)
- Streamer.stream("user", notify)
- assert_receive {:render_with_user, _, _, ^notify}
- refute Streamer.filtered_by_user?(user, notify)
- end
-
- test "it sends notify to in the 'user:notification' stream", %{user: user, notify: notify} do
- Streamer.get_topic_and_add_socket("user:notification", user)
- Streamer.stream("user:notification", notify)
- assert_receive {:render_with_user, _, _, ^notify}
- refute Streamer.filtered_by_user?(user, notify)
- end
-
- test "it sends chat messages to the 'user:pleroma_chat' stream", %{user: user} do
- other_user = insert(:user)
-
- {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
- object = Object.normalize(create_activity, false)
- chat = Chat.get(user.id, other_user.ap_id)
- cm_ref = MessageReference.for_chat_and_object(chat, object)
- cm_ref = %{cm_ref | chat: chat, object: object}
-
- Streamer.get_topic_and_add_socket("user:pleroma_chat", user)
- Streamer.stream("user:pleroma_chat", {user, cm_ref})
-
- text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
-
- assert text =~ "hey cirno"
- assert_receive {:text, ^text}
- end
-
- test "it sends chat messages to the 'user' stream", %{user: user} do
- other_user = insert(:user)
-
- {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
- object = Object.normalize(create_activity, false)
- chat = Chat.get(user.id, other_user.ap_id)
- cm_ref = MessageReference.for_chat_and_object(chat, object)
- cm_ref = %{cm_ref | chat: chat, object: object}
-
- Streamer.get_topic_and_add_socket("user", user)
- Streamer.stream("user", {user, cm_ref})
-
- text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
-
- assert text =~ "hey cirno"
- assert_receive {:text, ^text}
- end
-
- test "it sends chat message notifications to the 'user:notification' stream", %{user: user} do
- other_user = insert(:user)
-
- {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey")
-
- notify =
- Repo.get_by(Pleroma.Notification, user_id: user.id, activity_id: create_activity.id)
- |> Repo.preload(:activity)
-
- Streamer.get_topic_and_add_socket("user:notification", user)
- Streamer.stream("user:notification", notify)
- assert_receive {:render_with_user, _, _, ^notify}
- refute Streamer.filtered_by_user?(user, notify)
- end
-
- test "it doesn't send notify to the 'user:notification' stream when a user is blocked", %{
- user: user
- } do
- blocked = insert(:user)
- {:ok, _user_relationship} = User.block(user, blocked)
-
- Streamer.get_topic_and_add_socket("user:notification", user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: ":("})
- {:ok, _} = CommonAPI.favorite(blocked, activity.id)
-
- refute_receive _
- end
-
- test "it doesn't send notify to the 'user:notification' stream when a thread is muted", %{
- user: user
- } do
- user2 = insert(:user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
- {:ok, _} = CommonAPI.add_mute(user, activity)
-
- Streamer.get_topic_and_add_socket("user:notification", user)
-
- {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
-
- refute_receive _
- assert Streamer.filtered_by_user?(user, favorite_activity)
- end
-
- test "it sends favorite to 'user:notification' stream'", %{
- user: user
- } do
- user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"})
-
- {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
- Streamer.get_topic_and_add_socket("user:notification", user)
- {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
-
- assert_receive {:render_with_user, _, "notification.json", notif}
- assert notif.activity.id == favorite_activity.id
- refute Streamer.filtered_by_user?(user, notif)
- end
-
- test "it doesn't send the 'user:notification' stream' when a domain is blocked", %{
- user: user
- } do
- user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"})
-
- {:ok, user} = User.block_domain(user, "hecking-lewd-place.com")
- {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
- Streamer.get_topic_and_add_socket("user:notification", user)
- {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
-
- refute_receive _
- assert Streamer.filtered_by_user?(user, favorite_activity)
- end
-
- test "it sends follow activities to the 'user:notification' stream", %{
- user: user
- } do
- user_url = user.ap_id
- user2 = insert(:user)
-
- body =
- File.read!("test/fixtures/users_mock/localhost.json")
- |> String.replace("{{nickname}}", user.nickname)
- |> Jason.encode!()
-
- Tesla.Mock.mock_global(fn
- %{method: :get, url: ^user_url} ->
- %Tesla.Env{status: 200, body: body}
- end)
-
- Streamer.get_topic_and_add_socket("user:notification", user)
- {:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
-
- assert_receive {:render_with_user, _, "notification.json", notif}
- assert notif.activity.id == follow_activity.id
- refute Streamer.filtered_by_user?(user, notif)
- end
- end
-
- test "it sends to public authenticated" do
- user = insert(:user)
- other_user = insert(:user)
-
- Streamer.get_topic_and_add_socket("public", other_user)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Test"})
- assert_receive {:render_with_user, _, _, ^activity}
- refute Streamer.filtered_by_user?(user, activity)
- end
-
- test "works for deletions" do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
-
- Streamer.get_topic_and_add_socket("public", user)
-
- {:ok, _} = CommonAPI.delete(activity.id, other_user)
- activity_id = activity.id
- assert_receive {:text, event}
- assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event)
- end
-
- test "it sends to public unauthenticated" do
- user = insert(:user)
-
- Streamer.get_topic_and_add_socket("public", nil)
-
- {:ok, activity} = CommonAPI.post(user, %{status: "Test"})
- activity_id = activity.id
- assert_receive {:text, event}
- assert %{"event" => "update", "payload" => payload} = Jason.decode!(event)
- assert %{"id" => ^activity_id} = Jason.decode!(payload)
-
- {:ok, _} = CommonAPI.delete(activity.id, user)
- assert_receive {:text, event}
- assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event)
- end
-
- describe "thread_containment" do
- test "it filters to user if recipients invalid and thread containment is enabled" do
- Pleroma.Config.put([:instance, :skip_thread_containment], false)
- author = insert(:user)
- user = insert(:user)
- User.follow(user, author, :follow_accept)
-
- activity =
- insert(:note_activity,
- note:
- insert(:note,
- user: author,
- data: %{"to" => ["TEST-FFF"]}
- )
- )
-
- Streamer.get_topic_and_add_socket("public", user)
- Streamer.stream("public", activity)
- assert_receive {:render_with_user, _, _, ^activity}
- assert Streamer.filtered_by_user?(user, activity)
- end
-
- test "it sends message if recipients invalid and thread containment is disabled" do
- Pleroma.Config.put([:instance, :skip_thread_containment], true)
- author = insert(:user)
- user = insert(:user)
- User.follow(user, author, :follow_accept)
-
- activity =
- insert(:note_activity,
- note:
- insert(:note,
- user: author,
- data: %{"to" => ["TEST-FFF"]}
- )
- )
-
- Streamer.get_topic_and_add_socket("public", user)
- Streamer.stream("public", activity)
-
- assert_receive {:render_with_user, _, _, ^activity}
- refute Streamer.filtered_by_user?(user, activity)
- end
-
- test "it sends message if recipients invalid and thread containment is enabled but user's thread containment is disabled" do
- Pleroma.Config.put([:instance, :skip_thread_containment], false)
- author = insert(:user)
- user = insert(:user, skip_thread_containment: true)
- User.follow(user, author, :follow_accept)
-
- activity =
- insert(:note_activity,
- note:
- insert(:note,
- user: author,
- data: %{"to" => ["TEST-FFF"]}
- )
- )
-
- Streamer.get_topic_and_add_socket("public", user)
- Streamer.stream("public", activity)
-
- assert_receive {:render_with_user, _, _, ^activity}
- refute Streamer.filtered_by_user?(user, activity)
- end
- end
-
- describe "blocks" do
- test "it filters messages involving blocked users" do
- user = insert(:user)
- blocked_user = insert(:user)
- {:ok, _user_relationship} = User.block(user, blocked_user)
-
- Streamer.get_topic_and_add_socket("public", user)
- {:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"})
- assert_receive {:render_with_user, _, _, ^activity}
- assert Streamer.filtered_by_user?(user, activity)
- end
-
- test "it filters messages transitively involving blocked users" do
- blocker = insert(:user)
- blockee = insert(:user)
- friend = insert(:user)
-
- Streamer.get_topic_and_add_socket("public", blocker)
-
- {:ok, _user_relationship} = User.block(blocker, blockee)
-
- {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
-
- assert_receive {:render_with_user, _, _, ^activity_one}
- assert Streamer.filtered_by_user?(blocker, activity_one)
-
- {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
-
- assert_receive {:render_with_user, _, _, ^activity_two}
- assert Streamer.filtered_by_user?(blocker, activity_two)
-
- {:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
-
- assert_receive {:render_with_user, _, _, ^activity_three}
- assert Streamer.filtered_by_user?(blocker, activity_three)
- end
- end
-
- describe "lists" do
- test "it doesn't send unwanted DMs to list" do
- user_a = insert(:user)
- user_b = insert(:user)
- user_c = insert(:user)
-
- {:ok, user_a} = User.follow(user_a, user_b)
-
- {:ok, list} = List.create("Test", user_a)
- {:ok, list} = List.follow(list, user_b)
-
- Streamer.get_topic_and_add_socket("list", user_a, %{"list" => list.id})
-
- {:ok, _activity} =
- CommonAPI.post(user_b, %{
- status: "@#{user_c.nickname} Test",
- visibility: "direct"
- })
-
- refute_receive _
- end
-
- test "it doesn't send unwanted private posts to list" do
- user_a = insert(:user)
- user_b = insert(:user)
-
- {:ok, list} = List.create("Test", user_a)
- {:ok, list} = List.follow(list, user_b)
-
- Streamer.get_topic_and_add_socket("list", user_a, %{"list" => list.id})
-
- {:ok, _activity} =
- CommonAPI.post(user_b, %{
- status: "Test",
- visibility: "private"
- })
-
- refute_receive _
- end
-
- test "it sends wanted private posts to list" do
- user_a = insert(:user)
- user_b = insert(:user)
-
- {:ok, user_a} = User.follow(user_a, user_b)
-
- {:ok, list} = List.create("Test", user_a)
- {:ok, list} = List.follow(list, user_b)
-
- Streamer.get_topic_and_add_socket("list", user_a, %{"list" => list.id})
-
- {:ok, activity} =
- CommonAPI.post(user_b, %{
- status: "Test",
- visibility: "private"
- })
-
- assert_receive {:render_with_user, _, _, ^activity}
- refute Streamer.filtered_by_user?(user_a, activity)
- end
- end
-
- describe "muted reblogs" do
- test "it filters muted reblogs" do
- user1 = insert(:user)
- user2 = insert(:user)
- user3 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.hide_reblogs(user1, user2)
-
- {:ok, create_activity} = CommonAPI.post(user3, %{status: "I'm kawen"})
-
- Streamer.get_topic_and_add_socket("user", user1)
- {:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
- assert_receive {:render_with_user, _, _, ^announce_activity}
- assert Streamer.filtered_by_user?(user1, announce_activity)
- end
-
- test "it filters reblog notification for reblog-muted actors" do
- user1 = insert(:user)
- user2 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.hide_reblogs(user1, user2)
-
- {:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
- Streamer.get_topic_and_add_socket("user", user1)
- {:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
-
- assert_receive {:render_with_user, _, "notification.json", notif}
- assert Streamer.filtered_by_user?(user1, notif)
- end
-
- test "it send non-reblog notification for reblog-muted actors" do
- user1 = insert(:user)
- user2 = insert(:user)
- CommonAPI.follow(user1, user2)
- CommonAPI.hide_reblogs(user1, user2)
-
- {:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
- Streamer.get_topic_and_add_socket("user", user1)
- {:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
-
- assert_receive {:render_with_user, _, "notification.json", notif}
- refute Streamer.filtered_by_user?(user1, notif)
- end
- end
-
- test "it filters posts from muted threads" do
- user = insert(:user)
- user2 = insert(:user)
- Streamer.get_topic_and_add_socket("user", user2)
- {:ok, user2, user, _activity} = CommonAPI.follow(user2, user)
- {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
- {:ok, _} = CommonAPI.add_mute(user2, activity)
- assert_receive {:render_with_user, _, _, ^activity}
- assert Streamer.filtered_by_user?(user2, activity)
- end
-
- describe "direct streams" do
- setup do
- :ok
- end
-
- test "it sends conversation update to the 'direct' stream", %{} do
- user = insert(:user)
- another_user = insert(:user)
-
- Streamer.get_topic_and_add_socket("direct", user)
-
- {:ok, _create_activity} =
- CommonAPI.post(another_user, %{
- status: "hey @#{user.nickname}",
- visibility: "direct"
- })
-
- assert_receive {:text, received_event}
-
- assert %{"event" => "conversation", "payload" => received_payload} =
- Jason.decode!(received_event)
-
- assert %{"last_status" => last_status} = Jason.decode!(received_payload)
- [participation] = Participation.for_user(user)
- assert last_status["pleroma"]["direct_conversation_id"] == participation.id
- end
-
- test "it doesn't send conversation update to the 'direct' stream when the last message in the conversation is deleted" do
- user = insert(:user)
- another_user = insert(:user)
-
- Streamer.get_topic_and_add_socket("direct", user)
-
- {:ok, create_activity} =
- CommonAPI.post(another_user, %{
- status: "hi @#{user.nickname}",
- visibility: "direct"
- })
-
- create_activity_id = create_activity.id
- assert_receive {:render_with_user, _, _, ^create_activity}
- assert_receive {:text, received_conversation1}
- assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
-
- {:ok, _} = CommonAPI.delete(create_activity_id, another_user)
-
- assert_receive {:text, received_event}
-
- assert %{"event" => "delete", "payload" => ^create_activity_id} =
- Jason.decode!(received_event)
-
- refute_receive _
- end
-
- test "it sends conversation update to the 'direct' stream when a message is deleted" do
- user = insert(:user)
- another_user = insert(:user)
- Streamer.get_topic_and_add_socket("direct", user)
-
- {:ok, create_activity} =
- CommonAPI.post(another_user, %{
- status: "hi @#{user.nickname}",
- visibility: "direct"
- })
-
- {:ok, create_activity2} =
- CommonAPI.post(another_user, %{
- status: "hi @#{user.nickname} 2",
- in_reply_to_status_id: create_activity.id,
- visibility: "direct"
- })
-
- assert_receive {:render_with_user, _, _, ^create_activity}
- assert_receive {:render_with_user, _, _, ^create_activity2}
- assert_receive {:text, received_conversation1}
- assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
- assert_receive {:text, received_conversation1}
- assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
-
- {:ok, _} = CommonAPI.delete(create_activity2.id, another_user)
-
- assert_receive {:text, received_event}
- assert %{"event" => "delete", "payload" => _} = Jason.decode!(received_event)
-
- assert_receive {:text, received_event}
-
- assert %{"event" => "conversation", "payload" => received_payload} =
- Jason.decode!(received_event)
-
- assert %{"last_status" => last_status} = Jason.decode!(received_payload)
- assert last_status["id"] == to_string(create_activity.id)
- end
- end
-end
diff --git a/test/web/twitter_api/password_controller_test.exs b/test/web/twitter_api/password_controller_test.exs
deleted file mode 100644
index 231a46c67..000000000
--- a/test/web/twitter_api/password_controller_test.exs
+++ /dev/null
@@ -1,81 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.PasswordResetToken
- alias Pleroma.User
- alias Pleroma.Web.OAuth.Token
- import Pleroma.Factory
-
- describe "GET /api/pleroma/password_reset/token" do
- test "it returns error when token invalid", %{conn: conn} do
- response =
- conn
- |> get("/api/pleroma/password_reset/token")
- |> html_response(:ok)
-
- assert response =~ "<h2>Invalid Token</h2>"
- end
-
- test "it shows password reset form", %{conn: conn} do
- user = insert(:user)
- {:ok, token} = PasswordResetToken.create_token(user)
-
- response =
- conn
- |> get("/api/pleroma/password_reset/#{token.token}")
- |> html_response(:ok)
-
- assert response =~ "<h2>Password Reset for #{user.nickname}</h2>"
- end
- end
-
- describe "POST /api/pleroma/password_reset" do
- test "it returns HTTP 200", %{conn: conn} do
- user = insert(:user)
- {: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
- }
-
- response =
- conn
- |> assign(:user, user)
- |> post("/api/pleroma/password_reset", %{data: params})
- |> html_response(:ok)
-
- assert response =~ "<h2>Password changed!</h2>"
-
- user = refresh_record(user)
- assert Pbkdf2.verify_pass("test", user.password_hash)
- assert Enum.empty?(Token.get_user_tokens(user))
- end
-
- test "it sets password_reset_pending to false", %{conn: conn} do
- user = insert(:user, 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).password_reset_pending == false
- end
- end
-end
diff --git a/test/web/twitter_api/remote_follow_controller_test.exs b/test/web/twitter_api/remote_follow_controller_test.exs
deleted file mode 100644
index f7e54c26a..000000000
--- a/test/web/twitter_api/remote_follow_controller_test.exs
+++ /dev/null
@@ -1,350 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Config
- alias Pleroma.MFA
- alias Pleroma.MFA.TOTP
- alias Pleroma.User
- alias Pleroma.Web.CommonAPI
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
- import Ecto.Query
-
- setup do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup_all do: clear_config([:instance, :federating], true)
- setup do: clear_config([:instance])
- setup do: clear_config([:frontend_configurations, :pleroma_fe])
- setup do: clear_config([:user, :deny_follow_blocked])
-
- describe "GET /ostatus_subscribe - remote_follow/2" do
- test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do
- assert conn
- |> get(
- remote_follow_path(conn, :follow, %{
- acct: "https://mastodon.social/users/emelie/statuses/101849165031453009"
- })
- )
- |> redirected_to() =~ "/notice/"
- end
-
- test "show follow account page if the `acct` is a account link", %{conn: conn} do
- response =
- conn
- |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
- |> html_response(200)
-
- assert response =~ "Log in to follow"
- end
-
- test "show follow page if the `acct` is a account link", %{conn: conn} do
- user = insert(:user)
-
- response =
- conn
- |> assign(:user, user)
- |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
- |> html_response(200)
-
- assert response =~ "Remote follow"
- end
-
- test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do
- user = insert(:user)
-
- assert capture_log(fn ->
- response =
- conn
- |> assign(:user, user)
- |> get(
- remote_follow_path(conn, :follow, %{
- acct: "https://mastodon.social/users/not_found"
- })
- )
- |> html_response(200)
-
- assert response =~ "Error fetching user"
- end) =~ "Object has been deleted"
- end
- end
-
- describe "POST /ostatus_subscribe - do_follow/2 with assigned user " do
- test "required `follow | write:follows` scope", %{conn: conn} do
- user = insert(:user)
- user2 = insert(:user)
- read_token = insert(:oauth_token, user: user, scopes: ["read"])
-
- assert capture_log(fn ->
- response =
- conn
- |> assign(:user, user)
- |> assign(:token, read_token)
- |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
- |> response(200)
-
- assert response =~ "Error following account"
- end) =~ "Insufficient permissions: follow | write:follows."
- end
-
- test "follows user", %{conn: conn} do
- user = insert(:user)
- user2 = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
- |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
-
- assert redirected_to(conn) == "/users/#{user2.id}"
- end
-
- test "returns error when user is deactivated", %{conn: conn} do
- user = insert(:user, deactivated: true)
- user2 = insert(:user)
-
- response =
- conn
- |> assign(:user, user)
- |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
- |> response(200)
-
- assert response =~ "Error following account"
- end
-
- test "returns error when user is blocked", %{conn: conn} do
- Pleroma.Config.put([:user, :deny_follow_blocked], true)
- user = insert(:user)
- user2 = insert(:user)
-
- {:ok, _user_block} = Pleroma.User.block(user2, user)
-
- response =
- conn
- |> assign(:user, user)
- |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
- |> response(200)
-
- assert response =~ "Error following account"
- end
-
- test "returns error when followee not found", %{conn: conn} do
- user = insert(:user)
-
- response =
- conn
- |> assign(:user, user)
- |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => "jimm"}})
- |> response(200)
-
- assert response =~ "Error following account"
- end
-
- test "returns success result when user already in followers", %{conn: conn} do
- user = insert(:user)
- user2 = insert(:user)
- {:ok, _, _, _} = CommonAPI.follow(user, user2)
-
- conn =
- conn
- |> assign(:user, refresh_record(user))
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
- |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
-
- assert redirected_to(conn) == "/users/#{user2.id}"
- end
- end
-
- describe "POST /ostatus_subscribe - follow/2 with enabled Two-Factor Auth " do
- test "render the MFA login form", %{conn: conn} do
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- user2 = insert(:user)
-
- response =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
- })
- |> response(200)
-
- mfa_token = Pleroma.Repo.one(from(q in Pleroma.MFA.Token, where: q.user_id == ^user.id))
-
- assert response =~ "Two-factor authentication"
- assert response =~ "Authentication code"
- assert response =~ mfa_token.token
- refute user2.follower_address in User.following(user)
- end
-
- test "returns error when password is incorrect", %{conn: conn} do
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- user2 = insert(:user)
-
- response =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => user.nickname, "password" => "test1", "id" => user2.id}
- })
- |> response(200)
-
- assert response =~ "Wrong username or password"
- refute user2.follower_address in User.following(user)
- end
-
- test "follows", %{conn: conn} do
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- {:ok, %{token: token}} = MFA.Token.create_token(user)
-
- user2 = insert(:user)
- otp_token = TOTP.generate_token(otp_secret)
-
- conn =
- conn
- |> post(
- remote_follow_path(conn, :do_follow),
- %{
- "mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id}
- }
- )
-
- assert redirected_to(conn) == "/users/#{user2.id}"
- assert user2.follower_address in User.following(user)
- end
-
- test "returns error when auth code is incorrect", %{conn: conn} do
- otp_secret = TOTP.generate_secret()
-
- user =
- insert(:user,
- multi_factor_authentication_settings: %MFA.Settings{
- enabled: true,
- totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
- }
- )
-
- {:ok, %{token: token}} = MFA.Token.create_token(user)
-
- user2 = insert(:user)
- otp_token = TOTP.generate_token(TOTP.generate_secret())
-
- response =
- conn
- |> post(
- remote_follow_path(conn, :do_follow),
- %{
- "mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id}
- }
- )
- |> response(200)
-
- assert response =~ "Wrong authentication code"
- refute user2.follower_address in User.following(user)
- end
- end
-
- describe "POST /ostatus_subscribe - follow/2 without assigned user " do
- test "follows", %{conn: conn} do
- user = insert(:user)
- user2 = insert(:user)
-
- conn =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
- })
-
- assert redirected_to(conn) == "/users/#{user2.id}"
- assert user2.follower_address in User.following(user)
- end
-
- test "returns error when followee not found", %{conn: conn} do
- user = insert(:user)
-
- response =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"}
- })
- |> response(200)
-
- assert response =~ "Error following account"
- end
-
- test "returns error when login invalid", %{conn: conn} do
- user = insert(:user)
-
- response =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id}
- })
- |> response(200)
-
- assert response =~ "Wrong username or password"
- end
-
- test "returns error when password invalid", %{conn: conn} do
- user = insert(:user)
- user2 = insert(:user)
-
- response =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id}
- })
- |> response(200)
-
- assert response =~ "Wrong username or password"
- end
-
- test "returns error when user is blocked", %{conn: conn} do
- Pleroma.Config.put([:user, :deny_follow_blocked], true)
- user = insert(:user)
- user2 = insert(:user)
- {:ok, _user_block} = Pleroma.User.block(user2, user)
-
- response =
- conn
- |> post(remote_follow_path(conn, :do_follow), %{
- "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
- })
- |> response(200)
-
- assert response =~ "Error following account"
- end
- end
-end
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
deleted file mode 100644
index 464d0ea2e..000000000
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ /dev/null
@@ -1,138 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.TwitterAPI.ControllerTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Builders.ActivityBuilder
- alias Pleroma.Repo
- alias Pleroma.User
- alias Pleroma.Web.OAuth.Token
-
- import Pleroma.Factory
-
- describe "POST /api/qvitter/statuses/notifications/read" do
- test "without valid credentials", %{conn: conn} do
- conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
- assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
- end
-
- test "with credentials, without any params" do
- %{conn: conn} = oauth_access(["write:notifications"])
-
- conn = post(conn, "/api/qvitter/statuses/notifications/read")
-
- assert json_response(conn, 400) == %{
- "error" => "You need to specify latest_id",
- "request" => "/api/qvitter/statuses/notifications/read"
- }
- end
-
- test "with credentials, with params" do
- %{user: current_user, conn: conn} =
- oauth_access(["read:notifications", "write:notifications"])
-
- other_user = insert(:user)
-
- {:ok, _activity} =
- ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
-
- response_conn =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/notifications")
-
- [notification] = response = json_response(response_conn, 200)
-
- assert length(response) == 1
-
- assert notification["pleroma"]["is_seen"] == false
-
- response_conn =
- conn
- |> assign(:user, current_user)
- |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
-
- [notification] = response = json_response(response_conn, 200)
-
- assert length(response) == 1
-
- assert notification["pleroma"]["is_seen"] == true
- end
- end
-
- describe "GET /api/account/confirm_email/:id/:token" do
- setup do
- {:ok, user} =
- insert(:user)
- |> User.confirmation_changeset(need_confirmation: true)
- |> Repo.update()
-
- assert user.confirmation_pending
-
- [user: user]
- end
-
- test "it redirects to root url", %{conn: conn, user: user} do
- conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.confirmation_token}")
-
- assert 302 == conn.status
- end
-
- test "it confirms the user account", %{conn: conn, user: user} do
- get(conn, "/api/account/confirm_email/#{user.id}/#{user.confirmation_token}")
-
- user = User.get_cached_by_id(user.id)
-
- refute user.confirmation_pending
- refute user.confirmation_token
- end
-
- test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
- conn = get(conn, "/api/account/confirm_email/0/#{user.confirmation_token}")
-
- assert 500 == conn.status
- end
-
- test "it returns 500 if token is invalid", %{conn: conn, user: user} do
- conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
-
- assert 500 == conn.status
- end
- end
-
- describe "GET /api/oauth_tokens" do
- setup do
- token = insert(:oauth_token) |> Repo.preload(:user)
-
- %{token: token}
- end
-
- test "renders list", %{token: token} do
- response =
- build_conn()
- |> assign(:user, token.user)
- |> get("/api/oauth_tokens")
-
- keys =
- json_response(response, 200)
- |> hd()
- |> Map.keys()
-
- assert keys -- ["id", "app_name", "valid_until"] == []
- end
-
- test "revoke token", %{token: token} do
- response =
- build_conn()
- |> assign(:user, token.user)
- |> delete("/api/oauth_tokens/#{token.id}")
-
- tokens = Token.get_user_tokens(token.user)
-
- assert tokens == []
- assert response.status == 201
- end
- end
-end
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
deleted file mode 100644
index 20a45cb6f..000000000
--- a/test/web/twitter_api/twitter_api_test.exs
+++ /dev/null
@@ -1,432 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
- use Pleroma.DataCase
- import Pleroma.Factory
- alias Pleroma.Repo
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
- alias Pleroma.UserInviteToken
- alias Pleroma.Web.TwitterAPI.TwitterAPI
-
- setup_all do
- Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- test "it registers a new user and returns the user." do
- data = %{
- :username => "lain",
- :email => "lain@wired.jp",
- :fullname => "lain iwakura",
- :password => "bear",
- :confirm => "bear"
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
-
- assert user == User.get_cached_by_nickname("lain")
- end
-
- test "it registers a new user with empty string in bio and returns the user" do
- data = %{
- :username => "lain",
- :email => "lain@wired.jp",
- :fullname => "lain iwakura",
- :bio => "",
- :password => "bear",
- :confirm => "bear"
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
-
- assert user == User.get_cached_by_nickname("lain")
- end
-
- test "it sends confirmation email if :account_activation_required is specified in instance config" do
- setting = Pleroma.Config.get([:instance, :account_activation_required])
-
- unless setting do
- Pleroma.Config.put([:instance, :account_activation_required], true)
- on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
- end
-
- data = %{
- :username => "lain",
- :email => "lain@wired.jp",
- :fullname => "lain iwakura",
- :bio => "",
- :password => "bear",
- :confirm => "bear"
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
- ObanHelpers.perform_all()
-
- assert user.confirmation_pending
-
- email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
-
- notify_email = Pleroma.Config.get([:instance, :notify_email])
- instance_name = Pleroma.Config.get([:instance, :name])
-
- Swoosh.TestAssertions.assert_email_sent(
- from: {instance_name, notify_email},
- to: {user.name, user.email},
- html_body: email.html_body
- )
- end
-
- test "it sends an admin email if :account_approval_required is specified in instance config" do
- admin = insert(:user, is_admin: true)
- setting = Pleroma.Config.get([:instance, :account_approval_required])
-
- unless setting do
- Pleroma.Config.put([:instance, :account_approval_required], true)
- on_exit(fn -> Pleroma.Config.put([:instance, :account_approval_required], setting) end)
- end
-
- data = %{
- :username => "lain",
- :email => "lain@wired.jp",
- :fullname => "lain iwakura",
- :bio => "",
- :password => "bear",
- :confirm => "bear",
- :reason => "I love anime"
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
- ObanHelpers.perform_all()
-
- assert user.approval_pending
-
- email = Pleroma.Emails.AdminEmail.new_unapproved_registration(admin, user)
-
- notify_email = Pleroma.Config.get([:instance, :notify_email])
- instance_name = Pleroma.Config.get([:instance, :name])
-
- Swoosh.TestAssertions.assert_email_sent(
- from: {instance_name, notify_email},
- to: {admin.name, admin.email},
- html_body: email.html_body
- )
- end
-
- test "it registers a new user and parses mentions in the bio" do
- data1 = %{
- :username => "john",
- :email => "john@gmail.com",
- :fullname => "John Doe",
- :bio => "test",
- :password => "bear",
- :confirm => "bear"
- }
-
- {:ok, user1} = TwitterAPI.register_user(data1)
-
- data2 = %{
- :username => "lain",
- :email => "lain@wired.jp",
- :fullname => "lain iwakura",
- :bio => "@john test",
- :password => "bear",
- :confirm => "bear"
- }
-
- {:ok, user2} = TwitterAPI.register_user(data2)
-
- expected_text =
- ~s(<span class="h-card"><a class="u-url mention" data-user="#{user1.id}" href="#{
- user1.ap_id
- }" rel="ugc">@<span>john</span></a></span> test)
-
- assert user2.bio == expected_text
- end
-
- describe "register with one time token" do
- setup do: clear_config([:instance, :registrations_open], false)
-
- test "returns user on success" do
- {:ok, invite} = UserInviteToken.create_invite()
-
- data = %{
- :username => "vinny",
- :email => "pasta@pizza.vs",
- :fullname => "Vinny Vinesauce",
- :bio => "streamer",
- :password => "hiptofbees",
- :confirm => "hiptofbees",
- :token => invite.token
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
-
- assert user == User.get_cached_by_nickname("vinny")
-
- invite = Repo.get_by(UserInviteToken, token: invite.token)
- assert invite.used == true
- end
-
- test "returns error on invalid token" do
- data = %{
- :username => "GrimReaper",
- :email => "death@reapers.afterlife",
- :fullname => "Reaper Grim",
- :bio => "Your time has come",
- :password => "scythe",
- :confirm => "scythe",
- :token => "DudeLetMeInImAFairy"
- }
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Invalid token"
- refute User.get_cached_by_nickname("GrimReaper")
- end
-
- test "returns error on expired token" do
- {:ok, invite} = UserInviteToken.create_invite()
- UserInviteToken.update_invite!(invite, used: true)
-
- data = %{
- :username => "GrimReaper",
- :email => "death@reapers.afterlife",
- :fullname => "Reaper Grim",
- :bio => "Your time has come",
- :password => "scythe",
- :confirm => "scythe",
- :token => invite.token
- }
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Expired token"
- refute User.get_cached_by_nickname("GrimReaper")
- end
- end
-
- describe "registers with date limited token" do
- setup do: clear_config([:instance, :registrations_open], false)
-
- setup do
- data = %{
- :username => "vinny",
- :email => "pasta@pizza.vs",
- :fullname => "Vinny Vinesauce",
- :bio => "streamer",
- :password => "hiptofbees",
- :confirm => "hiptofbees"
- }
-
- check_fn = fn invite ->
- data = Map.put(data, :token, invite.token)
- {:ok, user} = TwitterAPI.register_user(data)
-
- assert user == User.get_cached_by_nickname("vinny")
- end
-
- {:ok, data: data, check_fn: check_fn}
- end
-
- test "returns user on success", %{check_fn: check_fn} do
- {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today()})
-
- check_fn.(invite)
-
- invite = Repo.get_by(UserInviteToken, token: invite.token)
-
- refute invite.used
- end
-
- test "returns user on token which expired tomorrow", %{check_fn: check_fn} do
- {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), 1)})
-
- check_fn.(invite)
-
- invite = Repo.get_by(UserInviteToken, token: invite.token)
-
- refute invite.used
- end
-
- test "returns an error on overdue date", %{data: data} do
- {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1)})
-
- data = Map.put(data, "token", invite.token)
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Expired token"
- refute User.get_cached_by_nickname("vinny")
- invite = Repo.get_by(UserInviteToken, token: invite.token)
-
- refute invite.used
- end
- end
-
- describe "registers with reusable token" do
- setup do: clear_config([:instance, :registrations_open], false)
-
- test "returns user on success, after him registration fails" do
- {:ok, invite} = UserInviteToken.create_invite(%{max_use: 100})
-
- UserInviteToken.update_invite!(invite, uses: 99)
-
- data = %{
- :username => "vinny",
- :email => "pasta@pizza.vs",
- :fullname => "Vinny Vinesauce",
- :bio => "streamer",
- :password => "hiptofbees",
- :confirm => "hiptofbees",
- :token => invite.token
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
- assert user == User.get_cached_by_nickname("vinny")
-
- invite = Repo.get_by(UserInviteToken, token: invite.token)
- assert invite.used == true
-
- data = %{
- :username => "GrimReaper",
- :email => "death@reapers.afterlife",
- :fullname => "Reaper Grim",
- :bio => "Your time has come",
- :password => "scythe",
- :confirm => "scythe",
- :token => invite.token
- }
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Expired token"
- refute User.get_cached_by_nickname("GrimReaper")
- end
- end
-
- describe "registers with reusable date limited token" do
- setup do: clear_config([:instance, :registrations_open], false)
-
- test "returns user on success" do
- {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100})
-
- data = %{
- :username => "vinny",
- :email => "pasta@pizza.vs",
- :fullname => "Vinny Vinesauce",
- :bio => "streamer",
- :password => "hiptofbees",
- :confirm => "hiptofbees",
- :token => invite.token
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
- assert user == User.get_cached_by_nickname("vinny")
-
- invite = Repo.get_by(UserInviteToken, token: invite.token)
- refute invite.used
- end
-
- test "error after max uses" do
- {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100})
-
- UserInviteToken.update_invite!(invite, uses: 99)
-
- data = %{
- :username => "vinny",
- :email => "pasta@pizza.vs",
- :fullname => "Vinny Vinesauce",
- :bio => "streamer",
- :password => "hiptofbees",
- :confirm => "hiptofbees",
- :token => invite.token
- }
-
- {:ok, user} = TwitterAPI.register_user(data)
- assert user == User.get_cached_by_nickname("vinny")
-
- invite = Repo.get_by(UserInviteToken, token: invite.token)
- assert invite.used == true
-
- data = %{
- :username => "GrimReaper",
- :email => "death@reapers.afterlife",
- :fullname => "Reaper Grim",
- :bio => "Your time has come",
- :password => "scythe",
- :confirm => "scythe",
- :token => invite.token
- }
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Expired token"
- refute User.get_cached_by_nickname("GrimReaper")
- end
-
- test "returns error on overdue date" do
- {:ok, invite} =
- UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1), max_use: 100})
-
- data = %{
- :username => "GrimReaper",
- :email => "death@reapers.afterlife",
- :fullname => "Reaper Grim",
- :bio => "Your time has come",
- :password => "scythe",
- :confirm => "scythe",
- :token => invite.token
- }
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Expired token"
- refute User.get_cached_by_nickname("GrimReaper")
- end
-
- test "returns error on with overdue date and after max" do
- {:ok, invite} =
- UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1), max_use: 100})
-
- UserInviteToken.update_invite!(invite, uses: 100)
-
- data = %{
- :username => "GrimReaper",
- :email => "death@reapers.afterlife",
- :fullname => "Reaper Grim",
- :bio => "Your time has come",
- :password => "scythe",
- :confirm => "scythe",
- :token => invite.token
- }
-
- {:error, msg} = TwitterAPI.register_user(data)
-
- assert msg == "Expired token"
- refute User.get_cached_by_nickname("GrimReaper")
- end
- end
-
- test "it returns the error on registration problems" do
- data = %{
- :username => "lain",
- :email => "lain@wired.jp",
- :fullname => "lain iwakura",
- :bio => "close the world."
- }
-
- {:error, error} = TwitterAPI.register_user(data)
-
- assert is_binary(error)
- refute User.get_cached_by_nickname("lain")
- end
-
- setup do
- Supervisor.terminate_child(Pleroma.Supervisor, Cachex)
- Supervisor.restart_child(Pleroma.Supervisor, Cachex)
- :ok
- end
-end
diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs
deleted file mode 100644
index 354d77b56..000000000
--- a/test/web/twitter_api/util_controller_test.exs
+++ /dev/null
@@ -1,601 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
- use Pleroma.Web.ConnCase
- use Oban.Testing, repo: Pleroma.Repo
-
- alias Pleroma.Config
- alias Pleroma.Tests.ObanHelpers
- alias Pleroma.User
-
- import Pleroma.Factory
- import Mock
-
- setup do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup do: clear_config([:instance])
- setup do: clear_config([:frontend_configurations, :pleroma_fe])
-
- describe "POST /api/pleroma/follow_import" do
- setup do: oauth_access(["follow"])
-
- test "it returns HTTP 200", %{conn: conn} do
- user2 = insert(:user)
-
- response =
- conn
- |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"})
- |> json_response(:ok)
-
- assert response == "job started"
- end
-
- test "it imports follow lists from file", %{user: user1, conn: conn} do
- user2 = insert(:user)
-
- with_mocks([
- {File, [],
- read!: fn "follow_list.txt" ->
- "Account address,Show boosts\n#{user2.ap_id},true"
- end}
- ]) do
- response =
- conn
- |> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}})
- |> json_response(:ok)
-
- 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
-
- test "it imports new-style mastodon follow lists", %{conn: conn} do
- user2 = insert(:user)
-
- response =
- conn
- |> post("/api/pleroma/follow_import", %{
- "list" => "Account address,Show boosts\n#{user2.ap_id},true"
- })
- |> json_response(:ok)
-
- assert response == "job started"
- end
-
- test "requires 'follow' or 'write:follows' permissions" do
- token1 = insert(:oauth_token, scopes: ["read", "write"])
- token2 = insert(:oauth_token, scopes: ["follow"])
- token3 = insert(:oauth_token, scopes: ["something"])
- another_user = insert(:user)
-
- for token <- [token1, token2, token3] do
- conn =
- build_conn()
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
-
- if token == token3 do
- assert %{"error" => "Insufficient permissions: follow | write:follows."} ==
- json_response(conn, 403)
- else
- assert json_response(conn, 200)
- end
- end
- end
-
- test "it imports follows with different nickname variations", %{conn: conn} do
- [user2, user3, user4, user5, user6] = insert_list(5, :user)
-
- identifiers =
- [
- user2.ap_id,
- user3.nickname,
- " ",
- "@" <> user4.nickname,
- user5.nickname <> "@localhost",
- "@" <> user6.nickname <> "@localhost"
- ]
- |> Enum.join("\n")
-
- response =
- conn
- |> post("/api/pleroma/follow_import", %{"list" => identifiers})
- |> json_response(:ok)
-
- assert response == "job started"
- assert [{:ok, job_result}] = ObanHelpers.perform_all()
- assert job_result == [user2, user3, user4, user5, user6]
- end
- end
-
- describe "POST /api/pleroma/blocks_import" do
- # Note: "follow" or "write:blocks" permission is required
- setup do: oauth_access(["write:blocks"])
-
- test "it returns HTTP 200", %{conn: conn} do
- user2 = insert(:user)
-
- response =
- conn
- |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"})
- |> json_response(:ok)
-
- assert response == "job started"
- end
-
- test "it imports blocks users from file", %{user: user1, conn: conn} do
- user2 = insert(:user)
- user3 = insert(:user)
-
- with_mocks([
- {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end}
- ]) do
- response =
- conn
- |> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}})
- |> json_response(:ok)
-
- 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
-
- test "it imports blocks with different nickname variations", %{conn: conn} do
- [user2, user3, user4, user5, user6] = insert_list(5, :user)
-
- identifiers =
- [
- user2.ap_id,
- user3.nickname,
- "@" <> user4.nickname,
- user5.nickname <> "@localhost",
- "@" <> user6.nickname <> "@localhost"
- ]
- |> Enum.join(" ")
-
- response =
- conn
- |> post("/api/pleroma/blocks_import", %{"list" => identifiers})
- |> json_response(:ok)
-
- assert response == "job started"
- assert [{:ok, job_result}] = ObanHelpers.perform_all()
- assert job_result == [user2, user3, user4, user5, user6]
- end
- end
-
- describe "PUT /api/pleroma/notification_settings" do
- setup do: oauth_access(["write:accounts"])
-
- test "it updates notification settings", %{user: user, conn: conn} do
- conn
- |> put("/api/pleroma/notification_settings", %{
- "block_from_strangers" => true,
- "bar" => 1
- })
- |> json_response(:ok)
-
- user = refresh_record(user)
-
- assert %Pleroma.User.NotificationSetting{
- block_from_strangers: true,
- hide_notification_contents: false
- } == user.notification_settings
- end
-
- test "it updates notification settings to enable hiding contents", %{user: user, conn: conn} do
- conn
- |> put("/api/pleroma/notification_settings", %{"hide_notification_contents" => "1"})
- |> json_response(:ok)
-
- user = refresh_record(user)
-
- assert %Pleroma.User.NotificationSetting{
- block_from_strangers: false,
- hide_notification_contents: true
- } == user.notification_settings
- end
- end
-
- describe "GET /api/pleroma/frontend_configurations" do
- test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} do
- config = [
- frontend_a: %{
- x: 1,
- y: 2
- },
- frontend_b: %{
- z: 3
- }
- ]
-
- Config.put(:frontend_configurations, config)
-
- response =
- conn
- |> get("/api/pleroma/frontend_configurations")
- |> json_response(:ok)
-
- assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!()
- end
- end
-
- describe "/api/pleroma/emoji" do
- test "returns json with custom emoji with tags", %{conn: conn} do
- emoji =
- conn
- |> get("/api/pleroma/emoji")
- |> json_response(200)
-
- assert Enum.all?(emoji, fn
- {_key,
- %{
- "image_url" => url,
- "tags" => tags
- }} ->
- is_binary(url) and is_list(tags)
- end)
- end
- end
-
- describe "GET /api/pleroma/healthcheck" do
- setup do: clear_config([:instance, :healthcheck])
-
- test "returns 503 when healthcheck disabled", %{conn: conn} do
- Config.put([:instance, :healthcheck], false)
-
- response =
- conn
- |> get("/api/pleroma/healthcheck")
- |> json_response(503)
-
- assert response == %{}
- end
-
- test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do
- Config.put([:instance, :healthcheck], true)
-
- with_mock Pleroma.Healthcheck,
- system_info: fn -> %Pleroma.Healthcheck{healthy: true} end do
- response =
- conn
- |> get("/api/pleroma/healthcheck")
- |> json_response(200)
-
- assert %{
- "active" => _,
- "healthy" => true,
- "idle" => _,
- "memory_used" => _,
- "pool_size" => _
- } = response
- end
- end
-
- test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do
- Config.put([:instance, :healthcheck], true)
-
- with_mock Pleroma.Healthcheck,
- system_info: fn -> %Pleroma.Healthcheck{healthy: false} end do
- response =
- conn
- |> get("/api/pleroma/healthcheck")
- |> json_response(503)
-
- assert %{
- "active" => _,
- "healthy" => false,
- "idle" => _,
- "memory_used" => _,
- "pool_size" => _
- } = response
- end
- end
- end
-
- describe "POST /api/pleroma/disable_account" do
- setup do: oauth_access(["write:accounts"])
-
- test "with valid permissions and password, it disables the account", %{conn: conn, user: user} do
- response =
- conn
- |> post("/api/pleroma/disable_account", %{"password" => "test"})
- |> json_response(:ok)
-
- assert response == %{"status" => "success"}
- ObanHelpers.perform_all()
-
- user = User.get_cached_by_id(user.id)
-
- assert user.deactivated == true
- end
-
- test "with valid permissions and invalid password, it returns an error", %{conn: conn} do
- user = insert(:user)
-
- response =
- conn
- |> post("/api/pleroma/disable_account", %{"password" => "test1"})
- |> json_response(:ok)
-
- assert response == %{"error" => "Invalid password."}
- user = User.get_cached_by_id(user.id)
-
- refute user.deactivated
- end
- end
-
- describe "POST /main/ostatus - remote_subscribe/2" do
- setup do: clear_config([:instance, :federating], true)
-
- test "renders subscribe form", %{conn: conn} do
- user = insert(:user)
-
- response =
- conn
- |> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
- |> response(:ok)
-
- refute response =~ "Could not find user"
- assert response =~ "Remotely follow #{user.nickname}"
- end
-
- test "renders subscribe form with error when user not found", %{conn: conn} do
- response =
- conn
- |> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
- |> response(:ok)
-
- assert response =~ "Could not find user"
- refute response =~ "Remotely follow"
- end
-
- test "it redirect to webfinger url", %{conn: conn} do
- user = insert(:user)
- user2 = insert(:user, ap_id: "shp@social.heldscal.la")
-
- conn =
- conn
- |> post("/main/ostatus", %{
- "user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
- })
-
- assert redirected_to(conn) ==
- "https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
- end
-
- test "it renders form with error when user not found", %{conn: conn} do
- user2 = insert(:user, ap_id: "shp@social.heldscal.la")
-
- response =
- conn
- |> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
- |> response(:ok)
-
- assert response =~ "Something went wrong."
- end
- end
-
- test "it returns new captcha", %{conn: conn} do
- with_mock Pleroma.Captcha,
- new: fn -> "test_captcha" end do
- resp =
- conn
- |> get("/api/pleroma/captcha")
- |> response(200)
-
- assert resp == "\"test_captcha\""
- assert called(Pleroma.Captcha.new())
- end
- end
-
- describe "POST /api/pleroma/change_email" do
- setup do: oauth_access(["write:accounts"])
-
- test "without permissions", %{conn: conn} do
- conn =
- conn
- |> assign(:token, nil)
- |> post("/api/pleroma/change_email")
-
- assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."}
- end
-
- test "with proper permissions and invalid password", %{conn: conn} do
- conn =
- post(conn, "/api/pleroma/change_email", %{
- "password" => "hi",
- "email" => "test@test.com"
- })
-
- assert json_response(conn, 200) == %{"error" => "Invalid password."}
- end
-
- test "with proper permissions, valid password and invalid email", %{
- conn: conn
- } do
- conn =
- post(conn, "/api/pleroma/change_email", %{
- "password" => "test",
- "email" => "foobar"
- })
-
- assert json_response(conn, 200) == %{"error" => "Email has invalid format."}
- end
-
- test "with proper permissions, valid password and no email", %{
- conn: conn
- } do
- conn =
- post(conn, "/api/pleroma/change_email", %{
- "password" => "test"
- })
-
- assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
- end
-
- test "with proper permissions, valid password and blank email", %{
- conn: conn
- } do
- conn =
- post(conn, "/api/pleroma/change_email", %{
- "password" => "test",
- "email" => ""
- })
-
- assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
- end
-
- test "with proper permissions, valid password and non unique email", %{
- conn: conn
- } do
- user = insert(:user)
-
- conn =
- post(conn, "/api/pleroma/change_email", %{
- "password" => "test",
- "email" => user.email
- })
-
- assert json_response(conn, 200) == %{"error" => "Email has already been taken."}
- end
-
- test "with proper permissions, valid password and valid email", %{
- conn: conn
- } do
- conn =
- post(conn, "/api/pleroma/change_email", %{
- "password" => "test",
- "email" => "cofe@foobar.com"
- })
-
- assert json_response(conn, 200) == %{"status" => "success"}
- end
- end
-
- describe "POST /api/pleroma/change_password" do
- setup do: oauth_access(["write:accounts"])
-
- test "without permissions", %{conn: conn} do
- conn =
- conn
- |> assign(:token, nil)
- |> post("/api/pleroma/change_password")
-
- assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."}
- end
-
- test "with proper permissions and invalid password", %{conn: conn} do
- conn =
- post(conn, "/api/pleroma/change_password", %{
- "password" => "hi",
- "new_password" => "newpass",
- "new_password_confirmation" => "newpass"
- })
-
- assert json_response(conn, 200) == %{"error" => "Invalid password."}
- end
-
- test "with proper permissions, valid password and new password and confirmation not matching",
- %{
- conn: conn
- } do
- conn =
- post(conn, "/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 proper permissions, valid password and invalid new password", %{
- conn: conn
- } do
- conn =
- post(conn, "/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 proper permissions, valid password and matching new password and confirmation", %{
- conn: conn,
- user: user
- } do
- conn =
- post(conn, "/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(user.id)
- assert Pbkdf2.verify_pass("newpass", fetched_user.password_hash) == true
- end
- end
-
- describe "POST /api/pleroma/delete_account" do
- setup do: oauth_access(["write:accounts"])
-
- test "without permissions", %{conn: conn} do
- conn =
- conn
- |> assign(:token, nil)
- |> post("/api/pleroma/delete_account")
-
- assert json_response(conn, 403) ==
- %{"error" => "Insufficient permissions: write:accounts."}
- end
-
- test "with proper permissions and wrong or missing password", %{conn: conn} do
- for params <- [%{"password" => "hi"}, %{}] do
- ret_conn = post(conn, "/api/pleroma/delete_account", params)
-
- assert json_response(ret_conn, 200) == %{"error" => "Invalid password."}
- end
- end
-
- test "with proper permissions and valid password", %{conn: conn, user: user} do
- conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"})
- ObanHelpers.perform_all()
- assert json_response(conn, 200) == %{"status" => "success"}
-
- user = User.get_by_id(user.id)
- assert user.deactivated == true
- assert user.name == nil
- assert user.bio == nil
- assert user.password_hash == nil
- end
- end
-end
diff --git a/test/web/uploader_controller_test.exs b/test/web/uploader_controller_test.exs
deleted file mode 100644
index 21e518236..000000000
--- a/test/web/uploader_controller_test.exs
+++ /dev/null
@@ -1,43 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.UploaderControllerTest do
- use Pleroma.Web.ConnCase
- alias Pleroma.Uploaders.Uploader
-
- describe "callback/2" do
- test "it returns 400 response when process callback isn't alive", %{conn: conn} do
- res =
- conn
- |> post(uploader_path(conn, :callback, "test-path"))
-
- assert res.status == 400
- assert res.resp_body == "{\"error\":\"bad request\"}"
- end
-
- test "it returns success result", %{conn: conn} do
- task =
- Task.async(fn ->
- receive do
- {Uploader, pid, conn, _params} ->
- conn =
- conn
- |> put_status(:ok)
- |> Phoenix.Controller.json(%{upload_path: "test-path"})
-
- send(pid, {Uploader, conn})
- end
- end)
-
- :global.register_name({Uploader, "test-path"}, task.pid)
-
- res =
- conn
- |> post(uploader_path(conn, :callback, "test-path"))
- |> json_response(200)
-
- assert res == %{"upload_path" => "test-path"}
- end
- end
-end
diff --git a/test/web/views/error_view_test.exs b/test/web/views/error_view_test.exs
deleted file mode 100644
index 8dbbd18b4..000000000
--- a/test/web/views/error_view_test.exs
+++ /dev/null
@@ -1,36 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ErrorViewTest do
- use Pleroma.Web.ConnCase, async: true
- import ExUnit.CaptureLog
-
- # Bring render/3 and render_to_string/3 for testing custom views
- import Phoenix.View
-
- test "renders 404.json" do
- assert render(Pleroma.Web.ErrorView, "404.json", []) == %{errors: %{detail: "Page not found"}}
- end
-
- test "render 500.json" do
- assert capture_log(fn ->
- assert render(Pleroma.Web.ErrorView, "500.json", []) ==
- %{errors: %{detail: "Internal server error", reason: "nil"}}
- end) =~ "[error] Internal server error: nil"
- end
-
- test "render any other" do
- assert capture_log(fn ->
- assert render(Pleroma.Web.ErrorView, "505.json", []) ==
- %{errors: %{detail: "Internal server error", reason: "nil"}}
- end) =~ "[error] Internal server error: nil"
- end
-
- test "render 500.json with reason" do
- assert capture_log(fn ->
- assert render(Pleroma.Web.ErrorView, "500.json", reason: "test reason") ==
- %{errors: %{detail: "Internal server error", reason: "\"test reason\""}}
- end) =~ "[error] Internal server error: \"test reason\""
- end
-end
diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs
deleted file mode 100644
index 0023f1e81..000000000
--- a/test/web/web_finger/web_finger_controller_test.exs
+++ /dev/null
@@ -1,94 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
- use Pleroma.Web.ConnCase
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
- import Tesla.Mock
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- setup_all do: clear_config([:instance, :federating], true)
-
- test "GET host-meta" do
- response =
- build_conn()
- |> get("/.well-known/host-meta")
-
- assert response.status == 200
-
- assert response.resp_body ==
- ~s(<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="#{
- Pleroma.Web.base_url()
- }/.well-known/webfinger?resource={uri}" type="application/xrd+xml" /></XRD>)
- end
-
- test "Webfinger JRD" do
- user = insert(:user)
-
- response =
- build_conn()
- |> put_req_header("accept", "application/jrd+json")
- |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost")
-
- assert json_response(response, 200)["subject"] == "acct:#{user.nickname}@localhost"
- end
-
- test "it returns 404 when user isn't found (JSON)" do
- result =
- build_conn()
- |> put_req_header("accept", "application/jrd+json")
- |> get("/.well-known/webfinger?resource=acct:jimm@localhost")
- |> json_response(404)
-
- assert result == "Couldn't find user"
- end
-
- test "Webfinger XML" do
- user = insert(:user)
-
- response =
- build_conn()
- |> put_req_header("accept", "application/xrd+xml")
- |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost")
-
- assert response(response, 200)
- end
-
- test "it returns 404 when user isn't found (XML)" do
- result =
- build_conn()
- |> put_req_header("accept", "application/xrd+xml")
- |> get("/.well-known/webfinger?resource=acct:jimm@localhost")
- |> response(404)
-
- assert result == "Couldn't find user"
- end
-
- test "Sends a 404 when invalid format" do
- user = insert(:user)
-
- 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
- response =
- build_conn()
- |> put_req_header("accept", "application/xrd+xml,application/jrd+json")
- |> get("/.well-known/webfinger")
-
- assert response(response, 400)
- end
-end
diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs
deleted file mode 100644
index 96fc0bbaa..000000000
--- a/test/web/web_finger/web_finger_test.exs
+++ /dev/null
@@ -1,116 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.WebFingerTest do
- use Pleroma.DataCase
- alias Pleroma.Web.WebFinger
- import Pleroma.Factory
- import Tesla.Mock
-
- setup do
- mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- :ok
- end
-
- describe "host meta" do
- test "returns a link to the xml lrdd" do
- host_info = WebFinger.host_meta()
-
- assert String.contains?(host_info, Pleroma.Web.base_url())
- end
- end
-
- describe "incoming webfinger request" do
- test "works for fqns" do
- user = insert(:user)
-
- {:ok, result} =
- WebFinger.webfinger("#{user.nickname}@#{Pleroma.Web.Endpoint.host()}", "XML")
-
- assert is_binary(result)
- end
-
- test "works for ap_ids" do
- user = insert(:user)
-
- {:ok, result} = WebFinger.webfinger(user.ap_id, "XML")
- assert is_binary(result)
- end
- end
-
- describe "fingering" do
- test "returns error for nonsensical input" do
- assert {:error, _} = WebFinger.finger("bliblablu")
- assert {:error, _} = WebFinger.finger("pleroma.social")
- end
-
- test "returns error when fails parse xml or json" do
- user = "invalid_content@social.heldscal.la"
- assert {:error, %Jason.DecodeError{}} = WebFinger.finger(user)
- end
-
- test "returns the ActivityPub actor URI for an ActivityPub user" do
- user = "framasoft@framatube.org"
-
- {:ok, _data} = WebFinger.finger(user)
- end
-
- test "returns the ActivityPub actor URI for an ActivityPub user with the ld+json mimetype" do
- user = "kaniini@gerzilla.de"
-
- {:ok, data} = WebFinger.finger(user)
-
- assert data["ap_id"] == "https://gerzilla.de/channel/kaniini"
- end
-
- test "it work for AP-only user" do
- user = "kpherox@mstdn.jp"
-
- {:ok, data} = WebFinger.finger(user)
-
- assert data["magic_key"] == nil
- assert data["salmon"] == nil
-
- assert data["topic"] == nil
- assert data["subject"] == "acct:kPherox@mstdn.jp"
- assert data["ap_id"] == "https://mstdn.jp/users/kPherox"
- assert data["subscribe_address"] == "https://mstdn.jp/authorize_interaction?acct={uri}"
- end
-
- test "it works for friendica" do
- user = "lain@squeet.me"
-
- {:ok, _data} = WebFinger.finger(user)
- end
-
- test "it gets the xrd endpoint" do
- {:ok, template} = WebFinger.find_lrdd_template("social.heldscal.la")
-
- assert template == "https://social.heldscal.la/.well-known/webfinger?resource={uri}"
- end
-
- test "it gets the xrd endpoint for hubzilla" do
- {:ok, template} = WebFinger.find_lrdd_template("macgirvin.com")
-
- assert template == "https://macgirvin.com/xrd/?uri={uri}"
- end
-
- test "it gets the xrd endpoint for statusnet" do
- {:ok, template} = WebFinger.find_lrdd_template("status.alpicola.com")
-
- assert template == "http://status.alpicola.com/main/xrd?uri={uri}"
- end
-
- test "it works with idna domains as nickname" do
- nickname = "lain@" <> to_string(:idna.encode("zetsubou.みんな"))
-
- {:ok, _data} = WebFinger.finger(nickname)
- end
-
- test "it works with idna domains as link" do
- ap_id = "https://" <> to_string(:idna.encode("zetsubou.みんな")) <> "/users/lain"
- {:ok, _data} = WebFinger.finger(ap_id)
- end
- end
-end