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.exs1534
-rw-r--r--test/web/activity_pub/activity_pub_test.exs2102
-rw-r--r--test/web/activity_pub/mrf/activity_expiration_policy_test.exs77
-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.exs82
-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.exs106
-rw-r--r--test/web/activity_pub/mrf/reject_non_public_test.exs100
-rw-r--r--test/web/activity_pub/mrf/simple_policy_test.exs479
-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/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/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.exs622
-rw-r--r--test/web/activity_pub/transmogrifier/announce_handling_test.exs172
-rw-r--r--test/web/activity_pub/transmogrifier/block_handling_test.exs63
-rw-r--r--test/web/activity_pub/transmogrifier/chat_message_test.exs153
-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/follow_handling_test.exs189
-rw-r--r--test/web/activity_pub/transmogrifier/like_handling_test.exs78
-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.exs1654
-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.exs1786
-rw-r--r--test/web/admin_api/controllers/config_controller_test.exs1396
-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.exs145
-rw-r--r--test/web/admin_api/controllers/oauth_app_controller_test.exs220
-rw-r--r--test/web/admin_api/controllers/relay_controller_test.exs92
-rw-r--r--test/web/admin_api/controllers/report_controller_test.exs374
-rw-r--r--test/web/admin_api/controllers/status_controller_test.exs202
-rw-r--r--test/web/admin_api/search_test.exs170
-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.exs1124
-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.exs184
-rw-r--r--test/web/feed/user_controller_test.exs238
-rw-r--r--test/web/instances/instance_test.exs100
-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.exs525
-rw-r--r--test/web/mastodon_api/controllers/account_controller_test.exs1399
-rw-r--r--test/web/mastodon_api/controllers/app_controller_test.exs60
-rw-r--r--test/web/mastodon_api/controllers/auth_controller_test.exs152
-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.exs129
-rw-r--r--test/web/mastodon_api/controllers/follow_request_controller_test.exs74
-rw-r--r--test/web/mastodon_api/controllers/instance_controller_test.exs86
-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.exs1654
-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.exs495
-rw-r--r--test/web/mastodon_api/mastodon_api_controller_test.exs34
-rw-r--r--test/web/mastodon_api/mastodon_api_test.exs104
-rw-r--r--test/web/mastodon_api/views/account_view_test.exs570
-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.exs138
-rw-r--r--test/web/mastodon_api/views/scheduled_activity_view_test.exs68
-rw-r--r--test/web/mastodon_api/views/status_view_test.exs658
-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.exs25
-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.exs22
-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.exs33
-rw-r--r--test/web/oauth/authorization_test.exs77
-rw-r--r--test/web/oauth/ldap_authorization_test.exs182
-rw-r--r--test/web/oauth/mfa_controller_test.exs306
-rw-r--r--test/web/oauth/oauth_controller_test.exs1205
-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.exs358
-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.exs132
-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.exs61
-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.exs74
-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.exs137
-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.exs396
-rw-r--r--test/web/twitter_api/util_controller_test.exs595
-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.exs111
170 files changed, 0 insertions, 38369 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 ed900d8f8..000000000
--- a/test/web/activity_pub/activity_pub_controller_test.exs
+++ /dev/null
@@ -1,1534 +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, ["relay.mastodon.host"]}
- 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
- [
- 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
- 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 d6eab7337..000000000
--- a/test/web/activity_pub/activity_pub_test.exs
+++ /dev/null
@@ -1,2102 +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
- test "copies the file to the configured folder" 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)
- 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 == []
- 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 8babf49e7..000000000
--- a/test/web/activity_pub/mrf/activity_expiration_policy_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.ActivityPub.MRF.ActivityExpirationPolicyTest do
- use ExUnit.Case, async: true
- alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
-
- @id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
-
- test "adds `expires_at` property" do
- assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
- ActivityExpirationPolicy.filter(%{
- "id" => @id,
- "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,
- "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,
- "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",
- "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",
- "type" => "Follow"
- })
-
- refute Map.has_key?(activity, "expires_at")
-
- assert {:ok, activity} =
- ActivityExpirationPolicy.filter(%{
- "id" => "https://example.com/123",
- "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 38ddec5bb..000000000
--- a/test/web/activity_pub/mrf/ensure_re_prepended_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.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
- 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 b0fb753bd..000000000
--- a/test/web/activity_pub/mrf/object_age_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.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 "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 "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 "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 e842d8d8d..000000000
--- a/test/web/activity_pub/mrf/simple_policy_test.exs
+++ /dev/null
@@ -1,479 +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
-
- setup do:
- clear_config(:mrf_simple,
- media_removal: [],
- media_nsfw: [],
- federated_timeline_removal: [],
- report_removal: [],
- reject: [],
- 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 :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/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 42cd18298..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 delete object", []}} in cng.errors
- end
-
- test "it's valid if the actor of the object is a local superuser",
- %{valid_post_delete: valid_post_delete} do
- user =
- insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo")
-
- valid_other_actor =
- valid_post_delete
- |> Map.put("actor", user.ap_id)
-
- {:ok, _, meta} = ObjectValidator.validate(valid_other_actor, [])
- assert meta[:do_not_federate]
- end
- end
-end
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/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 f2a231eaf..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,
- [],
- [filter: fn o -> {:ok, o} 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.filter(activity))
- 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,
- [],
- [filter: fn o -> {:ok, o} 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.filter(activity))
- 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,
- [],
- [filter: fn o -> {:ok, o} 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.filter(activity))
- 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,
- [],
- [filter: fn o -> {:ok, o} 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.filter(activity))
- 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 4a08eb7ee..000000000
--- a/test/web/activity_pub/side_effects_test.exs
+++ /dev/null
@@ -1,622 +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 Pleroma.Factory
- import Mock
-
- 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
- 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/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/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 d6736dc3e..000000000
--- a/test/web/activity_pub/transmogrifier/chat_message_test.exs
+++ /dev/null
@@ -1,153 +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 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/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
deleted file mode 100644
index 17e764ca1..000000000
--- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs
+++ /dev/null
@@ -1,189 +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
- 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/undo_handling_test.exs b/test/web/activity_pub/transmogrifier/undo_handling_test.exs
deleted file mode 100644
index 01dd6c370..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 incomming 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 7d33feaf2..000000000
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ /dev/null
@@ -1,1654 +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 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 questions" 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)
-
- assert Enum.all?(object.data["oneOf"], fn choice ->
- choice["name"] in [
- "Dunno",
- "Everyone knows that!",
- "25 char limit is dumb",
- "I can't even fit a funny"
- ]
- end)
- end
-
- test "it works for incoming listens" do
- data = %{
- "@context" => "https://www.w3.org/ns/activitystreams",
- "to" => ["https://www.w3.org/ns/activitystreams#Public"],
- "cc" => [],
- "type" => "Listen",
- "id" => "http://mastodon.example.org/users/admin/listens/1234/activity",
- "actor" => "http://mastodon.example.org/users/admin",
- "object" => %{
- "type" => "Audio",
- "id" => "http://mastodon.example.org/users/admin/listens/1234",
- "attributedTo" => "http://mastodon.example.org/users/admin",
- "title" => "lain radio episode 1",
- "artist" => "lain",
- "album" => "lain radio",
- "length" => 180_000
- }
- }
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- object = Object.normalize(activity)
-
- assert object.data["title"] == "lain radio episode 1"
- assert object.data["artist"] == "lain"
- assert object.data["album"] == "lain radio"
- assert object.data["length"] == 180_000
- end
-
- test "it rewrites Note votes to Answers and increments vote counters on question activities" do
- user = insert(:user)
-
- {: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"
- object = Object.get_by_ap_id(object.data["id"])
-
- assert Enum.any?(
- object.data["oneOf"],
- fn
- %{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true
- _ -> false
- end
- )
- 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 incomming 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 "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
-
- 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 were orphaned" 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)
-
- accept_data =
- Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_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
- 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
-
- 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 orphaned" 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)
-
- reject_data =
- Map.put(reject_data, "object", Map.put(reject_data["object"], "actor", follower.ap_id))
-
- {:ok, activity} = Transmogrifier.handle_incoming(reject_data)
- refute activity.local
- assert activity.data["id"] == reject_data["id"]
-
- follower = User.get_cached_by_id(follower.id)
-
- assert User.following?(follower, followed) == false
- 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
-
- 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"
- }
- ]
- }
- ]
-
- {:ok, object} =
- Fetcher.fetch_object_from_id(
- "https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
- )
-
- assert object.data["attachment"] == [
- %{
- "type" => "Link",
- "mediaType" => "video/mp4",
- "url" => [
- %{
- "href" =>
- "https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4",
- "mediaType" => "video/mp4"
- }
- ]
- }
- ]
-
- assert object.data["url"] ==
- "https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
- end
-
- test "it accepts Flag activities" do
- 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
-
- test "Rewrites Answers to Notes" 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
-
- 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",
- "url" => [
- %{"href" => "https://peertube.moe/stat-480.mp4", "mediaType" => "video/mp4"}
- ]
- }
- ]
- }
- end
-
- test "returns modified object when attachment is list" do
- assert Transmogrifier.fix_attachments(%{
- "attachment" => [
- %{"mediaType" => "video/mp4", "url" => "https://pe.er/stat-480.mp4"},
- %{"mimeType" => "video/mp4", "href" => "https://pe.er/stat-480.mp4"}
- ]
- }) == %{
- "attachment" => [
- %{
- "mediaType" => "video/mp4",
- "url" => [
- %{"href" => "https://pe.er/stat-480.mp4", "mediaType" => "video/mp4"}
- ]
- },
- %{
- "mediaType" => "video/mp4",
- "url" => [
- %{"href" => "https://pe.er/stat-480.mp4", "mediaType" => "video/mp4"}
- ]
- }
- ]
- }
- 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 6082441ee..000000000
--- a/test/web/admin_api/controllers/admin_api_controller_test.exs
+++ /dev/null
@@ -1,1786 +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
- user = insert(:user)
- clear_config([:instance, :federating], true)
-
- with_mock Pleroma.Web.Federator,
- publish: 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]
-
- 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,
- "url" => user.ap_id
- }
-
- 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 json_response(conn, :no_content)
- assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
- assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
-
- log_entry = Repo.one(ModerationLog)
-
- users =
- [user1.nickname, user2.nickname]
- |> Enum.map(&"@#{&1}")
- |> Enum.join(", ")
-
- tags = ["foo", "bar"] |> Enum.join(", ")
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} added tags: #{tags} to users: #{users}"
- end
-
- test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
- assert json_response(conn, :no_content)
- 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 json_response(conn, :no_content)
- assert User.get_cached_by_id(user1.id).tags == []
- assert User.get_cached_by_id(user2.id).tags == ["y"]
-
- log_entry = Repo.one(ModerationLog)
-
- users =
- [user1.nickname, user2.nickname]
- |> Enum.map(&"@#{&1}")
- |> Enum.join(", ")
-
- tags = ["x", "z"] |> Enum.join(", ")
-
- assert ModerationLog.get_log_entry_message(log_entry) ==
- "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
- end
-
- test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
- assert json_response(conn, :no_content)
- 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"])
- 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,
- "url" => admin.ap_id
- },
- %{
- "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,
- "url" => user.ap_id
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 2,
- "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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
-
- 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,
- "url" => user2.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => user.ap_id
- },
- %{
- "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,
- "url" => admin.ap_id
- },
- %{
- "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,
- "url" => old_admin.ap_id
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 3,
- "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,
- "url" => admin.ap_id
- },
- %{
- "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,
- "url" => second_admin.ap_id
- }
- ]
- |> 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,
- "url" => moderator.ap_id
- }
- ]
- }
- 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,
- "url" => user1.ap_id
- },
- %{
- "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,
- "url" => user2.ap_id
- }
- ]
- |> Enum.sort_by(& &1["nickname"])
-
- assert json_response(conn, 200) == %{
- "count" => 2,
- "page_size" => 50,
- "users" => users
- }
- 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,
- "url" => user.ap_id
- }
- ]
- }
- 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,
- "url" => admin.ap_id
- }
- ]
- }
- 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/: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,
- "url" => user.ap_id
- }
-
- 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 json_response(conn, 204) == ""
-
- 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 61bc9fd39..000000000
--- a/test/web/admin_api/controllers/config_controller_test.exs
+++ /dev/null
@@ -1,1396 +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
- 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 5ab6cb78a..000000000
--- a/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs
+++ /dev/null
@@ -1,145 +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["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"
- ]
-
- 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
- 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"
- ])
-
- response =
- 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)
-
- assert response["urls"] == ["http://localhost:4001/media/a688346.jpg"]
- 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
- response =
- 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)
-
- assert response["urls"] == urls
-
- 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
- response =
- 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 response["urls"] == urls
-
- 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 64086adc5..000000000
--- a/test/web/admin_api/controllers/relay_controller_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.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) ==
- "http://mastodon.example.org/users/admin"
-
- 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"] --
- ["mastodon.example.org", "mstdn.io"] == []
- 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 f30dc8956..000000000
--- a/test/web/admin_api/controllers/report_controller_test.exs
+++ /dev/null
@@ -1,374 +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("/api/pleroma/admin/reports")
- |> 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("/api/pleroma/admin/reports")
- |> 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("/api/pleroma/admin/reports?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("/api/pleroma/admin/reports?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("/api/pleroma/admin/reports?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 e0e3d4153..000000000
--- a/test/web/admin_api/search_test.exs
+++ /dev/null
@@ -1,170 +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
- 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 313dda21b..000000000
--- a/test/web/common_api/common_api_test.exs
+++ /dev/null
@@ -1,1124 +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
- 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 "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 3c29cd94f..000000000
--- a/test/web/feed/tag_controller_test.exs
+++ /dev/null
@@ -1,184 +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
-end
diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs
deleted file mode 100644
index fa2ed1ea5..000000000
--- a/test/web/feed/user_controller_test.exs
+++ /dev/null
@@ -1,238 +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
- 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
-end
diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs
deleted file mode 100644
index e463200ca..000000000
--- a/test/web/instances/instance_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.Instances.InstanceTest do
- alias Pleroma.Instances.Instance
- alias Pleroma.Repo
-
- use Pleroma.DataCase
-
- 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
-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 b888e4c71..000000000
--- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
+++ /dev/null
@@ -1,525 +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"
- 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 c304487ea..000000000
--- a/test/web/mastodon_api/controllers/account_controller_test.exs
+++ /dev/null
@@ -1,1399 +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.Config
- 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
- setup do: clear_config([:instance, :limit_to_local_content])
-
- 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
- Config.put([: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
- Config.put([: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
- Config.put([:instance, :limit_to_local_content], :unauthenticated)
-
- user = insert(:user, nickname: "user@example.com", local: false)
- reading_user = insert(:user)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
-
- assert json_response_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
-
- setup do: clear_config([:instance, :account_activation_required])
-
- test "Account registration via Application", %{conn: conn} do
- 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
- })
-
- %{
- "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
-
- assert token_from_db.user.confirmation_pending
- end
-
- test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
- _user = insert(:user, email: "lain@example.org")
- app_token = insert(:oauth_token, user: nil)
-
- 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
-
- setup do: clear_config([:instance, :account_activation_required])
-
- test "returns bad_request if missing email params when :account_activation_required is enabled",
- %{conn: conn, valid_params: valid_params} do
- Pleroma.Config.put([: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
-
- assert token_from_db.user.confirmation_pending
- 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 a485f8e41..000000000
--- a/test/web/mastodon_api/controllers/auth_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.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 404 when user is not found", %{conn: conn, user: user} do
- conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
- assert conn.status == 404
- assert conn.resp_body == ""
- end
-
- test "it returns 400 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.status == 400
- assert conn.resp_body == ""
- 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 f29547d13..000000000
--- a/test/web/mastodon_api/controllers/filter_controller_test.exs
+++ /dev/null
@@ -1,129 +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"])
-
- query = %Pleroma.Filter{
- user_id: user.id,
- filter_id: 2,
- phrase: "knight",
- context: ["home"]
- }
-
- {:ok, filter} = Pleroma.Filter.create(query)
-
- conn = get(conn, "/api/v1/filters/#{filter.filter_id}")
-
- assert response = json_response_and_validate_schema(conn, 200)
- 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
- }
-
- {: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
- 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 cc880d82c..000000000
--- a/test/web/mastodon_api/controllers/instance_controller_test.exs
+++ /dev/null
@@ -1,86 +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" => _,
- "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 d34f300da..000000000
--- a/test/web/mastodon_api/controllers/status_controller_test.exs
+++ /dev/null
@@ -1,1654 +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 "posting a status with OGP link preview", %{conn: conn} do
- Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
- Config.put([:rich_media, :enabled], true)
-
- conn =
- conn
- |> 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
- 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 50e0d783d..000000000
--- a/test/web/mastodon_api/controllers/timeline_controller_test.exs
+++ /dev/null
@@ -1,495 +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 "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 `%{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 c08be37d4..000000000
--- a/test/web/mastodon_api/mastodon_api_test.exs
+++ /dev/null
@@ -1,104 +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)
- {:error, error} = MastodonAPI.follow(follower, user)
- assert error == :rejected
- 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 8f37efa3c..000000000
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ /dev/null
@@ -1,570 +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.Config
- 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
-
- setup do: clear_config([:instances_favicons, :enabled])
-
- 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:
- "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
- 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 "Favicon is nil when :instances_favicons is disabled" do
- user = insert(:user)
-
- Config.put([:instances_favicons, :enabled], true)
-
- assert %{
- pleroma: %{
- favicon:
- "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png"
- }
- } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
-
- Config.put([:instances_favicons, :enabled], false)
-
- assert %{pleroma: %{favicon: nil}} =
- AccountView.render("show.json", %{user: user, skip_visibility_check: true})
- 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:
- "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
- 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 8e0e58538..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: false, 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 76672f36c..000000000
--- a/test/web/mastodon_api/views/poll_view_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.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
-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 8703d5ba7..000000000
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ /dev/null
@@ -1,658 +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)
- 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 3f8b29e58..000000000
--- a/test/web/metadata/metadata_test.exs
+++ /dev/null
@@ -1,25 +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
-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 4107a8459..000000000
--- a/test/web/metadata/rel_me_test.exs
+++ /dev/null
@@ -1,22 +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 899af648e..000000000
--- a/test/web/oauth/app_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.OAuth.AppTest do
- use Pleroma.DataCase
-
- alias Pleroma.Web.OAuth.App
- import Pleroma.Factory
-
- describe "get_or_make/2" do
- test "gets exist app" do
- attrs = %{client_name: "Mastodon-Local", redirect_uris: "."}
- app = insert(:oauth_app, Map.merge(attrs, %{scopes: ["read", "write"]}))
- {:ok, %App{} = exist_app} = App.get_or_make(attrs, [])
- assert exist_app == app
- end
-
- test "make app" do
- attrs = %{client_name: "Mastodon-Local", redirect_uris: "."}
- {:ok, %App{} = app} = App.get_or_make(attrs, ["write"])
- assert app.scopes == ["write"]
- end
-
- test "gets exist app and updates scopes" do
- attrs = %{client_name: "Mastodon-Local", redirect_uris: "."}
- app = insert(:oauth_app, Map.merge(attrs, %{scopes: ["read", "write"]}))
- {:ok, %App{} = exist_app} = App.get_or_make(attrs, ["read", "write", "follow", "push"])
- assert exist_app.id == app.id
- assert exist_app.scopes == ["read", "write", "follow", "push"]
- end
- end
-end
diff --git a/test/web/oauth/authorization_test.exs b/test/web/oauth/authorization_test.exs
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 011642c08..000000000
--- a/test/web/oauth/ldap_authorization_test.exs
+++ /dev/null
@@ -1,182 +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 ExUnit.CaptureLog
- 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, '', [{'mail', [to_charlist(user.email)]}]}],
- []}}
- 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 "falls back to the default authorization when LDAP is unavailable" 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} | _] -> {:error, 'connect failed'} end,
- simple_bind: fn _connection, _dn, ^password -> :ok end,
- close: fn _connection ->
- send(self(), :close_connection)
- :ok
- end
- ]}
- ] do
- log =
- capture_log(fn ->
- 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
- end)
-
- assert log =~ "Could not open LDAP connection: 'connect failed'"
- refute_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 d389e4ce0..000000000
--- a/test/web/oauth/oauth_controller_test.exs
+++ /dev/null
@@ -1,1205 +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])
-
- 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 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 d71e80d03..000000000
--- a/test/web/pleroma_api/controllers/chat_controller_test.exs
+++ /dev/null
@@ -1,358 +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 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
- 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 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 e1bb5ebfe..000000000
--- a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
+++ /dev/null
@@ -1,132 +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/: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 e5b165255..000000000
--- a/test/web/pleroma_api/views/chat/message_reference_view_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.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])
-
- {:ok, activity} = CommonAPI.post_chat_message(recipient, user, "gkgkgk", 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] == "gkgkgk"
- 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
- 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 fea95a6a4..000000000
--- a/test/web/preload/timeline_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.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
- svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
- Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{local: true, federated: true})
-
- on_exit(fn ->
- Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
- end)
-
- :ok
- end
-
- 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
- svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
-
- Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{
- local: false,
- federated: false
- })
-
- on_exit(fn ->
- Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
- end)
-
- {:ok, user: insert(:user)}
- end
-
- 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 b30f4400e..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 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({:ok, 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 420a612c6..000000000
--- a/test/web/rich_media/parser_test.exs
+++ /dev/null
@@ -1,137 +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
-
- 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"}
- end)
-
- :ok
- end
-
- test "returns error when no metadata present" do
- assert {:error, _} = Pleroma.Web.RichMedia.Parser.parse("http://example.com/empty")
- end
-
- test "doesn't just add a title" do
- assert Pleroma.Web.RichMedia.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 Pleroma.Web.RichMedia.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 Pleroma.Web.RichMedia.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 Pleroma.Web.RichMedia.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 Pleroma.Web.RichMedia.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, _} = Pleroma.Web.RichMedia.Parser.parse("http://example.com/malformed")
- 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 5bb2d8d89..000000000
--- a/test/web/twitter_api/twitter_api_test.exs
+++ /dev/null
@@ -1,396 +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
-
- 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 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 109c1e637..000000000
--- a/test/web/twitter_api/util_controller_test.exs
+++ /dev/null
@@ -1,595 +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} do
- conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"})
-
- assert json_response(conn, 200) == %{"status" => "success"}
- 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 f4884e0a2..000000000
--- a/test/web/web_finger/web_finger_test.exs
+++ /dev/null
@@ -1,111 +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 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