1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
6 use Pleroma.Web.ConnCase
7 use Oban.Testing, repo: Pleroma.Repo
11 alias Pleroma.ModerationLog
13 alias Pleroma.Tests.ObanHelpers
15 alias Pleroma.UserInviteToken
16 alias Pleroma.Web.ActivityPub.Relay
17 alias Pleroma.Web.CommonAPI
18 alias Pleroma.Web.MastodonAPI.StatusView
19 alias Pleroma.Web.MediaProxy
20 import Pleroma.Factory
23 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
28 clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
29 Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
32 describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
33 clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
34 Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
37 test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope" do
39 admin = insert(:user, is_admin: true)
40 url = "/api/pleroma/admin/users/#{user.nickname}"
42 good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
43 good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
44 good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
46 bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
47 bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
50 for good_token <- [good_token1, good_token2, good_token3] do
53 |> assign(:user, admin)
54 |> assign(:token, good_token)
57 assert json_response(conn, 200)
60 for good_token <- [good_token1, good_token2, good_token3] do
64 |> assign(:token, good_token)
67 assert json_response(conn, :forbidden)
70 for bad_token <- [bad_token1, bad_token2, bad_token3] do
73 |> assign(:user, admin)
74 |> assign(:token, bad_token)
77 assert json_response(conn, :forbidden)
82 describe "DELETE /api/pleroma/admin/users" do
84 admin = insert(:user, is_admin: true)
89 |> assign(:user, admin)
90 |> put_req_header("accept", "application/json")
91 |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
93 log_entry = Repo.one(ModerationLog)
95 assert ModerationLog.get_log_entry_message(log_entry) ==
96 "@#{admin.nickname} deleted users: @#{user.nickname}"
98 assert json_response(conn, 200) == user.nickname
101 test "multiple users" do
102 admin = insert(:user, is_admin: true)
103 user_one = insert(:user)
104 user_two = insert(:user)
108 |> assign(:user, admin)
109 |> put_req_header("accept", "application/json")
110 |> delete("/api/pleroma/admin/users", %{
111 nicknames: [user_one.nickname, user_two.nickname]
114 log_entry = Repo.one(ModerationLog)
116 assert ModerationLog.get_log_entry_message(log_entry) ==
117 "@#{admin.nickname} deleted users: @#{user_one.nickname}, @#{user_two.nickname}"
119 response = json_response(conn, 200)
120 assert response -- [user_one.nickname, user_two.nickname] == []
124 describe "/api/pleroma/admin/users" do
126 admin = insert(:user, is_admin: true)
130 |> assign(:user, admin)
131 |> put_req_header("accept", "application/json")
132 |> post("/api/pleroma/admin/users", %{
135 "nickname" => "lain",
136 "email" => "lain@example.org",
140 "nickname" => "lain2",
141 "email" => "lain2@example.org",
147 response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
148 assert response == ["success", "success"]
150 log_entry = Repo.one(ModerationLog)
152 assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
155 test "Cannot create user with existing email" do
156 admin = insert(:user, is_admin: true)
161 |> assign(:user, admin)
162 |> put_req_header("accept", "application/json")
163 |> post("/api/pleroma/admin/users", %{
166 "nickname" => "lain",
167 "email" => user.email,
173 assert json_response(conn, 409) == [
177 "email" => user.email,
180 "error" => "email has already been taken",
186 test "Cannot create user with existing nickname" do
187 admin = insert(:user, is_admin: true)
192 |> assign(:user, admin)
193 |> put_req_header("accept", "application/json")
194 |> post("/api/pleroma/admin/users", %{
197 "nickname" => user.nickname,
198 "email" => "someuser@plerama.social",
204 assert json_response(conn, 409) == [
208 "email" => "someuser@plerama.social",
209 "nickname" => user.nickname
211 "error" => "nickname has already been taken",
217 test "Multiple user creation works in transaction" do
218 admin = insert(:user, is_admin: true)
223 |> assign(:user, admin)
224 |> put_req_header("accept", "application/json")
225 |> post("/api/pleroma/admin/users", %{
228 "nickname" => "newuser",
229 "email" => "newuser@pleroma.social",
233 "nickname" => "lain",
234 "email" => user.email,
240 assert json_response(conn, 409) == [
244 "email" => user.email,
247 "error" => "email has already been taken",
253 "email" => "newuser@pleroma.social",
254 "nickname" => "newuser"
261 assert User.get_by_nickname("newuser") === nil
265 describe "/api/pleroma/admin/users/:nickname" do
266 test "Show", %{conn: conn} do
267 admin = insert(:user, is_admin: true)
272 |> assign(:user, admin)
273 |> get("/api/pleroma/admin/users/#{user.nickname}")
276 "deactivated" => false,
277 "id" => to_string(user.id),
279 "nickname" => user.nickname,
280 "roles" => %{"admin" => false, "moderator" => false},
282 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
283 "display_name" => HTML.strip_tags(user.name || user.nickname),
284 "confirmation_pending" => false
287 assert expected == json_response(conn, 200)
290 test "when the user doesn't exist", %{conn: conn} do
291 admin = insert(:user, is_admin: true)
296 |> assign(:user, admin)
297 |> get("/api/pleroma/admin/users/#{user.nickname}")
299 assert "Not found" == json_response(conn, 404)
303 describe "/api/pleroma/admin/users/follow" do
304 test "allows to force-follow another user" do
305 admin = insert(:user, is_admin: true)
307 follower = insert(:user)
310 |> assign(:user, admin)
311 |> put_req_header("accept", "application/json")
312 |> post("/api/pleroma/admin/users/follow", %{
313 "follower" => follower.nickname,
314 "followed" => user.nickname
317 user = User.get_cached_by_id(user.id)
318 follower = User.get_cached_by_id(follower.id)
320 assert User.following?(follower, user)
322 log_entry = Repo.one(ModerationLog)
324 assert ModerationLog.get_log_entry_message(log_entry) ==
325 "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
329 describe "/api/pleroma/admin/users/unfollow" do
330 test "allows to force-unfollow another user" do
331 admin = insert(:user, is_admin: true)
333 follower = insert(:user)
335 User.follow(follower, user)
338 |> assign(:user, admin)
339 |> put_req_header("accept", "application/json")
340 |> post("/api/pleroma/admin/users/unfollow", %{
341 "follower" => follower.nickname,
342 "followed" => user.nickname
345 user = User.get_cached_by_id(user.id)
346 follower = User.get_cached_by_id(follower.id)
348 refute User.following?(follower, user)
350 log_entry = Repo.one(ModerationLog)
352 assert ModerationLog.get_log_entry_message(log_entry) ==
353 "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
357 describe "PUT /api/pleroma/admin/users/tag" do
359 admin = insert(:user, is_admin: true)
360 user1 = insert(:user, %{tags: ["x"]})
361 user2 = insert(:user, %{tags: ["y"]})
362 user3 = insert(:user, %{tags: ["unchanged"]})
366 |> assign(:user, admin)
367 |> put_req_header("accept", "application/json")
369 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
371 }&tags[]=foo&tags[]=bar"
374 %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
377 test "it appends specified tags to users with specified nicknames", %{
383 assert json_response(conn, :no_content)
384 assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
385 assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
387 log_entry = Repo.one(ModerationLog)
390 [user1.nickname, user2.nickname]
391 |> Enum.map(&"@#{&1}")
394 tags = ["foo", "bar"] |> Enum.join(", ")
396 assert ModerationLog.get_log_entry_message(log_entry) ==
397 "@#{admin.nickname} added tags: #{tags} to users: #{users}"
400 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
401 assert json_response(conn, :no_content)
402 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
406 describe "DELETE /api/pleroma/admin/users/tag" do
408 admin = insert(:user, is_admin: true)
409 user1 = insert(:user, %{tags: ["x"]})
410 user2 = insert(:user, %{tags: ["y", "z"]})
411 user3 = insert(:user, %{tags: ["unchanged"]})
415 |> assign(:user, admin)
416 |> put_req_header("accept", "application/json")
418 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
423 %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
426 test "it removes specified tags from users with specified nicknames", %{
432 assert json_response(conn, :no_content)
433 assert User.get_cached_by_id(user1.id).tags == []
434 assert User.get_cached_by_id(user2.id).tags == ["y"]
436 log_entry = Repo.one(ModerationLog)
439 [user1.nickname, user2.nickname]
440 |> Enum.map(&"@#{&1}")
443 tags = ["x", "z"] |> Enum.join(", ")
445 assert ModerationLog.get_log_entry_message(log_entry) ==
446 "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
449 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
450 assert json_response(conn, :no_content)
451 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
455 describe "/api/pleroma/admin/users/:nickname/permission_group" do
456 test "GET is giving user_info" do
457 admin = insert(:user, is_admin: true)
461 |> assign(:user, admin)
462 |> put_req_header("accept", "application/json")
463 |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
465 assert json_response(conn, 200) == %{
467 "is_moderator" => false
471 test "/:right POST, can add to a permission group" do
472 admin = insert(:user, is_admin: true)
477 |> assign(:user, admin)
478 |> put_req_header("accept", "application/json")
479 |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
481 assert json_response(conn, 200) == %{
485 log_entry = Repo.one(ModerationLog)
487 assert ModerationLog.get_log_entry_message(log_entry) ==
488 "@#{admin.nickname} made @#{user.nickname} admin"
491 test "/:right POST, can add to a permission group (multiple)" do
492 admin = insert(:user, is_admin: true)
493 user_one = insert(:user)
494 user_two = insert(:user)
498 |> assign(:user, admin)
499 |> put_req_header("accept", "application/json")
500 |> post("/api/pleroma/admin/users/permission_group/admin", %{
501 nicknames: [user_one.nickname, user_two.nickname]
504 assert json_response(conn, 200) == %{
508 log_entry = Repo.one(ModerationLog)
510 assert ModerationLog.get_log_entry_message(log_entry) ==
511 "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin"
514 test "/:right DELETE, can remove from a permission group" do
515 admin = insert(:user, is_admin: true)
516 user = insert(:user, is_admin: true)
520 |> assign(:user, admin)
521 |> put_req_header("accept", "application/json")
522 |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
524 assert json_response(conn, 200) == %{
528 log_entry = Repo.one(ModerationLog)
530 assert ModerationLog.get_log_entry_message(log_entry) ==
531 "@#{admin.nickname} revoked admin role from @#{user.nickname}"
534 test "/:right DELETE, can remove from a permission group (multiple)" do
535 admin = insert(:user, is_admin: true)
536 user_one = insert(:user, is_admin: true)
537 user_two = insert(:user, is_admin: true)
541 |> assign(:user, admin)
542 |> put_req_header("accept", "application/json")
543 |> delete("/api/pleroma/admin/users/permission_group/admin", %{
544 nicknames: [user_one.nickname, user_two.nickname]
547 assert json_response(conn, 200) == %{
551 log_entry = Repo.one(ModerationLog)
553 assert ModerationLog.get_log_entry_message(log_entry) ==
554 "@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{
560 describe "POST /api/pleroma/admin/email_invite, with valid config" do
562 [user: insert(:user, is_admin: true)]
565 clear_config([:instance, :registrations_open]) do
566 Pleroma.Config.put([:instance, :registrations_open], false)
569 clear_config([:instance, :invites_enabled]) do
570 Pleroma.Config.put([:instance, :invites_enabled], true)
573 test "sends invitation and returns 204", %{conn: conn, user: user} do
574 recipient_email = "foo@bar.com"
575 recipient_name = "J. D."
579 |> assign(:user, user)
581 "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
584 assert json_response(conn, :no_content)
586 token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
588 refute token_record.used
590 notify_email = Pleroma.Config.get([:instance, :notify_email])
591 instance_name = Pleroma.Config.get([:instance, :name])
594 Pleroma.Emails.UserEmail.user_invitation_email(
601 Swoosh.TestAssertions.assert_email_sent(
602 from: {instance_name, notify_email},
603 to: {recipient_name, recipient_email},
604 html_body: email.html_body
608 test "it returns 403 if requested by a non-admin", %{conn: conn} do
609 non_admin_user = insert(:user)
613 |> assign(:user, non_admin_user)
614 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
616 assert json_response(conn, :forbidden)
620 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
622 [user: insert(:user, is_admin: true)]
625 clear_config([:instance, :registrations_open])
626 clear_config([:instance, :invites_enabled])
628 test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do
629 Pleroma.Config.put([:instance, :registrations_open], false)
630 Pleroma.Config.put([:instance, :invites_enabled], false)
634 |> assign(:user, user)
635 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
637 assert json_response(conn, :internal_server_error)
640 test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do
641 Pleroma.Config.put([:instance, :registrations_open], true)
642 Pleroma.Config.put([:instance, :invites_enabled], true)
646 |> assign(:user, user)
647 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
649 assert json_response(conn, :internal_server_error)
653 test "/api/pleroma/admin/users/:nickname/password_reset" do
654 admin = insert(:user, is_admin: true)
659 |> assign(:user, admin)
660 |> put_req_header("accept", "application/json")
661 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
663 resp = json_response(conn, 200)
665 assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
668 describe "GET /api/pleroma/admin/users" do
670 admin = insert(:user, is_admin: true)
674 |> assign(:user, admin)
676 {:ok, conn: conn, admin: admin}
679 test "renders users array for the first page", %{conn: conn, admin: admin} do
680 user = insert(:user, local: false, tags: ["foo", "bar"])
681 conn = get(conn, "/api/pleroma/admin/users?page=1")
686 "deactivated" => admin.deactivated,
688 "nickname" => admin.nickname,
689 "roles" => %{"admin" => true, "moderator" => false},
692 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
693 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
694 "confirmation_pending" => false
697 "deactivated" => user.deactivated,
699 "nickname" => user.nickname,
700 "roles" => %{"admin" => false, "moderator" => false},
702 "tags" => ["foo", "bar"],
703 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
704 "display_name" => HTML.strip_tags(user.name || user.nickname),
705 "confirmation_pending" => false
708 |> Enum.sort_by(& &1["nickname"])
710 assert json_response(conn, 200) == %{
717 test "renders empty array for the second page", %{conn: conn} do
720 conn = get(conn, "/api/pleroma/admin/users?page=2")
722 assert json_response(conn, 200) == %{
729 test "regular search", %{conn: conn} do
730 user = insert(:user, nickname: "bob")
732 conn = get(conn, "/api/pleroma/admin/users?query=bo")
734 assert json_response(conn, 200) == %{
739 "deactivated" => user.deactivated,
741 "nickname" => user.nickname,
742 "roles" => %{"admin" => false, "moderator" => false},
745 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
746 "display_name" => HTML.strip_tags(user.name || user.nickname),
747 "confirmation_pending" => false
753 test "search by domain", %{conn: conn} do
754 user = insert(:user, nickname: "nickname@domain.com")
757 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
759 assert json_response(conn, 200) == %{
764 "deactivated" => user.deactivated,
766 "nickname" => user.nickname,
767 "roles" => %{"admin" => false, "moderator" => false},
770 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
771 "display_name" => HTML.strip_tags(user.name || user.nickname),
772 "confirmation_pending" => false
778 test "search by full nickname", %{conn: conn} do
779 user = insert(:user, nickname: "nickname@domain.com")
782 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
784 assert json_response(conn, 200) == %{
789 "deactivated" => user.deactivated,
791 "nickname" => user.nickname,
792 "roles" => %{"admin" => false, "moderator" => false},
795 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
796 "display_name" => HTML.strip_tags(user.name || user.nickname),
797 "confirmation_pending" => false
803 test "search by display name", %{conn: conn} do
804 user = insert(:user, name: "Display name")
807 conn = get(conn, "/api/pleroma/admin/users?name=display")
809 assert json_response(conn, 200) == %{
814 "deactivated" => user.deactivated,
816 "nickname" => user.nickname,
817 "roles" => %{"admin" => false, "moderator" => false},
820 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
821 "display_name" => HTML.strip_tags(user.name || user.nickname),
822 "confirmation_pending" => false
828 test "search by email", %{conn: conn} do
829 user = insert(:user, email: "email@example.com")
832 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
834 assert json_response(conn, 200) == %{
839 "deactivated" => user.deactivated,
841 "nickname" => user.nickname,
842 "roles" => %{"admin" => false, "moderator" => false},
845 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
846 "display_name" => HTML.strip_tags(user.name || user.nickname),
847 "confirmation_pending" => false
853 test "regular search with page size", %{conn: conn} do
854 user = insert(:user, nickname: "aalice")
855 user2 = insert(:user, nickname: "alice")
857 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
859 assert json_response(conn1, 200) == %{
864 "deactivated" => user.deactivated,
866 "nickname" => user.nickname,
867 "roles" => %{"admin" => false, "moderator" => false},
870 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
871 "display_name" => HTML.strip_tags(user.name || user.nickname),
872 "confirmation_pending" => false
877 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
879 assert json_response(conn2, 200) == %{
884 "deactivated" => user2.deactivated,
886 "nickname" => user2.nickname,
887 "roles" => %{"admin" => false, "moderator" => false},
890 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
891 "display_name" => HTML.strip_tags(user2.name || user2.nickname),
892 "confirmation_pending" => false
898 test "only local users" do
899 admin = insert(:user, is_admin: true, nickname: "john")
900 user = insert(:user, nickname: "bob")
902 insert(:user, nickname: "bobb", local: false)
906 |> assign(:user, admin)
907 |> get("/api/pleroma/admin/users?query=bo&filters=local")
909 assert json_response(conn, 200) == %{
914 "deactivated" => user.deactivated,
916 "nickname" => user.nickname,
917 "roles" => %{"admin" => false, "moderator" => false},
920 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
921 "display_name" => HTML.strip_tags(user.name || user.nickname),
922 "confirmation_pending" => false
928 test "only local users with no query", %{admin: old_admin} do
929 admin = insert(:user, is_admin: true, nickname: "john")
930 user = insert(:user, nickname: "bob")
932 insert(:user, nickname: "bobb", local: false)
936 |> assign(:user, admin)
937 |> get("/api/pleroma/admin/users?filters=local")
942 "deactivated" => user.deactivated,
944 "nickname" => user.nickname,
945 "roles" => %{"admin" => false, "moderator" => false},
948 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
949 "display_name" => HTML.strip_tags(user.name || user.nickname),
950 "confirmation_pending" => false
953 "deactivated" => admin.deactivated,
955 "nickname" => admin.nickname,
956 "roles" => %{"admin" => true, "moderator" => false},
959 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
960 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
961 "confirmation_pending" => false
964 "deactivated" => false,
965 "id" => old_admin.id,
967 "nickname" => old_admin.nickname,
968 "roles" => %{"admin" => true, "moderator" => false},
970 "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
971 "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname),
972 "confirmation_pending" => false
975 |> Enum.sort_by(& &1["nickname"])
977 assert json_response(conn, 200) == %{
984 test "load only admins", %{conn: conn, admin: admin} do
985 second_admin = insert(:user, is_admin: true)
989 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
994 "deactivated" => false,
996 "nickname" => admin.nickname,
997 "roles" => %{"admin" => true, "moderator" => false},
998 "local" => admin.local,
1000 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
1001 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
1002 "confirmation_pending" => false
1005 "deactivated" => false,
1006 "id" => second_admin.id,
1007 "nickname" => second_admin.nickname,
1008 "roles" => %{"admin" => true, "moderator" => false},
1009 "local" => second_admin.local,
1011 "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
1012 "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname),
1013 "confirmation_pending" => false
1016 |> Enum.sort_by(& &1["nickname"])
1018 assert json_response(conn, 200) == %{
1025 test "load only moderators", %{conn: conn} do
1026 moderator = insert(:user, is_moderator: true)
1030 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
1032 assert json_response(conn, 200) == %{
1037 "deactivated" => false,
1038 "id" => moderator.id,
1039 "nickname" => moderator.nickname,
1040 "roles" => %{"admin" => false, "moderator" => true},
1041 "local" => moderator.local,
1043 "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
1044 "display_name" => HTML.strip_tags(moderator.name || moderator.nickname),
1045 "confirmation_pending" => false
1051 test "load users with tags list", %{conn: conn} do
1052 user1 = insert(:user, tags: ["first"])
1053 user2 = insert(:user, tags: ["second"])
1057 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
1062 "deactivated" => false,
1064 "nickname" => user1.nickname,
1065 "roles" => %{"admin" => false, "moderator" => false},
1066 "local" => user1.local,
1067 "tags" => ["first"],
1068 "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
1069 "display_name" => HTML.strip_tags(user1.name || user1.nickname),
1070 "confirmation_pending" => false
1073 "deactivated" => false,
1075 "nickname" => user2.nickname,
1076 "roles" => %{"admin" => false, "moderator" => false},
1077 "local" => user2.local,
1078 "tags" => ["second"],
1079 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
1080 "display_name" => HTML.strip_tags(user2.name || user2.nickname),
1081 "confirmation_pending" => false
1084 |> Enum.sort_by(& &1["nickname"])
1086 assert json_response(conn, 200) == %{
1093 test "it works with multiple filters" do
1094 admin = insert(:user, nickname: "john", is_admin: true)
1095 user = insert(:user, nickname: "bob", local: false, deactivated: true)
1097 insert(:user, nickname: "ken", local: true, deactivated: true)
1098 insert(:user, nickname: "bobb", local: false, deactivated: false)
1102 |> assign(:user, admin)
1103 |> get("/api/pleroma/admin/users?filters=deactivated,external")
1105 assert json_response(conn, 200) == %{
1110 "deactivated" => user.deactivated,
1112 "nickname" => user.nickname,
1113 "roles" => %{"admin" => false, "moderator" => false},
1114 "local" => user.local,
1116 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1117 "display_name" => HTML.strip_tags(user.name || user.nickname),
1118 "confirmation_pending" => false
1124 test "it omits relay user", %{admin: admin} do
1125 assert %User{} = Relay.get_actor()
1129 |> assign(:user, admin)
1130 |> get("/api/pleroma/admin/users")
1132 assert json_response(conn, 200) == %{
1137 "deactivated" => admin.deactivated,
1139 "nickname" => admin.nickname,
1140 "roles" => %{"admin" => true, "moderator" => false},
1143 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
1144 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
1145 "confirmation_pending" => false
1152 test "PATCH /api/pleroma/admin/users/activate" do
1153 admin = insert(:user, is_admin: true)
1154 user_one = insert(:user, deactivated: true)
1155 user_two = insert(:user, deactivated: true)
1159 |> assign(:user, admin)
1161 "/api/pleroma/admin/users/activate",
1162 %{nicknames: [user_one.nickname, user_two.nickname]}
1165 response = json_response(conn, 200)
1166 assert Enum.map(response["users"], & &1["deactivated"]) == [false, false]
1168 log_entry = Repo.one(ModerationLog)
1170 assert ModerationLog.get_log_entry_message(log_entry) ==
1171 "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
1174 test "PATCH /api/pleroma/admin/users/deactivate" do
1175 admin = insert(:user, is_admin: true)
1176 user_one = insert(:user, deactivated: false)
1177 user_two = insert(:user, deactivated: false)
1181 |> assign(:user, admin)
1183 "/api/pleroma/admin/users/deactivate",
1184 %{nicknames: [user_one.nickname, user_two.nickname]}
1187 response = json_response(conn, 200)
1188 assert Enum.map(response["users"], & &1["deactivated"]) == [true, true]
1190 log_entry = Repo.one(ModerationLog)
1192 assert ModerationLog.get_log_entry_message(log_entry) ==
1193 "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
1196 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
1197 admin = insert(:user, is_admin: true)
1198 user = insert(:user)
1202 |> assign(:user, admin)
1203 |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
1205 assert json_response(conn, 200) ==
1207 "deactivated" => !user.deactivated,
1209 "nickname" => user.nickname,
1210 "roles" => %{"admin" => false, "moderator" => false},
1213 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1214 "display_name" => HTML.strip_tags(user.name || user.nickname),
1215 "confirmation_pending" => false
1218 log_entry = Repo.one(ModerationLog)
1220 assert ModerationLog.get_log_entry_message(log_entry) ==
1221 "@#{admin.nickname} deactivated users: @#{user.nickname}"
1224 describe "POST /api/pleroma/admin/users/invite_token" do
1226 admin = insert(:user, is_admin: true)
1230 |> assign(:user, admin)
1235 test "without options", %{conn: conn} do
1236 conn = post(conn, "/api/pleroma/admin/users/invite_token")
1238 invite_json = json_response(conn, 200)
1239 invite = UserInviteToken.find_by_token!(invite_json["token"])
1241 refute invite.expires_at
1242 refute invite.max_use
1243 assert invite.invite_type == "one_time"
1246 test "with expires_at", %{conn: conn} do
1248 post(conn, "/api/pleroma/admin/users/invite_token", %{
1249 "expires_at" => Date.to_string(Date.utc_today())
1252 invite_json = json_response(conn, 200)
1253 invite = UserInviteToken.find_by_token!(invite_json["token"])
1256 assert invite.expires_at == Date.utc_today()
1257 refute invite.max_use
1258 assert invite.invite_type == "date_limited"
1261 test "with max_use", %{conn: conn} do
1262 conn = post(conn, "/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
1264 invite_json = json_response(conn, 200)
1265 invite = UserInviteToken.find_by_token!(invite_json["token"])
1267 refute invite.expires_at
1268 assert invite.max_use == 150
1269 assert invite.invite_type == "reusable"
1272 test "with max use and expires_at", %{conn: conn} do
1274 post(conn, "/api/pleroma/admin/users/invite_token", %{
1276 "expires_at" => Date.to_string(Date.utc_today())
1279 invite_json = json_response(conn, 200)
1280 invite = UserInviteToken.find_by_token!(invite_json["token"])
1282 assert invite.expires_at == Date.utc_today()
1283 assert invite.max_use == 150
1284 assert invite.invite_type == "reusable_date_limited"
1288 describe "GET /api/pleroma/admin/users/invites" do
1290 admin = insert(:user, is_admin: true)
1294 |> assign(:user, admin)
1299 test "no invites", %{conn: conn} do
1300 conn = get(conn, "/api/pleroma/admin/users/invites")
1302 assert json_response(conn, 200) == %{"invites" => []}
1305 test "with invite", %{conn: conn} do
1306 {:ok, invite} = UserInviteToken.create_invite()
1308 conn = get(conn, "/api/pleroma/admin/users/invites")
1310 assert json_response(conn, 200) == %{
1313 "expires_at" => nil,
1315 "invite_type" => "one_time",
1317 "token" => invite.token,
1326 describe "POST /api/pleroma/admin/users/revoke_invite" do
1327 test "with token" do
1328 admin = insert(:user, is_admin: true)
1329 {:ok, invite} = UserInviteToken.create_invite()
1333 |> assign(:user, admin)
1334 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
1336 assert json_response(conn, 200) == %{
1337 "expires_at" => nil,
1339 "invite_type" => "one_time",
1341 "token" => invite.token,
1347 test "with invalid token" do
1348 admin = insert(:user, is_admin: true)
1352 |> assign(:user, admin)
1353 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
1355 assert json_response(conn, :not_found) == "Not found"
1359 describe "GET /api/pleroma/admin/reports/:id" do
1360 setup %{conn: conn} do
1361 admin = insert(:user, is_admin: true)
1363 %{conn: assign(conn, :user, admin)}
1366 test "returns report by its id", %{conn: conn} do
1367 [reporter, target_user] = insert_pair(:user)
1368 activity = insert(:note_activity, user: target_user)
1370 {:ok, %{id: report_id}} =
1371 CommonAPI.report(reporter, %{
1372 "account_id" => target_user.id,
1373 "comment" => "I feel offended",
1374 "status_ids" => [activity.id]
1379 |> get("/api/pleroma/admin/reports/#{report_id}")
1380 |> json_response(:ok)
1382 assert response["id"] == report_id
1385 test "returns 404 when report id is invalid", %{conn: conn} do
1386 conn = get(conn, "/api/pleroma/admin/reports/test")
1388 assert json_response(conn, :not_found) == "Not found"
1392 describe "PATCH /api/pleroma/admin/reports" do
1393 setup %{conn: conn} do
1394 admin = insert(:user, is_admin: true)
1395 [reporter, target_user] = insert_pair(:user)
1396 activity = insert(:note_activity, user: target_user)
1398 {:ok, %{id: report_id}} =
1399 CommonAPI.report(reporter, %{
1400 "account_id" => target_user.id,
1401 "comment" => "I feel offended",
1402 "status_ids" => [activity.id]
1405 {:ok, %{id: second_report_id}} =
1406 CommonAPI.report(reporter, %{
1407 "account_id" => target_user.id,
1408 "comment" => "I feel very offended",
1409 "status_ids" => [activity.id]
1413 conn: assign(conn, :user, admin),
1416 second_report_id: second_report_id
1420 test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
1422 |> patch("/api/pleroma/admin/reports", %{
1424 %{"state" => "resolved", "id" => id}
1427 |> json_response(:no_content)
1429 activity = Activity.get_by_id(id)
1430 assert activity.data["state"] == "resolved"
1432 log_entry = Repo.one(ModerationLog)
1434 assert ModerationLog.get_log_entry_message(log_entry) ==
1435 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
1438 test "closes report", %{conn: conn, id: id, admin: admin} do
1440 |> patch("/api/pleroma/admin/reports", %{
1442 %{"state" => "closed", "id" => id}
1445 |> json_response(:no_content)
1447 activity = Activity.get_by_id(id)
1448 assert activity.data["state"] == "closed"
1450 log_entry = Repo.one(ModerationLog)
1452 assert ModerationLog.get_log_entry_message(log_entry) ==
1453 "@#{admin.nickname} updated report ##{id} with 'closed' state"
1456 test "returns 400 when state is unknown", %{conn: conn, id: id} do
1459 |> patch("/api/pleroma/admin/reports", %{
1461 %{"state" => "test", "id" => id}
1465 assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"
1468 test "returns 404 when report is not exist", %{conn: conn} do
1471 |> patch("/api/pleroma/admin/reports", %{
1473 %{"state" => "closed", "id" => "test"}
1477 assert hd(json_response(conn, :bad_request))["error"] == "not_found"
1480 test "updates state of multiple reports", %{
1484 second_report_id: second_report_id
1487 |> patch("/api/pleroma/admin/reports", %{
1489 %{"state" => "resolved", "id" => id},
1490 %{"state" => "closed", "id" => second_report_id}
1493 |> json_response(:no_content)
1495 activity = Activity.get_by_id(id)
1496 second_activity = Activity.get_by_id(second_report_id)
1497 assert activity.data["state"] == "resolved"
1498 assert second_activity.data["state"] == "closed"
1500 [first_log_entry, second_log_entry] = Repo.all(ModerationLog)
1502 assert ModerationLog.get_log_entry_message(first_log_entry) ==
1503 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
1505 assert ModerationLog.get_log_entry_message(second_log_entry) ==
1506 "@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"
1510 describe "GET /api/pleroma/admin/reports" do
1511 setup %{conn: conn} do
1512 admin = insert(:user, is_admin: true)
1514 %{conn: assign(conn, :user, admin)}
1517 test "returns empty response when no reports created", %{conn: conn} do
1520 |> get("/api/pleroma/admin/reports")
1521 |> json_response(:ok)
1523 assert Enum.empty?(response["reports"])
1524 assert response["total"] == 0
1527 test "returns reports", %{conn: conn} do
1528 [reporter, target_user] = insert_pair(:user)
1529 activity = insert(:note_activity, user: target_user)
1531 {:ok, %{id: report_id}} =
1532 CommonAPI.report(reporter, %{
1533 "account_id" => target_user.id,
1534 "comment" => "I feel offended",
1535 "status_ids" => [activity.id]
1540 |> get("/api/pleroma/admin/reports")
1541 |> json_response(:ok)
1543 [report] = response["reports"]
1545 assert length(response["reports"]) == 1
1546 assert report["id"] == report_id
1548 assert response["total"] == 1
1551 test "returns reports with specified state", %{conn: conn} do
1552 [reporter, target_user] = insert_pair(:user)
1553 activity = insert(:note_activity, user: target_user)
1555 {:ok, %{id: first_report_id}} =
1556 CommonAPI.report(reporter, %{
1557 "account_id" => target_user.id,
1558 "comment" => "I feel offended",
1559 "status_ids" => [activity.id]
1562 {:ok, %{id: second_report_id}} =
1563 CommonAPI.report(reporter, %{
1564 "account_id" => target_user.id,
1565 "comment" => "I don't like this user"
1568 CommonAPI.update_report_state(second_report_id, "closed")
1572 |> get("/api/pleroma/admin/reports", %{
1575 |> json_response(:ok)
1577 [open_report] = response["reports"]
1579 assert length(response["reports"]) == 1
1580 assert open_report["id"] == first_report_id
1582 assert response["total"] == 1
1586 |> get("/api/pleroma/admin/reports", %{
1589 |> json_response(:ok)
1591 [closed_report] = response["reports"]
1593 assert length(response["reports"]) == 1
1594 assert closed_report["id"] == second_report_id
1596 assert response["total"] == 1
1600 |> get("/api/pleroma/admin/reports", %{
1601 "state" => "resolved"
1603 |> json_response(:ok)
1605 assert Enum.empty?(response["reports"])
1606 assert response["total"] == 0
1609 test "returns 403 when requested by a non-admin" do
1610 user = insert(:user)
1614 |> assign(:user, user)
1615 |> get("/api/pleroma/admin/reports")
1617 assert json_response(conn, :forbidden) ==
1618 %{"error" => "User is not an admin or OAuth admin scope is not granted."}
1621 test "returns 403 when requested by anonymous" do
1624 |> get("/api/pleroma/admin/reports")
1626 assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
1630 describe "GET /api/pleroma/admin/grouped_reports" do
1631 setup %{conn: conn} do
1632 admin = insert(:user, is_admin: true)
1633 [reporter, target_user] = insert_pair(:user)
1635 date1 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
1636 date2 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
1637 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
1640 insert(:note_activity, user: target_user, data_attrs: %{"published" => date1})
1643 insert(:note_activity, user: target_user, data_attrs: %{"published" => date2})
1646 insert(:note_activity, user: target_user, data_attrs: %{"published" => date3})
1648 {:ok, first_report} =
1649 CommonAPI.report(reporter, %{
1650 "account_id" => target_user.id,
1651 "status_ids" => [first_status.id, second_status.id, third_status.id]
1654 {:ok, second_report} =
1655 CommonAPI.report(reporter, %{
1656 "account_id" => target_user.id,
1657 "status_ids" => [first_status.id, second_status.id]
1660 {:ok, third_report} =
1661 CommonAPI.report(reporter, %{
1662 "account_id" => target_user.id,
1663 "status_ids" => [first_status.id]
1667 conn: assign(conn, :user, admin),
1668 first_status: Activity.get_by_ap_id_with_object(first_status.data["id"]),
1669 second_status: Activity.get_by_ap_id_with_object(second_status.data["id"]),
1670 third_status: Activity.get_by_ap_id_with_object(third_status.data["id"]),
1671 first_report: first_report,
1672 first_status_reports: [first_report, second_report, third_report],
1673 second_status_reports: [first_report, second_report],
1674 third_status_reports: [first_report],
1675 target_user: target_user,
1680 test "returns reports grouped by status", %{
1682 first_status: first_status,
1683 second_status: second_status,
1684 third_status: third_status,
1685 first_status_reports: first_status_reports,
1686 second_status_reports: second_status_reports,
1687 third_status_reports: third_status_reports,
1688 target_user: target_user,
1693 |> get("/api/pleroma/admin/grouped_reports")
1694 |> json_response(:ok)
1696 assert length(response["reports"]) == 3
1698 first_group = Enum.find(response["reports"], &(&1["status"]["id"] == first_status.id))
1700 second_group = Enum.find(response["reports"], &(&1["status"]["id"] == second_status.id))
1702 third_group = Enum.find(response["reports"], &(&1["status"]["id"] == third_status.id))
1704 assert length(first_group["reports"]) == 3
1705 assert length(second_group["reports"]) == 2
1706 assert length(third_group["reports"]) == 1
1708 assert first_group["date"] ==
1709 Enum.max_by(first_status_reports, fn act ->
1710 NaiveDateTime.from_iso8601!(act.data["published"])
1711 end).data["published"]
1713 assert first_group["status"] ==
1715 stringify_keys(StatusView.render("show.json", %{activity: first_status})),
1720 assert(first_group["account"]["id"] == target_user.id)
1722 assert length(first_group["actors"]) == 1
1723 assert hd(first_group["actors"])["id"] == reporter.id
1725 assert Enum.map(first_group["reports"], & &1["id"]) --
1726 Enum.map(first_status_reports, & &1.id) == []
1728 assert second_group["date"] ==
1729 Enum.max_by(second_status_reports, fn act ->
1730 NaiveDateTime.from_iso8601!(act.data["published"])
1731 end).data["published"]
1733 assert second_group["status"] ==
1735 stringify_keys(StatusView.render("show.json", %{activity: second_status})),
1740 assert second_group["account"]["id"] == target_user.id
1742 assert length(second_group["actors"]) == 1
1743 assert hd(second_group["actors"])["id"] == reporter.id
1745 assert Enum.map(second_group["reports"], & &1["id"]) --
1746 Enum.map(second_status_reports, & &1.id) == []
1748 assert third_group["date"] ==
1749 Enum.max_by(third_status_reports, fn act ->
1750 NaiveDateTime.from_iso8601!(act.data["published"])
1751 end).data["published"]
1753 assert third_group["status"] ==
1755 stringify_keys(StatusView.render("show.json", %{activity: third_status})),
1760 assert third_group["account"]["id"] == target_user.id
1762 assert length(third_group["actors"]) == 1
1763 assert hd(third_group["actors"])["id"] == reporter.id
1765 assert Enum.map(third_group["reports"], & &1["id"]) --
1766 Enum.map(third_status_reports, & &1.id) == []
1769 test "reopened report renders status data", %{
1771 first_report: first_report,
1772 first_status: first_status
1774 {:ok, _} = CommonAPI.update_report_state(first_report.id, "resolved")
1778 |> get("/api/pleroma/admin/grouped_reports")
1779 |> json_response(:ok)
1781 first_group = Enum.find(response["reports"], &(&1["status"]["id"] == first_status.id))
1783 assert first_group["status"] ==
1785 stringify_keys(StatusView.render("show.json", %{activity: first_status})),
1791 test "reopened report does not render status data if status has been deleted", %{
1793 first_report: first_report,
1794 first_status: first_status,
1795 target_user: target_user
1797 {:ok, _} = CommonAPI.update_report_state(first_report.id, "resolved")
1798 {:ok, _} = CommonAPI.delete(first_status.id, target_user)
1800 refute Activity.get_by_ap_id(first_status.id)
1804 |> get("/api/pleroma/admin/grouped_reports")
1805 |> json_response(:ok)
1807 assert Enum.find(response["reports"], &(&1["status"]["deleted"] == true))["status"][
1811 assert length(Enum.filter(response["reports"], &(&1["status"]["deleted"] == false))) == 2
1814 test "account not empty if status was deleted", %{
1816 first_report: first_report,
1817 first_status: first_status,
1818 target_user: target_user
1820 {:ok, _} = CommonAPI.update_report_state(first_report.id, "resolved")
1821 {:ok, _} = CommonAPI.delete(first_status.id, target_user)
1823 refute Activity.get_by_ap_id(first_status.id)
1827 |> get("/api/pleroma/admin/grouped_reports")
1828 |> json_response(:ok)
1830 assert Enum.find(response["reports"], &(&1["status"]["deleted"] == true))["account"]
1834 describe "POST /api/pleroma/admin/reports/:id/respond" do
1835 setup %{conn: conn} do
1836 admin = insert(:user, is_admin: true)
1838 %{conn: assign(conn, :user, admin), admin: admin}
1841 test "returns created dm", %{conn: conn, admin: admin} do
1842 [reporter, target_user] = insert_pair(:user)
1843 activity = insert(:note_activity, user: target_user)
1845 {:ok, %{id: report_id}} =
1846 CommonAPI.report(reporter, %{
1847 "account_id" => target_user.id,
1848 "comment" => "I feel offended",
1849 "status_ids" => [activity.id]
1854 |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
1855 "status" => "I will check it out"
1857 |> json_response(:ok)
1859 recipients = Enum.map(response["mentions"], & &1["username"])
1861 assert reporter.nickname in recipients
1862 assert response["content"] == "I will check it out"
1863 assert response["visibility"] == "direct"
1865 log_entry = Repo.one(ModerationLog)
1867 assert ModerationLog.get_log_entry_message(log_entry) ==
1868 "@#{admin.nickname} responded with 'I will check it out' to report ##{
1873 test "returns 400 when status is missing", %{conn: conn} do
1874 conn = post(conn, "/api/pleroma/admin/reports/test/respond")
1876 assert json_response(conn, :bad_request) == "Invalid parameters"
1879 test "returns 404 when report id is invalid", %{conn: conn} do
1881 post(conn, "/api/pleroma/admin/reports/test/respond", %{
1885 assert json_response(conn, :not_found) == "Not found"
1889 describe "PUT /api/pleroma/admin/statuses/:id" do
1890 setup %{conn: conn} do
1891 admin = insert(:user, is_admin: true)
1892 activity = insert(:note_activity)
1894 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1897 test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
1900 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
1901 |> json_response(:ok)
1903 assert response["sensitive"]
1905 log_entry = Repo.one(ModerationLog)
1907 assert ModerationLog.get_log_entry_message(log_entry) ==
1908 "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
1912 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
1913 |> json_response(:ok)
1915 refute response["sensitive"]
1918 test "change visibility flag", %{conn: conn, id: id, admin: admin} do
1921 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
1922 |> json_response(:ok)
1924 assert response["visibility"] == "public"
1926 log_entry = Repo.one(ModerationLog)
1928 assert ModerationLog.get_log_entry_message(log_entry) ==
1929 "@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
1933 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
1934 |> json_response(:ok)
1936 assert response["visibility"] == "private"
1940 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"})
1941 |> json_response(:ok)
1943 assert response["visibility"] == "unlisted"
1946 test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
1949 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"})
1951 assert json_response(conn, :bad_request) == "Unsupported visibility"
1955 describe "DELETE /api/pleroma/admin/statuses/:id" do
1956 setup %{conn: conn} do
1957 admin = insert(:user, is_admin: true)
1958 activity = insert(:note_activity)
1960 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1963 test "deletes status", %{conn: conn, id: id, admin: admin} do
1965 |> delete("/api/pleroma/admin/statuses/#{id}")
1966 |> json_response(:ok)
1968 refute Activity.get_by_id(id)
1970 log_entry = Repo.one(ModerationLog)
1972 assert ModerationLog.get_log_entry_message(log_entry) ==
1973 "@#{admin.nickname} deleted status ##{id}"
1976 test "returns error when status is not exist", %{conn: conn} do
1979 |> delete("/api/pleroma/admin/statuses/test")
1981 assert json_response(conn, :bad_request) == "Could not delete"
1985 describe "GET /api/pleroma/admin/config" do
1986 setup %{conn: conn} do
1987 admin = insert(:user, is_admin: true)
1989 %{conn: assign(conn, :user, admin)}
1992 test "without any settings in db", %{conn: conn} do
1993 conn = get(conn, "/api/pleroma/admin/config")
1995 assert json_response(conn, 200) == %{"configs" => []}
1998 test "with settings in db", %{conn: conn} do
1999 config1 = insert(:config)
2000 config2 = insert(:config)
2002 conn = get(conn, "/api/pleroma/admin/config")
2015 } = json_response(conn, 200)
2017 assert key1 == config1.key
2018 assert key2 == config2.key
2022 describe "POST /api/pleroma/admin/config" do
2023 setup %{conn: conn} do
2024 admin = insert(:user, is_admin: true)
2026 temp_file = "config/test.exported_from_db.secret.exs"
2029 Application.delete_env(:pleroma, :key1)
2030 Application.delete_env(:pleroma, :key2)
2031 Application.delete_env(:pleroma, :key3)
2032 Application.delete_env(:pleroma, :key4)
2033 Application.delete_env(:pleroma, :keyaa1)
2034 Application.delete_env(:pleroma, :keyaa2)
2035 Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
2036 Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
2037 :ok = File.rm(temp_file)
2040 %{conn: assign(conn, :user, admin)}
2043 clear_config([:instance, :dynamic_configuration]) do
2044 Pleroma.Config.put([:instance, :dynamic_configuration], true)
2047 @tag capture_log: true
2048 test "create new config setting in db", %{conn: conn} do
2050 post(conn, "/api/pleroma/admin/config", %{
2052 %{group: "pleroma", key: "key1", value: "value1"},
2055 key: "Ueberauth.Strategy.Twitter.OAuth",
2056 value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
2062 ":nested_1" => "nested_value1",
2064 %{":nested_22" => "nested_value222"},
2065 %{":nested_33" => %{":nested_44" => "nested_444"}}
2073 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
2074 %{"nested_4" => true}
2080 value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
2085 value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
2090 assert json_response(conn, 200) == %{
2093 "group" => "pleroma",
2098 "group" => "ueberauth",
2099 "key" => "Ueberauth.Strategy.Twitter.OAuth",
2100 "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}]
2103 "group" => "pleroma",
2106 ":nested_1" => "nested_value1",
2108 %{":nested_22" => "nested_value222"},
2109 %{":nested_33" => %{":nested_44" => "nested_444"}}
2114 "group" => "pleroma",
2117 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
2118 %{"nested_4" => true}
2122 "group" => "pleroma",
2124 "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}
2129 "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
2134 assert Application.get_env(:pleroma, :key1) == "value1"
2136 assert Application.get_env(:pleroma, :key2) == %{
2137 nested_1: "nested_value1",
2139 %{nested_22: "nested_value222"},
2140 %{nested_33: %{nested_44: "nested_444"}}
2144 assert Application.get_env(:pleroma, :key3) == [
2145 %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
2146 %{"nested_4" => true}
2149 assert Application.get_env(:pleroma, :key4) == %{
2150 "endpoint" => "https://example.com",
2154 assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
2157 test "update config setting & delete", %{conn: conn} do
2158 config1 = insert(:config, key: "keyaa1")
2159 config2 = insert(:config, key: "keyaa2")
2163 key: "Ueberauth.Strategy.Microsoft.OAuth",
2164 value: :erlang.term_to_binary([])
2168 post(conn, "/api/pleroma/admin/config", %{
2170 %{group: config1.group, key: config1.key, value: "another_value"},
2171 %{group: config2.group, key: config2.key, delete: "true"},
2174 key: "Ueberauth.Strategy.Microsoft.OAuth",
2180 assert json_response(conn, 200) == %{
2183 "group" => "pleroma",
2184 "key" => config1.key,
2185 "value" => "another_value"
2190 assert Application.get_env(:pleroma, :keyaa1) == "another_value"
2191 refute Application.get_env(:pleroma, :keyaa2)
2194 test "common config example", %{conn: conn} do
2196 post(conn, "/api/pleroma/admin/config", %{
2199 "group" => "pleroma",
2200 "key" => "Pleroma.Captcha.NotReal",
2202 %{"tuple" => [":enabled", false]},
2203 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
2204 %{"tuple" => [":seconds_valid", 60]},
2205 %{"tuple" => [":path", ""]},
2206 %{"tuple" => [":key1", nil]},
2207 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
2208 %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
2209 %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
2210 %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
2211 %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]}
2217 assert json_response(conn, 200) == %{
2220 "group" => "pleroma",
2221 "key" => "Pleroma.Captcha.NotReal",
2223 %{"tuple" => [":enabled", false]},
2224 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
2225 %{"tuple" => [":seconds_valid", 60]},
2226 %{"tuple" => [":path", ""]},
2227 %{"tuple" => [":key1", nil]},
2228 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
2229 %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
2230 %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
2231 %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
2232 %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]}
2239 test "tuples with more than two values", %{conn: conn} do
2241 post(conn, "/api/pleroma/admin/config", %{
2244 "group" => "pleroma",
2245 "key" => "Pleroma.Web.Endpoint.NotReal",
2261 "/api/v1/streaming",
2262 "Pleroma.Web.MastodonAPI.WebsocketHandler",
2269 "Phoenix.Endpoint.CowboyWebSocket",
2272 "Phoenix.Transports.WebSocket",
2275 "Pleroma.Web.Endpoint",
2276 "Pleroma.Web.UserSocket",
2287 "Phoenix.Endpoint.Cowboy2Handler",
2288 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
2305 assert json_response(conn, 200) == %{
2308 "group" => "pleroma",
2309 "key" => "Pleroma.Web.Endpoint.NotReal",
2325 "/api/v1/streaming",
2326 "Pleroma.Web.MastodonAPI.WebsocketHandler",
2333 "Phoenix.Endpoint.CowboyWebSocket",
2336 "Phoenix.Transports.WebSocket",
2339 "Pleroma.Web.Endpoint",
2340 "Pleroma.Web.UserSocket",
2351 "Phoenix.Endpoint.Cowboy2Handler",
2352 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
2370 test "settings with nesting map", %{conn: conn} do
2372 post(conn, "/api/pleroma/admin/config", %{
2375 "group" => "pleroma",
2378 %{"tuple" => [":key2", "some_val"]},
2383 ":max_options" => 20,
2384 ":max_option_chars" => 200,
2385 ":min_expiration" => 0,
2386 ":max_expiration" => 31_536_000,
2388 ":max_options" => 20,
2389 ":max_option_chars" => 200,
2390 ":min_expiration" => 0,
2391 ":max_expiration" => 31_536_000
2401 assert json_response(conn, 200) ==
2405 "group" => "pleroma",
2408 %{"tuple" => [":key2", "some_val"]},
2413 ":max_expiration" => 31_536_000,
2414 ":max_option_chars" => 200,
2415 ":max_options" => 20,
2416 ":min_expiration" => 0,
2418 ":max_expiration" => 31_536_000,
2419 ":max_option_chars" => 200,
2420 ":max_options" => 20,
2421 ":min_expiration" => 0
2432 test "value as map", %{conn: conn} do
2434 post(conn, "/api/pleroma/admin/config", %{
2437 "group" => "pleroma",
2439 "value" => %{"key" => "some_val"}
2444 assert json_response(conn, 200) ==
2448 "group" => "pleroma",
2450 "value" => %{"key" => "some_val"}
2456 test "dispatch setting", %{conn: conn} do
2458 post(conn, "/api/pleroma/admin/config", %{
2461 "group" => "pleroma",
2462 "key" => "Pleroma.Web.Endpoint.NotReal",
2468 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2469 %{"tuple" => [":dispatch", ["{:_,
2471 {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
2472 {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket,
2473 {Phoenix.Transports.WebSocket,
2474 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}},
2475 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
2486 "{:_, [{\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, " <>
2487 "{\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, " <>
2488 "{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, " <>
2489 "{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}]}"
2491 assert json_response(conn, 200) == %{
2494 "group" => "pleroma",
2495 "key" => "Pleroma.Web.Endpoint.NotReal",
2501 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2519 test "queues key as atom", %{conn: conn} do
2521 post(conn, "/api/pleroma/admin/config", %{
2527 %{"tuple" => [":federator_incoming", 50]},
2528 %{"tuple" => [":federator_outgoing", 50]},
2529 %{"tuple" => [":web_push", 50]},
2530 %{"tuple" => [":mailer", 10]},
2531 %{"tuple" => [":transmogrifier", 20]},
2532 %{"tuple" => [":scheduled_activities", 10]},
2533 %{"tuple" => [":background", 5]}
2539 assert json_response(conn, 200) == %{
2545 %{"tuple" => [":federator_incoming", 50]},
2546 %{"tuple" => [":federator_outgoing", 50]},
2547 %{"tuple" => [":web_push", 50]},
2548 %{"tuple" => [":mailer", 10]},
2549 %{"tuple" => [":transmogrifier", 20]},
2550 %{"tuple" => [":scheduled_activities", 10]},
2551 %{"tuple" => [":background", 5]}
2558 test "delete part of settings by atom subkeys", %{conn: conn} do
2562 value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3")
2566 post(conn, "/api/pleroma/admin/config", %{
2569 group: config.group,
2571 subkeys: [":subkey1", ":subkey3"],
2578 json_response(conn, 200) == %{
2581 "group" => "pleroma",
2583 "value" => [%{"tuple" => [":subkey2", "val2"]}]
2591 describe "config mix tasks run" do
2592 setup %{conn: conn} do
2593 admin = insert(:user, is_admin: true)
2595 temp_file = "config/test.exported_from_db.secret.exs"
2597 Mix.shell(Mix.Shell.Quiet)
2600 Mix.shell(Mix.Shell.IO)
2601 :ok = File.rm(temp_file)
2604 %{conn: assign(conn, :user, admin), admin: admin}
2607 clear_config([:instance, :dynamic_configuration]) do
2608 Pleroma.Config.put([:instance, :dynamic_configuration], true)
2611 clear_config([:feed, :post_title]) do
2612 Pleroma.Config.put([:feed, :post_title], %{max_length: 100, omission: "…"})
2615 test "transfer settings to DB and to file", %{conn: conn, admin: admin} do
2616 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2617 conn = get(conn, "/api/pleroma/admin/config/migrate_to_db")
2618 assert json_response(conn, 200) == %{}
2619 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) > 0
2623 |> assign(:user, admin)
2624 |> get("/api/pleroma/admin/config/migrate_from_db")
2626 assert json_response(conn, 200) == %{}
2627 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2631 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
2633 admin = insert(:user, is_admin: true)
2634 user = insert(:user)
2636 date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
2637 date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
2638 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
2640 insert(:note_activity, user: user, published: date1)
2641 insert(:note_activity, user: user, published: date2)
2642 insert(:note_activity, user: user, published: date3)
2646 |> assign(:user, admin)
2648 {:ok, conn: conn, user: user}
2651 test "renders user's statuses", %{conn: conn, user: user} do
2652 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2654 assert json_response(conn, 200) |> length() == 3
2657 test "renders user's statuses with a limit", %{conn: conn, user: user} do
2658 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
2660 assert json_response(conn, 200) |> length() == 2
2663 test "doesn't return private statuses by default", %{conn: conn, user: user} do
2664 {:ok, _private_status} =
2665 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2667 {:ok, _public_status} =
2668 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2670 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2672 assert json_response(conn, 200) |> length() == 4
2675 test "returns private statuses with godmode on", %{conn: conn, user: user} do
2676 {:ok, _private_status} =
2677 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2679 {:ok, _public_status} =
2680 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2682 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
2684 assert json_response(conn, 200) |> length() == 5
2688 describe "GET /api/pleroma/admin/moderation_log" do
2689 setup %{conn: conn} do
2690 admin = insert(:user, is_admin: true)
2691 moderator = insert(:user, is_moderator: true)
2693 %{conn: assign(conn, :user, admin), admin: admin, moderator: moderator}
2696 test "returns the log", %{conn: conn, admin: admin} do
2697 Repo.insert(%ModerationLog{
2701 "nickname" => admin.nickname,
2704 action: "relay_follow",
2705 target: "https://example.org/relay"
2707 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2710 Repo.insert(%ModerationLog{
2714 "nickname" => admin.nickname,
2717 action: "relay_unfollow",
2718 target: "https://example.org/relay"
2720 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2723 conn = get(conn, "/api/pleroma/admin/moderation_log")
2725 response = json_response(conn, 200)
2726 [first_entry, second_entry] = response["items"]
2728 assert response["total"] == 2
2729 assert first_entry["data"]["action"] == "relay_unfollow"
2731 assert first_entry["message"] ==
2732 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2734 assert second_entry["data"]["action"] == "relay_follow"
2736 assert second_entry["message"] ==
2737 "@#{admin.nickname} followed relay: https://example.org/relay"
2740 test "returns the log with pagination", %{conn: conn, admin: admin} do
2741 Repo.insert(%ModerationLog{
2745 "nickname" => admin.nickname,
2748 action: "relay_follow",
2749 target: "https://example.org/relay"
2751 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2754 Repo.insert(%ModerationLog{
2758 "nickname" => admin.nickname,
2761 action: "relay_unfollow",
2762 target: "https://example.org/relay"
2764 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2767 conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
2769 response1 = json_response(conn1, 200)
2770 [first_entry] = response1["items"]
2772 assert response1["total"] == 2
2773 assert response1["items"] |> length() == 1
2774 assert first_entry["data"]["action"] == "relay_unfollow"
2776 assert first_entry["message"] ==
2777 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2779 conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
2781 response2 = json_response(conn2, 200)
2782 [second_entry] = response2["items"]
2784 assert response2["total"] == 2
2785 assert response2["items"] |> length() == 1
2786 assert second_entry["data"]["action"] == "relay_follow"
2788 assert second_entry["message"] ==
2789 "@#{admin.nickname} followed relay: https://example.org/relay"
2792 test "filters log by date", %{conn: conn, admin: admin} do
2793 first_date = "2017-08-15T15:47:06Z"
2794 second_date = "2017-08-20T15:47:06Z"
2796 Repo.insert(%ModerationLog{
2800 "nickname" => admin.nickname,
2803 action: "relay_follow",
2804 target: "https://example.org/relay"
2806 inserted_at: NaiveDateTime.from_iso8601!(first_date)
2809 Repo.insert(%ModerationLog{
2813 "nickname" => admin.nickname,
2816 action: "relay_unfollow",
2817 target: "https://example.org/relay"
2819 inserted_at: NaiveDateTime.from_iso8601!(second_date)
2825 "/api/pleroma/admin/moderation_log?start_date=#{second_date}"
2828 response1 = json_response(conn1, 200)
2829 [first_entry] = response1["items"]
2831 assert response1["total"] == 1
2832 assert first_entry["data"]["action"] == "relay_unfollow"
2834 assert first_entry["message"] ==
2835 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2838 test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
2839 Repo.insert(%ModerationLog{
2843 "nickname" => admin.nickname,
2846 action: "relay_follow",
2847 target: "https://example.org/relay"
2851 Repo.insert(%ModerationLog{
2854 "id" => moderator.id,
2855 "nickname" => moderator.nickname,
2858 action: "relay_unfollow",
2859 target: "https://example.org/relay"
2863 conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
2865 response1 = json_response(conn1, 200)
2866 [first_entry] = response1["items"]
2868 assert response1["total"] == 1
2869 assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
2872 test "returns log filtered by search", %{conn: conn, moderator: moderator} do
2873 ModerationLog.insert_log(%{
2875 action: "relay_follow",
2876 target: "https://example.org/relay"
2879 ModerationLog.insert_log(%{
2881 action: "relay_unfollow",
2882 target: "https://example.org/relay"
2885 conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
2887 response1 = json_response(conn1, 200)
2888 [first_entry] = response1["items"]
2890 assert response1["total"] == 1
2892 assert get_in(first_entry, ["data", "message"]) ==
2893 "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
2897 describe "PATCH /users/:nickname/force_password_reset" do
2898 setup %{conn: conn} do
2899 admin = insert(:user, is_admin: true)
2900 user = insert(:user)
2902 %{conn: assign(conn, :user, admin), admin: admin, user: user}
2905 test "sets password_reset_pending to true", %{admin: admin, user: user} do
2906 assert user.password_reset_pending == false
2910 |> assign(:user, admin)
2911 |> patch("/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]})
2913 assert json_response(conn, 204) == ""
2915 ObanHelpers.perform_all()
2917 assert User.get_by_id(user.id).password_reset_pending == true
2921 describe "relays" do
2922 setup %{conn: conn} do
2923 admin = insert(:user, is_admin: true)
2925 %{conn: assign(conn, :user, admin), admin: admin}
2928 test "POST /relay", %{admin: admin} do
2931 |> assign(:user, admin)
2932 |> post("/api/pleroma/admin/relay", %{
2933 relay_url: "http://mastodon.example.org/users/admin"
2936 assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
2938 log_entry = Repo.one(ModerationLog)
2940 assert ModerationLog.get_log_entry_message(log_entry) ==
2941 "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
2944 test "GET /relay", %{admin: admin} do
2945 relay_user = Pleroma.Web.ActivityPub.Relay.get_actor()
2947 ["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
2948 |> Enum.each(fn ap_id ->
2949 {:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
2950 User.follow(relay_user, user)
2955 |> assign(:user, admin)
2956 |> get("/api/pleroma/admin/relay")
2958 assert json_response(conn, 200)["relays"] -- ["mastodon.example.org", "mstdn.io"] == []
2961 test "DELETE /relay", %{admin: admin} do
2963 |> assign(:user, admin)
2964 |> post("/api/pleroma/admin/relay", %{
2965 relay_url: "http://mastodon.example.org/users/admin"
2970 |> assign(:user, admin)
2971 |> delete("/api/pleroma/admin/relay", %{
2972 relay_url: "http://mastodon.example.org/users/admin"
2975 assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
2977 [log_entry_one, log_entry_two] = Repo.all(ModerationLog)
2979 assert ModerationLog.get_log_entry_message(log_entry_one) ==
2980 "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
2982 assert ModerationLog.get_log_entry_message(log_entry_two) ==
2983 "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
2987 describe "instances" do
2988 test "GET /instances/:instance/statuses" do
2989 admin = insert(:user, is_admin: true)
2990 user = insert(:user, local: false, nickname: "archaeme@archae.me")
2991 user2 = insert(:user, local: false, nickname: "test@test.com")
2992 insert_pair(:note_activity, user: user)
2993 insert(:note_activity, user: user2)
2997 |> assign(:user, admin)
2998 |> get("/api/pleroma/admin/instances/archae.me/statuses")
3000 response = json_response(conn, 200)
3002 assert length(response) == 2
3006 |> assign(:user, admin)
3007 |> get("/api/pleroma/admin/instances/test.com/statuses")
3009 response = json_response(conn, 200)
3011 assert length(response) == 1
3015 |> assign(:user, admin)
3016 |> get("/api/pleroma/admin/instances/nonexistent.com/statuses")
3018 response = json_response(conn, 200)
3020 assert length(response) == 0
3024 describe "PATCH /confirm_email" do
3025 setup %{conn: conn} do
3026 admin = insert(:user, is_admin: true)
3028 %{conn: assign(conn, :user, admin), admin: admin}
3031 test "it confirms emails of two users", %{admin: admin} do
3032 [first_user, second_user] = insert_pair(:user, confirmation_pending: true)
3034 assert first_user.confirmation_pending == true
3035 assert second_user.confirmation_pending == true
3038 |> assign(:user, admin)
3039 |> patch("/api/pleroma/admin/users/confirm_email", %{
3041 first_user.nickname,
3042 second_user.nickname
3046 assert first_user.confirmation_pending == true
3047 assert second_user.confirmation_pending == true
3049 log_entry = Repo.one(ModerationLog)
3051 assert ModerationLog.get_log_entry_message(log_entry) ==
3052 "@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{
3053 second_user.nickname
3058 describe "PATCH /resend_confirmation_email" do
3059 setup %{conn: conn} do
3060 admin = insert(:user, is_admin: true)
3062 %{conn: assign(conn, :user, admin), admin: admin}
3065 test "it resend emails for two users", %{admin: admin} do
3066 [first_user, second_user] = insert_pair(:user, confirmation_pending: true)
3069 |> assign(:user, admin)
3070 |> patch("/api/pleroma/admin/users/resend_confirmation_email", %{
3072 first_user.nickname,
3073 second_user.nickname
3077 log_entry = Repo.one(ModerationLog)
3079 assert ModerationLog.get_log_entry_message(log_entry) ==
3080 "@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{
3081 second_user.nickname
3087 # Needed for testing
3088 defmodule Pleroma.Web.Endpoint.NotReal do
3091 defmodule Pleroma.Captcha.NotReal do