1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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
9 import ExUnit.CaptureLog
11 import Pleroma.Factory
13 alias Pleroma.Activity
17 alias Pleroma.ModerationLog
19 alias Pleroma.Tests.ObanHelpers
22 alias Pleroma.Web.ActivityPub.Relay
23 alias Pleroma.Web.CommonAPI
24 alias Pleroma.Web.MediaProxy
27 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
33 admin = insert(:user, is_admin: true)
34 token = insert(:oauth_admin_token, user: admin)
38 |> assign(:user, admin)
39 |> assign(:token, token)
41 {:ok, %{admin: admin, token: token, conn: conn}}
44 describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
45 setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
47 test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
50 url = "/api/pleroma/admin/users/#{user.nickname}"
52 good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
53 good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
54 good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
56 bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
57 bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
60 for good_token <- [good_token1, good_token2, good_token3] do
63 |> assign(:user, admin)
64 |> assign(:token, good_token)
67 assert json_response(conn, 200)
70 for good_token <- [good_token1, good_token2, good_token3] do
74 |> assign(:token, good_token)
77 assert json_response(conn, :forbidden)
80 for bad_token <- [bad_token1, bad_token2, bad_token3] do
83 |> assign(:user, admin)
84 |> assign(:token, bad_token)
87 assert json_response(conn, :forbidden)
92 describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
93 setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
95 test "GET /api/pleroma/admin/users/:nickname requires " <>
96 "read:accounts or admin:read:accounts or broader scope",
99 url = "/api/pleroma/admin/users/#{user.nickname}"
101 good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
102 good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
103 good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
104 good_token4 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
105 good_token5 = insert(:oauth_token, user: admin, scopes: ["read"])
107 good_tokens = [good_token1, good_token2, good_token3, good_token4, good_token5]
109 bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts:partial"])
110 bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
113 for good_token <- good_tokens do
116 |> assign(:user, admin)
117 |> assign(:token, good_token)
120 assert json_response(conn, 200)
123 for good_token <- good_tokens do
126 |> assign(:user, nil)
127 |> assign(:token, good_token)
130 assert json_response(conn, :forbidden)
133 for bad_token <- [bad_token1, bad_token2, bad_token3] do
136 |> assign(:user, admin)
137 |> assign(:token, bad_token)
140 assert json_response(conn, :forbidden)
145 describe "DELETE /api/pleroma/admin/users" do
146 test "single user", %{admin: admin, conn: conn} do
148 clear_config([:instance, :federating], true)
150 with_mock Pleroma.Web.Federator,
151 publish: fn _ -> nil end do
154 |> put_req_header("accept", "application/json")
155 |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
157 ObanHelpers.perform_all()
159 assert User.get_by_nickname(user.nickname).deactivated
161 log_entry = Repo.one(ModerationLog)
163 assert ModerationLog.get_log_entry_message(log_entry) ==
164 "@#{admin.nickname} deleted users: @#{user.nickname}"
166 assert json_response(conn, 200) == [user.nickname]
168 assert called(Pleroma.Web.Federator.publish(:_))
172 test "multiple users", %{admin: admin, conn: conn} do
173 user_one = insert(:user)
174 user_two = insert(:user)
178 |> put_req_header("accept", "application/json")
179 |> delete("/api/pleroma/admin/users", %{
180 nicknames: [user_one.nickname, user_two.nickname]
183 log_entry = Repo.one(ModerationLog)
185 assert ModerationLog.get_log_entry_message(log_entry) ==
186 "@#{admin.nickname} deleted users: @#{user_one.nickname}, @#{user_two.nickname}"
188 response = json_response(conn, 200)
189 assert response -- [user_one.nickname, user_two.nickname] == []
193 describe "/api/pleroma/admin/users" do
194 test "Create", %{conn: conn} do
197 |> put_req_header("accept", "application/json")
198 |> post("/api/pleroma/admin/users", %{
201 "nickname" => "lain",
202 "email" => "lain@example.org",
206 "nickname" => "lain2",
207 "email" => "lain2@example.org",
213 response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
214 assert response == ["success", "success"]
216 log_entry = Repo.one(ModerationLog)
218 assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
221 test "Cannot create user with existing email", %{conn: conn} do
226 |> put_req_header("accept", "application/json")
227 |> post("/api/pleroma/admin/users", %{
230 "nickname" => "lain",
231 "email" => user.email,
237 assert json_response(conn, 409) == [
241 "email" => user.email,
244 "error" => "email has already been taken",
250 test "Cannot create user with existing nickname", %{conn: conn} do
255 |> put_req_header("accept", "application/json")
256 |> post("/api/pleroma/admin/users", %{
259 "nickname" => user.nickname,
260 "email" => "someuser@plerama.social",
266 assert json_response(conn, 409) == [
270 "email" => "someuser@plerama.social",
271 "nickname" => user.nickname
273 "error" => "nickname has already been taken",
279 test "Multiple user creation works in transaction", %{conn: conn} do
284 |> put_req_header("accept", "application/json")
285 |> post("/api/pleroma/admin/users", %{
288 "nickname" => "newuser",
289 "email" => "newuser@pleroma.social",
293 "nickname" => "lain",
294 "email" => user.email,
300 assert json_response(conn, 409) == [
304 "email" => user.email,
307 "error" => "email has already been taken",
313 "email" => "newuser@pleroma.social",
314 "nickname" => "newuser"
321 assert User.get_by_nickname("newuser") === nil
325 describe "/api/pleroma/admin/users/:nickname" do
326 test "Show", %{conn: conn} do
329 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}")
332 "deactivated" => false,
333 "id" => to_string(user.id),
335 "nickname" => user.nickname,
336 "roles" => %{"admin" => false, "moderator" => false},
338 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
339 "display_name" => HTML.strip_tags(user.name || user.nickname),
340 "confirmation_pending" => false,
341 "approval_pending" => false,
343 "registration_reason" => nil
346 assert expected == json_response(conn, 200)
349 test "when the user doesn't exist", %{conn: conn} do
352 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}")
354 assert %{"error" => "Not found"} == json_response(conn, 404)
358 describe "/api/pleroma/admin/users/follow" do
359 test "allows to force-follow another user", %{admin: admin, conn: conn} do
361 follower = insert(:user)
364 |> put_req_header("accept", "application/json")
365 |> post("/api/pleroma/admin/users/follow", %{
366 "follower" => follower.nickname,
367 "followed" => user.nickname
370 user = User.get_cached_by_id(user.id)
371 follower = User.get_cached_by_id(follower.id)
373 assert User.following?(follower, user)
375 log_entry = Repo.one(ModerationLog)
377 assert ModerationLog.get_log_entry_message(log_entry) ==
378 "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
382 describe "/api/pleroma/admin/users/unfollow" do
383 test "allows to force-unfollow another user", %{admin: admin, conn: conn} do
385 follower = insert(:user)
387 User.follow(follower, user)
390 |> put_req_header("accept", "application/json")
391 |> post("/api/pleroma/admin/users/unfollow", %{
392 "follower" => follower.nickname,
393 "followed" => user.nickname
396 user = User.get_cached_by_id(user.id)
397 follower = User.get_cached_by_id(follower.id)
399 refute User.following?(follower, user)
401 log_entry = Repo.one(ModerationLog)
403 assert ModerationLog.get_log_entry_message(log_entry) ==
404 "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
408 describe "PUT /api/pleroma/admin/users/tag" do
409 setup %{conn: conn} do
410 user1 = insert(:user, %{tags: ["x"]})
411 user2 = insert(:user, %{tags: ["y"]})
412 user3 = insert(:user, %{tags: ["unchanged"]})
416 |> put_req_header("accept", "application/json")
418 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
419 "#{user2.nickname}&tags[]=foo&tags[]=bar"
422 %{conn: conn, user1: user1, user2: user2, user3: user3}
425 test "it appends specified tags to users with specified nicknames", %{
431 assert json_response(conn, :no_content)
432 assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
433 assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
435 log_entry = Repo.one(ModerationLog)
438 [user1.nickname, user2.nickname]
439 |> Enum.map(&"@#{&1}")
442 tags = ["foo", "bar"] |> Enum.join(", ")
444 assert ModerationLog.get_log_entry_message(log_entry) ==
445 "@#{admin.nickname} added tags: #{tags} to users: #{users}"
448 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
449 assert json_response(conn, :no_content)
450 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
454 describe "DELETE /api/pleroma/admin/users/tag" do
455 setup %{conn: conn} do
456 user1 = insert(:user, %{tags: ["x"]})
457 user2 = insert(:user, %{tags: ["y", "z"]})
458 user3 = insert(:user, %{tags: ["unchanged"]})
462 |> put_req_header("accept", "application/json")
464 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
465 "#{user2.nickname}&tags[]=x&tags[]=z"
468 %{conn: conn, user1: user1, user2: user2, user3: user3}
471 test "it removes specified tags from users with specified nicknames", %{
477 assert json_response(conn, :no_content)
478 assert User.get_cached_by_id(user1.id).tags == []
479 assert User.get_cached_by_id(user2.id).tags == ["y"]
481 log_entry = Repo.one(ModerationLog)
484 [user1.nickname, user2.nickname]
485 |> Enum.map(&"@#{&1}")
488 tags = ["x", "z"] |> Enum.join(", ")
490 assert ModerationLog.get_log_entry_message(log_entry) ==
491 "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
494 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
495 assert json_response(conn, :no_content)
496 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
500 describe "/api/pleroma/admin/users/:nickname/permission_group" do
501 test "GET is giving user_info", %{admin: admin, conn: conn} do
504 |> put_req_header("accept", "application/json")
505 |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
507 assert json_response(conn, 200) == %{
509 "is_moderator" => false
513 test "/:right POST, can add to a permission group", %{admin: admin, conn: conn} do
518 |> put_req_header("accept", "application/json")
519 |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
521 assert json_response(conn, 200) == %{
525 log_entry = Repo.one(ModerationLog)
527 assert ModerationLog.get_log_entry_message(log_entry) ==
528 "@#{admin.nickname} made @#{user.nickname} admin"
531 test "/:right POST, can add to a permission group (multiple)", %{admin: admin, conn: conn} do
532 user_one = insert(:user)
533 user_two = insert(:user)
537 |> put_req_header("accept", "application/json")
538 |> post("/api/pleroma/admin/users/permission_group/admin", %{
539 nicknames: [user_one.nickname, user_two.nickname]
542 assert json_response(conn, 200) == %{"is_admin" => true}
544 log_entry = Repo.one(ModerationLog)
546 assert ModerationLog.get_log_entry_message(log_entry) ==
547 "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin"
550 test "/:right DELETE, can remove from a permission group", %{admin: admin, conn: conn} do
551 user = insert(:user, is_admin: true)
555 |> put_req_header("accept", "application/json")
556 |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
558 assert json_response(conn, 200) == %{"is_admin" => false}
560 log_entry = Repo.one(ModerationLog)
562 assert ModerationLog.get_log_entry_message(log_entry) ==
563 "@#{admin.nickname} revoked admin role from @#{user.nickname}"
566 test "/:right DELETE, can remove from a permission group (multiple)", %{
570 user_one = insert(:user, is_admin: true)
571 user_two = insert(:user, is_admin: true)
575 |> put_req_header("accept", "application/json")
576 |> delete("/api/pleroma/admin/users/permission_group/admin", %{
577 nicknames: [user_one.nickname, user_two.nickname]
580 assert json_response(conn, 200) == %{"is_admin" => false}
582 log_entry = Repo.one(ModerationLog)
584 assert ModerationLog.get_log_entry_message(log_entry) ==
585 "@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{
591 test "/api/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do
596 |> put_req_header("accept", "application/json")
597 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
599 resp = json_response(conn, 200)
601 assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
604 describe "GET /api/pleroma/admin/users" do
605 test "renders users array for the first page", %{conn: conn, admin: admin} do
606 user = insert(:user, local: false, tags: ["foo", "bar"])
607 user2 = insert(:user, approval_pending: true, registration_reason: "I'm a chill dude")
609 conn = get(conn, "/api/pleroma/admin/users?page=1")
614 "deactivated" => admin.deactivated,
616 "nickname" => admin.nickname,
617 "roles" => %{"admin" => true, "moderator" => false},
620 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
621 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
622 "confirmation_pending" => false,
623 "approval_pending" => false,
624 "url" => admin.ap_id,
625 "registration_reason" => nil
628 "deactivated" => user.deactivated,
630 "nickname" => user.nickname,
631 "roles" => %{"admin" => false, "moderator" => false},
633 "tags" => ["foo", "bar"],
634 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
635 "display_name" => HTML.strip_tags(user.name || user.nickname),
636 "confirmation_pending" => false,
637 "approval_pending" => false,
639 "registration_reason" => nil
642 "deactivated" => user2.deactivated,
644 "nickname" => user2.nickname,
645 "roles" => %{"admin" => false, "moderator" => false},
648 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
649 "display_name" => HTML.strip_tags(user2.name || user2.nickname),
650 "confirmation_pending" => false,
651 "approval_pending" => true,
652 "url" => user2.ap_id,
653 "registration_reason" => "I'm a chill dude"
656 |> Enum.sort_by(& &1["nickname"])
658 assert json_response(conn, 200) == %{
665 test "pagination works correctly with service users", %{conn: conn} do
666 service1 = User.get_or_create_service_actor_by_ap_id(Web.base_url() <> "/meido", "meido")
668 insert_list(25, :user)
670 assert %{"count" => 26, "page_size" => 10, "users" => users1} =
672 |> get("/api/pleroma/admin/users?page=1&filters=", %{page_size: "10"})
673 |> json_response(200)
675 assert Enum.count(users1) == 10
676 assert service1 not in users1
678 assert %{"count" => 26, "page_size" => 10, "users" => users2} =
680 |> get("/api/pleroma/admin/users?page=2&filters=", %{page_size: "10"})
681 |> json_response(200)
683 assert Enum.count(users2) == 10
684 assert service1 not in users2
686 assert %{"count" => 26, "page_size" => 10, "users" => users3} =
688 |> get("/api/pleroma/admin/users?page=3&filters=", %{page_size: "10"})
689 |> json_response(200)
691 assert Enum.count(users3) == 6
692 assert service1 not in users3
695 test "renders empty array for the second page", %{conn: conn} do
698 conn = get(conn, "/api/pleroma/admin/users?page=2")
700 assert json_response(conn, 200) == %{
707 test "regular search", %{conn: conn} do
708 user = insert(:user, nickname: "bob")
710 conn = get(conn, "/api/pleroma/admin/users?query=bo")
712 assert json_response(conn, 200) == %{
717 "deactivated" => user.deactivated,
719 "nickname" => user.nickname,
720 "roles" => %{"admin" => false, "moderator" => false},
723 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
724 "display_name" => HTML.strip_tags(user.name || user.nickname),
725 "confirmation_pending" => false,
726 "approval_pending" => false,
728 "registration_reason" => nil
734 test "search by domain", %{conn: conn} do
735 user = insert(:user, nickname: "nickname@domain.com")
738 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
740 assert json_response(conn, 200) == %{
745 "deactivated" => user.deactivated,
747 "nickname" => user.nickname,
748 "roles" => %{"admin" => false, "moderator" => false},
751 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
752 "display_name" => HTML.strip_tags(user.name || user.nickname),
753 "confirmation_pending" => false,
754 "approval_pending" => false,
756 "registration_reason" => nil
762 test "search by full nickname", %{conn: conn} do
763 user = insert(:user, nickname: "nickname@domain.com")
766 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
768 assert json_response(conn, 200) == %{
773 "deactivated" => user.deactivated,
775 "nickname" => user.nickname,
776 "roles" => %{"admin" => false, "moderator" => false},
779 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
780 "display_name" => HTML.strip_tags(user.name || user.nickname),
781 "confirmation_pending" => false,
782 "approval_pending" => false,
784 "registration_reason" => nil
790 test "search by display name", %{conn: conn} do
791 user = insert(:user, name: "Display name")
794 conn = get(conn, "/api/pleroma/admin/users?name=display")
796 assert json_response(conn, 200) == %{
801 "deactivated" => user.deactivated,
803 "nickname" => user.nickname,
804 "roles" => %{"admin" => false, "moderator" => false},
807 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
808 "display_name" => HTML.strip_tags(user.name || user.nickname),
809 "confirmation_pending" => false,
810 "approval_pending" => false,
812 "registration_reason" => nil
818 test "search by email", %{conn: conn} do
819 user = insert(:user, email: "email@example.com")
822 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
824 assert json_response(conn, 200) == %{
829 "deactivated" => user.deactivated,
831 "nickname" => user.nickname,
832 "roles" => %{"admin" => false, "moderator" => false},
835 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
836 "display_name" => HTML.strip_tags(user.name || user.nickname),
837 "confirmation_pending" => false,
838 "approval_pending" => false,
840 "registration_reason" => nil
846 test "regular search with page size", %{conn: conn} do
847 user = insert(:user, nickname: "aalice")
848 user2 = insert(:user, nickname: "alice")
850 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
852 assert json_response(conn1, 200) == %{
857 "deactivated" => user.deactivated,
859 "nickname" => user.nickname,
860 "roles" => %{"admin" => false, "moderator" => false},
863 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
864 "display_name" => HTML.strip_tags(user.name || user.nickname),
865 "confirmation_pending" => false,
866 "approval_pending" => false,
868 "registration_reason" => nil
873 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
875 assert json_response(conn2, 200) == %{
880 "deactivated" => user2.deactivated,
882 "nickname" => user2.nickname,
883 "roles" => %{"admin" => false, "moderator" => false},
886 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
887 "display_name" => HTML.strip_tags(user2.name || user2.nickname),
888 "confirmation_pending" => false,
889 "approval_pending" => false,
890 "url" => user2.ap_id,
891 "registration_reason" => nil
897 test "only local users" do
898 admin = insert(:user, is_admin: true, nickname: "john")
899 token = insert(:oauth_admin_token, user: admin)
900 user = insert(:user, nickname: "bob")
902 insert(:user, nickname: "bobb", local: false)
906 |> assign(:user, admin)
907 |> assign(:token, token)
908 |> get("/api/pleroma/admin/users?query=bo&filters=local")
910 assert json_response(conn, 200) == %{
915 "deactivated" => user.deactivated,
917 "nickname" => user.nickname,
918 "roles" => %{"admin" => false, "moderator" => false},
921 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
922 "display_name" => HTML.strip_tags(user.name || user.nickname),
923 "confirmation_pending" => false,
924 "approval_pending" => false,
926 "registration_reason" => nil
932 test "only local users with no query", %{conn: conn, admin: old_admin} do
933 admin = insert(:user, is_admin: true, nickname: "john")
934 user = insert(:user, nickname: "bob")
936 insert(:user, nickname: "bobb", local: false)
938 conn = get(conn, "/api/pleroma/admin/users?filters=local")
943 "deactivated" => user.deactivated,
945 "nickname" => user.nickname,
946 "roles" => %{"admin" => false, "moderator" => false},
949 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
950 "display_name" => HTML.strip_tags(user.name || user.nickname),
951 "confirmation_pending" => false,
952 "approval_pending" => false,
954 "registration_reason" => nil
957 "deactivated" => admin.deactivated,
959 "nickname" => admin.nickname,
960 "roles" => %{"admin" => true, "moderator" => false},
963 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
964 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
965 "confirmation_pending" => false,
966 "approval_pending" => false,
967 "url" => admin.ap_id,
968 "registration_reason" => nil
971 "deactivated" => false,
972 "id" => old_admin.id,
974 "nickname" => old_admin.nickname,
975 "roles" => %{"admin" => true, "moderator" => false},
977 "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
978 "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname),
979 "confirmation_pending" => false,
980 "approval_pending" => false,
981 "url" => old_admin.ap_id,
982 "registration_reason" => nil
985 |> Enum.sort_by(& &1["nickname"])
987 assert json_response(conn, 200) == %{
994 test "only unapproved users", %{conn: conn} do
998 approval_pending: true,
999 registration_reason: "Plz let me in!"
1002 insert(:user, nickname: "happyboy", approval_pending: false)
1004 conn = get(conn, "/api/pleroma/admin/users?filters=need_approval")
1009 "deactivated" => user.deactivated,
1011 "nickname" => user.nickname,
1012 "roles" => %{"admin" => false, "moderator" => false},
1015 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1016 "display_name" => HTML.strip_tags(user.name || user.nickname),
1017 "confirmation_pending" => false,
1018 "approval_pending" => true,
1019 "url" => user.ap_id,
1020 "registration_reason" => "Plz let me in!"
1023 |> Enum.sort_by(& &1["nickname"])
1025 assert json_response(conn, 200) == %{
1032 test "load only admins", %{conn: conn, admin: admin} do
1033 second_admin = insert(:user, is_admin: true)
1037 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
1042 "deactivated" => false,
1044 "nickname" => admin.nickname,
1045 "roles" => %{"admin" => true, "moderator" => false},
1046 "local" => admin.local,
1048 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
1049 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
1050 "confirmation_pending" => false,
1051 "approval_pending" => false,
1052 "url" => admin.ap_id,
1053 "registration_reason" => nil
1056 "deactivated" => false,
1057 "id" => second_admin.id,
1058 "nickname" => second_admin.nickname,
1059 "roles" => %{"admin" => true, "moderator" => false},
1060 "local" => second_admin.local,
1062 "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
1063 "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname),
1064 "confirmation_pending" => false,
1065 "approval_pending" => false,
1066 "url" => second_admin.ap_id,
1067 "registration_reason" => nil
1070 |> Enum.sort_by(& &1["nickname"])
1072 assert json_response(conn, 200) == %{
1079 test "load only moderators", %{conn: conn} do
1080 moderator = insert(:user, is_moderator: true)
1084 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
1086 assert json_response(conn, 200) == %{
1091 "deactivated" => false,
1092 "id" => moderator.id,
1093 "nickname" => moderator.nickname,
1094 "roles" => %{"admin" => false, "moderator" => true},
1095 "local" => moderator.local,
1097 "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
1098 "display_name" => HTML.strip_tags(moderator.name || moderator.nickname),
1099 "confirmation_pending" => false,
1100 "approval_pending" => false,
1101 "url" => moderator.ap_id,
1102 "registration_reason" => nil
1108 test "load users with tags list", %{conn: conn} do
1109 user1 = insert(:user, tags: ["first"])
1110 user2 = insert(:user, tags: ["second"])
1114 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
1119 "deactivated" => false,
1121 "nickname" => user1.nickname,
1122 "roles" => %{"admin" => false, "moderator" => false},
1123 "local" => user1.local,
1124 "tags" => ["first"],
1125 "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
1126 "display_name" => HTML.strip_tags(user1.name || user1.nickname),
1127 "confirmation_pending" => false,
1128 "approval_pending" => false,
1129 "url" => user1.ap_id,
1130 "registration_reason" => nil
1133 "deactivated" => false,
1135 "nickname" => user2.nickname,
1136 "roles" => %{"admin" => false, "moderator" => false},
1137 "local" => user2.local,
1138 "tags" => ["second"],
1139 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
1140 "display_name" => HTML.strip_tags(user2.name || user2.nickname),
1141 "confirmation_pending" => false,
1142 "approval_pending" => false,
1143 "url" => user2.ap_id,
1144 "registration_reason" => nil
1147 |> Enum.sort_by(& &1["nickname"])
1149 assert json_response(conn, 200) == %{
1156 test "it works with multiple filters" do
1157 admin = insert(:user, nickname: "john", is_admin: true)
1158 token = insert(:oauth_admin_token, user: admin)
1159 user = insert(:user, nickname: "bob", local: false, deactivated: true)
1161 insert(:user, nickname: "ken", local: true, deactivated: true)
1162 insert(:user, nickname: "bobb", local: false, deactivated: false)
1166 |> assign(:user, admin)
1167 |> assign(:token, token)
1168 |> get("/api/pleroma/admin/users?filters=deactivated,external")
1170 assert json_response(conn, 200) == %{
1175 "deactivated" => user.deactivated,
1177 "nickname" => user.nickname,
1178 "roles" => %{"admin" => false, "moderator" => false},
1179 "local" => user.local,
1181 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1182 "display_name" => HTML.strip_tags(user.name || user.nickname),
1183 "confirmation_pending" => false,
1184 "approval_pending" => false,
1185 "url" => user.ap_id,
1186 "registration_reason" => nil
1192 test "it omits relay user", %{admin: admin, conn: conn} do
1193 assert %User{} = Relay.get_actor()
1195 conn = get(conn, "/api/pleroma/admin/users")
1197 assert json_response(conn, 200) == %{
1202 "deactivated" => admin.deactivated,
1204 "nickname" => admin.nickname,
1205 "roles" => %{"admin" => true, "moderator" => false},
1208 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
1209 "display_name" => HTML.strip_tags(admin.name || admin.nickname),
1210 "confirmation_pending" => false,
1211 "approval_pending" => false,
1212 "url" => admin.ap_id,
1213 "registration_reason" => nil
1220 test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do
1221 user_one = insert(:user, deactivated: true)
1222 user_two = insert(:user, deactivated: true)
1227 "/api/pleroma/admin/users/activate",
1228 %{nicknames: [user_one.nickname, user_two.nickname]}
1231 response = json_response(conn, 200)
1232 assert Enum.map(response["users"], & &1["deactivated"]) == [false, false]
1234 log_entry = Repo.one(ModerationLog)
1236 assert ModerationLog.get_log_entry_message(log_entry) ==
1237 "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
1240 test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do
1241 user_one = insert(:user, deactivated: false)
1242 user_two = insert(:user, deactivated: false)
1247 "/api/pleroma/admin/users/deactivate",
1248 %{nicknames: [user_one.nickname, user_two.nickname]}
1251 response = json_response(conn, 200)
1252 assert Enum.map(response["users"], & &1["deactivated"]) == [true, true]
1254 log_entry = Repo.one(ModerationLog)
1256 assert ModerationLog.get_log_entry_message(log_entry) ==
1257 "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
1260 test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do
1261 user_one = insert(:user, approval_pending: true)
1262 user_two = insert(:user, approval_pending: true)
1267 "/api/pleroma/admin/users/approve",
1268 %{nicknames: [user_one.nickname, user_two.nickname]}
1271 response = json_response(conn, 200)
1272 assert Enum.map(response["users"], & &1["approval_pending"]) == [false, false]
1274 log_entry = Repo.one(ModerationLog)
1276 assert ModerationLog.get_log_entry_message(log_entry) ==
1277 "@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}"
1280 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
1281 user = insert(:user)
1283 conn = patch(conn, "/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
1285 assert json_response(conn, 200) ==
1287 "deactivated" => !user.deactivated,
1289 "nickname" => user.nickname,
1290 "roles" => %{"admin" => false, "moderator" => false},
1293 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1294 "display_name" => HTML.strip_tags(user.name || user.nickname),
1295 "confirmation_pending" => false,
1296 "approval_pending" => false,
1297 "url" => user.ap_id,
1298 "registration_reason" => nil
1301 log_entry = Repo.one(ModerationLog)
1303 assert ModerationLog.get_log_entry_message(log_entry) ==
1304 "@#{admin.nickname} deactivated users: @#{user.nickname}"
1307 describe "PUT disable_mfa" do
1308 test "returns 200 and disable 2fa", %{conn: conn} do
1311 multi_factor_authentication_settings: %MFA.Settings{
1313 totp: %MFA.Settings.TOTP{secret: "otp_secret", confirmed: true}
1319 |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: user.nickname})
1320 |> json_response(200)
1322 assert response == user.nickname
1323 mfa_settings = refresh_record(user).multi_factor_authentication_settings
1325 refute mfa_settings.enabled
1326 refute mfa_settings.totp.confirmed
1329 test "returns 404 if user not found", %{conn: conn} do
1332 |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"})
1333 |> json_response(404)
1335 assert response == %{"error" => "Not found"}
1339 describe "GET /api/pleroma/admin/restart" do
1340 setup do: clear_config(:configurable_from_database, true)
1342 test "pleroma restarts", %{conn: conn} do
1344 assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{}
1345 end) =~ "pleroma restarted"
1347 refute Restarter.Pleroma.need_reboot?()
1351 test "need_reboot flag", %{conn: conn} do
1353 |> get("/api/pleroma/admin/need_reboot")
1354 |> json_response(200) == %{"need_reboot" => false}
1356 Restarter.Pleroma.need_reboot()
1359 |> get("/api/pleroma/admin/need_reboot")
1360 |> json_response(200) == %{"need_reboot" => true}
1362 on_exit(fn -> Restarter.Pleroma.refresh() end)
1365 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
1367 user = insert(:user)
1369 date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
1370 date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
1371 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
1373 insert(:note_activity, user: user, published: date1)
1374 insert(:note_activity, user: user, published: date2)
1375 insert(:note_activity, user: user, published: date3)
1380 test "renders user's statuses", %{conn: conn, user: user} do
1381 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
1383 assert json_response(conn, 200) |> length() == 3
1386 test "renders user's statuses with a limit", %{conn: conn, user: user} do
1387 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
1389 assert json_response(conn, 200) |> length() == 2
1392 test "doesn't return private statuses by default", %{conn: conn, user: user} do
1393 {:ok, _private_status} = CommonAPI.post(user, %{status: "private", visibility: "private"})
1395 {:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
1397 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
1399 assert json_response(conn, 200) |> length() == 4
1402 test "returns private statuses with godmode on", %{conn: conn, user: user} do
1403 {:ok, _private_status} = CommonAPI.post(user, %{status: "private", visibility: "private"})
1405 {:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
1407 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
1409 assert json_response(conn, 200) |> length() == 5
1412 test "excludes reblogs by default", %{conn: conn, user: user} do
1413 other_user = insert(:user)
1414 {:ok, activity} = CommonAPI.post(user, %{status: "."})
1415 {:ok, %Activity{}} = CommonAPI.repeat(activity.id, other_user)
1417 conn_res = get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses")
1418 assert json_response(conn_res, 200) |> length() == 0
1421 get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses?with_reblogs=true")
1423 assert json_response(conn_res, 200) |> length() == 1
1427 describe "GET /api/pleroma/admin/moderation_log" do
1429 moderator = insert(:user, is_moderator: true)
1431 %{moderator: moderator}
1434 test "returns the log", %{conn: conn, admin: admin} do
1435 Repo.insert(%ModerationLog{
1439 "nickname" => admin.nickname,
1442 action: "relay_follow",
1443 target: "https://example.org/relay"
1445 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
1448 Repo.insert(%ModerationLog{
1452 "nickname" => admin.nickname,
1455 action: "relay_unfollow",
1456 target: "https://example.org/relay"
1458 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
1461 conn = get(conn, "/api/pleroma/admin/moderation_log")
1463 response = json_response(conn, 200)
1464 [first_entry, second_entry] = response["items"]
1466 assert response["total"] == 2
1467 assert first_entry["data"]["action"] == "relay_unfollow"
1469 assert first_entry["message"] ==
1470 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
1472 assert second_entry["data"]["action"] == "relay_follow"
1474 assert second_entry["message"] ==
1475 "@#{admin.nickname} followed relay: https://example.org/relay"
1478 test "returns the log with pagination", %{conn: conn, admin: admin} do
1479 Repo.insert(%ModerationLog{
1483 "nickname" => admin.nickname,
1486 action: "relay_follow",
1487 target: "https://example.org/relay"
1489 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
1492 Repo.insert(%ModerationLog{
1496 "nickname" => admin.nickname,
1499 action: "relay_unfollow",
1500 target: "https://example.org/relay"
1502 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
1505 conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
1507 response1 = json_response(conn1, 200)
1508 [first_entry] = response1["items"]
1510 assert response1["total"] == 2
1511 assert response1["items"] |> length() == 1
1512 assert first_entry["data"]["action"] == "relay_unfollow"
1514 assert first_entry["message"] ==
1515 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
1517 conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
1519 response2 = json_response(conn2, 200)
1520 [second_entry] = response2["items"]
1522 assert response2["total"] == 2
1523 assert response2["items"] |> length() == 1
1524 assert second_entry["data"]["action"] == "relay_follow"
1526 assert second_entry["message"] ==
1527 "@#{admin.nickname} followed relay: https://example.org/relay"
1530 test "filters log by date", %{conn: conn, admin: admin} do
1531 first_date = "2017-08-15T15:47:06Z"
1532 second_date = "2017-08-20T15:47:06Z"
1534 Repo.insert(%ModerationLog{
1538 "nickname" => admin.nickname,
1541 action: "relay_follow",
1542 target: "https://example.org/relay"
1544 inserted_at: NaiveDateTime.from_iso8601!(first_date)
1547 Repo.insert(%ModerationLog{
1551 "nickname" => admin.nickname,
1554 action: "relay_unfollow",
1555 target: "https://example.org/relay"
1557 inserted_at: NaiveDateTime.from_iso8601!(second_date)
1563 "/api/pleroma/admin/moderation_log?start_date=#{second_date}"
1566 response1 = json_response(conn1, 200)
1567 [first_entry] = response1["items"]
1569 assert response1["total"] == 1
1570 assert first_entry["data"]["action"] == "relay_unfollow"
1572 assert first_entry["message"] ==
1573 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
1576 test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
1577 Repo.insert(%ModerationLog{
1581 "nickname" => admin.nickname,
1584 action: "relay_follow",
1585 target: "https://example.org/relay"
1589 Repo.insert(%ModerationLog{
1592 "id" => moderator.id,
1593 "nickname" => moderator.nickname,
1596 action: "relay_unfollow",
1597 target: "https://example.org/relay"
1601 conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
1603 response1 = json_response(conn1, 200)
1604 [first_entry] = response1["items"]
1606 assert response1["total"] == 1
1607 assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
1610 test "returns log filtered by search", %{conn: conn, moderator: moderator} do
1611 ModerationLog.insert_log(%{
1613 action: "relay_follow",
1614 target: "https://example.org/relay"
1617 ModerationLog.insert_log(%{
1619 action: "relay_unfollow",
1620 target: "https://example.org/relay"
1623 conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
1625 response1 = json_response(conn1, 200)
1626 [first_entry] = response1["items"]
1628 assert response1["total"] == 1
1630 assert get_in(first_entry, ["data", "message"]) ==
1631 "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
1635 test "gets a remote users when [:instance, :limit_to_local_content] is set to :unauthenticated",
1637 clear_config(Pleroma.Config.get([:instance, :limit_to_local_content]), :unauthenticated)
1638 user = insert(:user, %{local: false, nickname: "u@peer1.com"})
1639 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
1641 assert json_response(conn, 200)
1644 describe "GET /users/:nickname/credentials" do
1645 test "gets the user credentials", %{conn: conn} do
1646 user = insert(:user)
1647 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
1649 response = assert json_response(conn, 200)
1650 assert response["email"] == user.email
1653 test "returns 403 if requested by a non-admin" do
1654 user = insert(:user)
1658 |> assign(:user, user)
1659 |> get("/api/pleroma/admin/users/#{user.nickname}/credentials")
1661 assert json_response(conn, :forbidden)
1665 describe "PATCH /users/:nickname/credentials" do
1667 user = insert(:user)
1671 test "changes password and email", %{conn: conn, admin: admin, user: user} do
1672 assert user.password_reset_pending == false
1675 patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
1676 "password" => "new_password",
1677 "email" => "new_email@example.com",
1678 "name" => "new_name"
1681 assert json_response(conn, 200) == %{"status" => "success"}
1683 ObanHelpers.perform_all()
1685 updated_user = User.get_by_id(user.id)
1687 assert updated_user.email == "new_email@example.com"
1688 assert updated_user.name == "new_name"
1689 assert updated_user.password_hash != user.password_hash
1690 assert updated_user.password_reset_pending == true
1692 [log_entry2, log_entry1] = ModerationLog |> Repo.all() |> Enum.sort()
1694 assert ModerationLog.get_log_entry_message(log_entry1) ==
1695 "@#{admin.nickname} updated users: @#{user.nickname}"
1697 assert ModerationLog.get_log_entry_message(log_entry2) ==
1698 "@#{admin.nickname} forced password reset for users: @#{user.nickname}"
1701 test "returns 403 if requested by a non-admin", %{user: user} do
1704 |> assign(:user, user)
1705 |> patch("/api/pleroma/admin/users/#{user.nickname}/credentials", %{
1706 "password" => "new_password",
1707 "email" => "new_email@example.com",
1708 "name" => "new_name"
1711 assert json_response(conn, :forbidden)
1714 test "changes actor type from permitted list", %{conn: conn, user: user} do
1715 assert user.actor_type == "Person"
1717 assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
1718 "actor_type" => "Service"
1720 |> json_response(200) == %{"status" => "success"}
1722 updated_user = User.get_by_id(user.id)
1724 assert updated_user.actor_type == "Service"
1726 assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
1727 "actor_type" => "Application"
1729 |> json_response(400) == %{"errors" => %{"actor_type" => "is invalid"}}
1732 test "update non existing user", %{conn: conn} do
1733 assert patch(conn, "/api/pleroma/admin/users/non-existing/credentials", %{
1734 "password" => "new_password"
1736 |> json_response(404) == %{"error" => "Not found"}
1740 describe "PATCH /users/:nickname/force_password_reset" do
1741 test "sets password_reset_pending to true", %{conn: conn} do
1742 user = insert(:user)
1743 assert user.password_reset_pending == false
1746 patch(conn, "/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]})
1748 assert json_response(conn, 204) == ""
1750 ObanHelpers.perform_all()
1752 assert User.get_by_id(user.id).password_reset_pending == true
1756 describe "instances" do
1757 test "GET /instances/:instance/statuses", %{conn: conn} do
1758 user = insert(:user, local: false, nickname: "archaeme@archae.me")
1759 user2 = insert(:user, local: false, nickname: "test@test.com")
1760 insert_pair(:note_activity, user: user)
1761 activity = insert(:note_activity, user: user2)
1763 ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses")
1765 response = json_response(ret_conn, 200)
1767 assert length(response) == 2
1769 ret_conn = get(conn, "/api/pleroma/admin/instances/test.com/statuses")
1771 response = json_response(ret_conn, 200)
1773 assert length(response) == 1
1775 ret_conn = get(conn, "/api/pleroma/admin/instances/nonexistent.com/statuses")
1777 response = json_response(ret_conn, 200)
1779 assert Enum.empty?(response)
1781 CommonAPI.repeat(activity.id, user)
1783 ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses")
1784 response = json_response(ret_conn, 200)
1785 assert length(response) == 2
1787 ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses?with_reblogs=true")
1788 response = json_response(ret_conn, 200)
1789 assert length(response) == 3
1793 describe "PATCH /confirm_email" do
1794 test "it confirms emails of two users", %{conn: conn, admin: admin} do
1795 [first_user, second_user] = insert_pair(:user, confirmation_pending: true)
1797 assert first_user.confirmation_pending == true
1798 assert second_user.confirmation_pending == true
1801 patch(conn, "/api/pleroma/admin/users/confirm_email", %{
1803 first_user.nickname,
1804 second_user.nickname
1808 assert ret_conn.status == 200
1810 assert first_user.confirmation_pending == true
1811 assert second_user.confirmation_pending == true
1813 log_entry = Repo.one(ModerationLog)
1815 assert ModerationLog.get_log_entry_message(log_entry) ==
1816 "@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{
1817 second_user.nickname
1822 describe "PATCH /resend_confirmation_email" do
1823 test "it resend emails for two users", %{conn: conn, admin: admin} do
1824 [first_user, second_user] = insert_pair(:user, confirmation_pending: true)
1827 patch(conn, "/api/pleroma/admin/users/resend_confirmation_email", %{
1829 first_user.nickname,
1830 second_user.nickname
1834 assert ret_conn.status == 200
1836 log_entry = Repo.one(ModerationLog)
1838 assert ModerationLog.get_log_entry_message(log_entry) ==
1839 "@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{
1840 second_user.nickname
1845 describe "/api/pleroma/admin/stats" do
1846 test "status visibility count", %{conn: conn} do
1847 admin = insert(:user, is_admin: true)
1848 user = insert(:user)
1849 CommonAPI.post(user, %{visibility: "public", status: "hey"})
1850 CommonAPI.post(user, %{visibility: "unlisted", status: "hey"})
1851 CommonAPI.post(user, %{visibility: "unlisted", status: "hey"})
1855 |> assign(:user, admin)
1856 |> get("/api/pleroma/admin/stats")
1857 |> json_response(200)
1859 assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 2} =
1860 response["status_visibility"]
1863 test "by instance", %{conn: conn} do
1864 admin = insert(:user, is_admin: true)
1865 user1 = insert(:user)
1866 instance2 = "instance2.tld"
1867 user2 = insert(:user, %{ap_id: "https://#{instance2}/@actor"})
1869 CommonAPI.post(user1, %{visibility: "public", status: "hey"})
1870 CommonAPI.post(user2, %{visibility: "unlisted", status: "hey"})
1871 CommonAPI.post(user2, %{visibility: "private", status: "hey"})
1875 |> assign(:user, admin)
1876 |> get("/api/pleroma/admin/stats", instance: instance2)
1877 |> json_response(200)
1879 assert %{"direct" => 0, "private" => 1, "public" => 0, "unlisted" => 1} =
1880 response["status_visibility"]
1885 # Needed for testing
1886 defmodule Pleroma.Web.Endpoint.NotReal do
1889 defmodule Pleroma.Captcha.NotReal do