1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 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
11 alias Pleroma.UserInviteToken
12 alias Pleroma.Web.CommonAPI
13 alias Pleroma.Web.MediaProxy
14 import Pleroma.Factory
16 describe "/api/pleroma/admin/users" do
18 admin = insert(:user, info: %{is_admin: true})
23 |> assign(:user, admin)
24 |> put_req_header("accept", "application/json")
25 |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
27 assert json_response(conn, 200) == user.nickname
31 admin = insert(:user, info: %{is_admin: true})
35 |> assign(:user, admin)
36 |> put_req_header("accept", "application/json")
37 |> post("/api/pleroma/admin/users", %{
39 "email" => "lain@example.org",
43 assert json_response(conn, 200) == "lain"
47 describe "/api/pleroma/admin/users/:nickname" do
48 test "Show", %{conn: conn} do
49 admin = insert(:user, info: %{is_admin: true})
54 |> assign(:user, admin)
55 |> get("/api/pleroma/admin/users/#{user.nickname}")
58 "deactivated" => false,
59 "id" => to_string(user.id),
61 "nickname" => user.nickname,
62 "roles" => %{"admin" => false, "moderator" => false},
64 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
65 "display_name" => HTML.strip_tags(user.name || user.nickname)
68 assert expected == json_response(conn, 200)
71 test "when the user doesn't exist", %{conn: conn} do
72 admin = insert(:user, info: %{is_admin: true})
77 |> assign(:user, admin)
78 |> get("/api/pleroma/admin/users/#{user.nickname}")
80 assert "Not found" == json_response(conn, 404)
84 describe "/api/pleroma/admin/users/follow" do
85 test "allows to force-follow another user" do
86 admin = insert(:user, info: %{is_admin: true})
88 follower = insert(:user)
91 |> assign(:user, admin)
92 |> put_req_header("accept", "application/json")
93 |> post("/api/pleroma/admin/users/follow", %{
94 "follower" => follower.nickname,
95 "followed" => user.nickname
98 user = User.get_cached_by_id(user.id)
99 follower = User.get_cached_by_id(follower.id)
101 assert User.following?(follower, user)
105 describe "/api/pleroma/admin/users/unfollow" do
106 test "allows to force-unfollow another user" do
107 admin = insert(:user, info: %{is_admin: true})
109 follower = insert(:user)
111 User.follow(follower, user)
114 |> assign(:user, admin)
115 |> put_req_header("accept", "application/json")
116 |> post("/api/pleroma/admin/users/unfollow", %{
117 "follower" => follower.nickname,
118 "followed" => user.nickname
121 user = User.get_cached_by_id(user.id)
122 follower = User.get_cached_by_id(follower.id)
124 refute User.following?(follower, user)
128 describe "PUT /api/pleroma/admin/users/tag" do
130 admin = insert(:user, info: %{is_admin: true})
131 user1 = insert(:user, %{tags: ["x"]})
132 user2 = insert(:user, %{tags: ["y"]})
133 user3 = insert(:user, %{tags: ["unchanged"]})
137 |> assign(:user, admin)
138 |> put_req_header("accept", "application/json")
140 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
142 }&tags[]=foo&tags[]=bar"
145 %{conn: conn, user1: user1, user2: user2, user3: user3}
148 test "it appends specified tags to users with specified nicknames", %{
153 assert json_response(conn, :no_content)
154 assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
155 assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
158 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
159 assert json_response(conn, :no_content)
160 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
164 describe "DELETE /api/pleroma/admin/users/tag" do
166 admin = insert(:user, info: %{is_admin: true})
167 user1 = insert(:user, %{tags: ["x"]})
168 user2 = insert(:user, %{tags: ["y", "z"]})
169 user3 = insert(:user, %{tags: ["unchanged"]})
173 |> assign(:user, admin)
174 |> put_req_header("accept", "application/json")
176 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
181 %{conn: conn, user1: user1, user2: user2, user3: user3}
184 test "it removes specified tags from users with specified nicknames", %{
189 assert json_response(conn, :no_content)
190 assert User.get_cached_by_id(user1.id).tags == []
191 assert User.get_cached_by_id(user2.id).tags == ["y"]
194 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
195 assert json_response(conn, :no_content)
196 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
200 describe "/api/pleroma/admin/users/:nickname/permission_group" do
201 test "GET is giving user_info" do
202 admin = insert(:user, info: %{is_admin: true})
206 |> assign(:user, admin)
207 |> put_req_header("accept", "application/json")
208 |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
210 assert json_response(conn, 200) == %{
212 "is_moderator" => false
216 test "/:right POST, can add to a permission group" do
217 admin = insert(:user, info: %{is_admin: true})
222 |> assign(:user, admin)
223 |> put_req_header("accept", "application/json")
224 |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
226 assert json_response(conn, 200) == %{
231 test "/:right DELETE, can remove from a permission group" do
232 admin = insert(:user, info: %{is_admin: true})
233 user = insert(:user, info: %{is_admin: true})
237 |> assign(:user, admin)
238 |> put_req_header("accept", "application/json")
239 |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
241 assert json_response(conn, 200) == %{
247 describe "PUT /api/pleroma/admin/users/:nickname/activation_status" do
248 setup %{conn: conn} do
249 admin = insert(:user, info: %{is_admin: true})
253 |> assign(:user, admin)
254 |> put_req_header("accept", "application/json")
259 test "deactivates the user", %{conn: conn} do
264 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
266 user = User.get_cached_by_id(user.id)
267 assert user.info.deactivated == true
268 assert json_response(conn, :no_content)
271 test "activates the user", %{conn: conn} do
272 user = insert(:user, info: %{deactivated: true})
276 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: true})
278 user = User.get_cached_by_id(user.id)
279 assert user.info.deactivated == false
280 assert json_response(conn, :no_content)
283 test "returns 403 when requested by a non-admin", %{conn: conn} do
288 |> assign(:user, user)
289 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
291 assert json_response(conn, :forbidden)
295 describe "POST /api/pleroma/admin/email_invite, with valid config" do
297 [user: insert(:user, info: %{is_admin: true})]
300 clear_config([:instance, :registrations_open]) do
301 Pleroma.Config.put([:instance, :registrations_open], false)
304 clear_config([:instance, :invites_enabled]) do
305 Pleroma.Config.put([:instance, :invites_enabled], true)
308 test "sends invitation and returns 204", %{conn: conn, user: user} do
309 recipient_email = "foo@bar.com"
310 recipient_name = "J. D."
314 |> assign(:user, user)
316 "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
319 assert json_response(conn, :no_content)
321 token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
323 refute token_record.used
325 notify_email = Pleroma.Config.get([:instance, :notify_email])
326 instance_name = Pleroma.Config.get([:instance, :name])
329 Pleroma.Emails.UserEmail.user_invitation_email(
336 Swoosh.TestAssertions.assert_email_sent(
337 from: {instance_name, notify_email},
338 to: {recipient_name, recipient_email},
339 html_body: email.html_body
343 test "it returns 403 if requested by a non-admin", %{conn: conn} do
344 non_admin_user = insert(:user)
348 |> assign(:user, non_admin_user)
349 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
351 assert json_response(conn, :forbidden)
355 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
357 [user: insert(:user, info: %{is_admin: true})]
360 clear_config([:instance, :registrations_open])
361 clear_config([:instance, :invites_enabled])
363 test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do
364 Pleroma.Config.put([:instance, :registrations_open], false)
365 Pleroma.Config.put([:instance, :invites_enabled], false)
369 |> assign(:user, user)
370 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
372 assert json_response(conn, :internal_server_error)
375 test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do
376 Pleroma.Config.put([:instance, :registrations_open], true)
377 Pleroma.Config.put([:instance, :invites_enabled], true)
381 |> assign(:user, user)
382 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
384 assert json_response(conn, :internal_server_error)
388 test "/api/pleroma/admin/users/invite_token" do
389 admin = insert(:user, info: %{is_admin: true})
393 |> assign(:user, admin)
394 |> put_req_header("accept", "application/json")
395 |> get("/api/pleroma/admin/users/invite_token")
397 assert conn.status == 200
400 test "/api/pleroma/admin/users/:nickname/password_reset" do
401 admin = insert(:user, info: %{is_admin: true})
406 |> assign(:user, admin)
407 |> put_req_header("accept", "application/json")
408 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
410 assert conn.status == 200
413 describe "GET /api/pleroma/admin/users" do
415 admin = insert(:user, info: %{is_admin: true})
419 |> assign(:user, admin)
421 {:ok, conn: conn, admin: admin}
424 test "renders users array for the first page", %{conn: conn, admin: admin} do
425 user = insert(:user, local: false, tags: ["foo", "bar"])
426 conn = get(conn, "/api/pleroma/admin/users?page=1")
431 "deactivated" => admin.info.deactivated,
433 "nickname" => admin.nickname,
434 "roles" => %{"admin" => true, "moderator" => false},
437 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
438 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
441 "deactivated" => user.info.deactivated,
443 "nickname" => user.nickname,
444 "roles" => %{"admin" => false, "moderator" => false},
446 "tags" => ["foo", "bar"],
447 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
448 "display_name" => HTML.strip_tags(user.name || user.nickname)
451 |> Enum.sort_by(& &1["nickname"])
453 assert json_response(conn, 200) == %{
460 test "renders empty array for the second page", %{conn: conn} do
463 conn = get(conn, "/api/pleroma/admin/users?page=2")
465 assert json_response(conn, 200) == %{
472 test "regular search", %{conn: conn} do
473 user = insert(:user, nickname: "bob")
475 conn = get(conn, "/api/pleroma/admin/users?query=bo")
477 assert json_response(conn, 200) == %{
482 "deactivated" => user.info.deactivated,
484 "nickname" => user.nickname,
485 "roles" => %{"admin" => false, "moderator" => false},
488 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
489 "display_name" => HTML.strip_tags(user.name || user.nickname)
495 test "search by domain", %{conn: conn} do
496 user = insert(:user, nickname: "nickname@domain.com")
499 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
501 assert json_response(conn, 200) == %{
506 "deactivated" => user.info.deactivated,
508 "nickname" => user.nickname,
509 "roles" => %{"admin" => false, "moderator" => false},
512 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
513 "display_name" => HTML.strip_tags(user.name || user.nickname)
519 test "search by full nickname", %{conn: conn} do
520 user = insert(:user, nickname: "nickname@domain.com")
523 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
525 assert json_response(conn, 200) == %{
530 "deactivated" => user.info.deactivated,
532 "nickname" => user.nickname,
533 "roles" => %{"admin" => false, "moderator" => false},
536 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
537 "display_name" => HTML.strip_tags(user.name || user.nickname)
543 test "search by display name", %{conn: conn} do
544 user = insert(:user, name: "Display name")
547 conn = get(conn, "/api/pleroma/admin/users?name=display")
549 assert json_response(conn, 200) == %{
554 "deactivated" => user.info.deactivated,
556 "nickname" => user.nickname,
557 "roles" => %{"admin" => false, "moderator" => false},
560 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
561 "display_name" => HTML.strip_tags(user.name || user.nickname)
567 test "search by email", %{conn: conn} do
568 user = insert(:user, email: "email@example.com")
571 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
573 assert json_response(conn, 200) == %{
578 "deactivated" => user.info.deactivated,
580 "nickname" => user.nickname,
581 "roles" => %{"admin" => false, "moderator" => false},
584 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
585 "display_name" => HTML.strip_tags(user.name || user.nickname)
591 test "regular search with page size", %{conn: conn} do
592 user = insert(:user, nickname: "aalice")
593 user2 = insert(:user, nickname: "alice")
595 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
597 assert json_response(conn1, 200) == %{
602 "deactivated" => user.info.deactivated,
604 "nickname" => user.nickname,
605 "roles" => %{"admin" => false, "moderator" => false},
608 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
609 "display_name" => HTML.strip_tags(user.name || user.nickname)
614 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
616 assert json_response(conn2, 200) == %{
621 "deactivated" => user2.info.deactivated,
623 "nickname" => user2.nickname,
624 "roles" => %{"admin" => false, "moderator" => false},
627 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
628 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
634 test "only local users" do
635 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
636 user = insert(:user, nickname: "bob")
638 insert(:user, nickname: "bobb", local: false)
642 |> assign(:user, admin)
643 |> get("/api/pleroma/admin/users?query=bo&filters=local")
645 assert json_response(conn, 200) == %{
650 "deactivated" => user.info.deactivated,
652 "nickname" => user.nickname,
653 "roles" => %{"admin" => false, "moderator" => false},
656 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
657 "display_name" => HTML.strip_tags(user.name || user.nickname)
663 test "only local users with no query", %{admin: old_admin} do
664 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
665 user = insert(:user, nickname: "bob")
667 insert(:user, nickname: "bobb", local: false)
671 |> assign(:user, admin)
672 |> get("/api/pleroma/admin/users?filters=local")
677 "deactivated" => user.info.deactivated,
679 "nickname" => user.nickname,
680 "roles" => %{"admin" => false, "moderator" => false},
683 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
684 "display_name" => HTML.strip_tags(user.name || user.nickname)
687 "deactivated" => admin.info.deactivated,
689 "nickname" => admin.nickname,
690 "roles" => %{"admin" => true, "moderator" => false},
693 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
694 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
697 "deactivated" => false,
698 "id" => old_admin.id,
700 "nickname" => old_admin.nickname,
701 "roles" => %{"admin" => true, "moderator" => false},
703 "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
704 "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname)
707 |> Enum.sort_by(& &1["nickname"])
709 assert json_response(conn, 200) == %{
716 test "load only admins", %{conn: conn, admin: admin} do
717 second_admin = insert(:user, info: %{is_admin: true})
721 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
726 "deactivated" => false,
728 "nickname" => admin.nickname,
729 "roles" => %{"admin" => true, "moderator" => false},
730 "local" => admin.local,
732 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
733 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
736 "deactivated" => false,
737 "id" => second_admin.id,
738 "nickname" => second_admin.nickname,
739 "roles" => %{"admin" => true, "moderator" => false},
740 "local" => second_admin.local,
742 "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
743 "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname)
746 |> Enum.sort_by(& &1["nickname"])
748 assert json_response(conn, 200) == %{
755 test "load only moderators", %{conn: conn} do
756 moderator = insert(:user, info: %{is_moderator: true})
760 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
762 assert json_response(conn, 200) == %{
767 "deactivated" => false,
768 "id" => moderator.id,
769 "nickname" => moderator.nickname,
770 "roles" => %{"admin" => false, "moderator" => true},
771 "local" => moderator.local,
773 "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
774 "display_name" => HTML.strip_tags(moderator.name || moderator.nickname)
780 test "load users with tags list", %{conn: conn} do
781 user1 = insert(:user, tags: ["first"])
782 user2 = insert(:user, tags: ["second"])
786 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
791 "deactivated" => false,
793 "nickname" => user1.nickname,
794 "roles" => %{"admin" => false, "moderator" => false},
795 "local" => user1.local,
797 "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
798 "display_name" => HTML.strip_tags(user1.name || user1.nickname)
801 "deactivated" => false,
803 "nickname" => user2.nickname,
804 "roles" => %{"admin" => false, "moderator" => false},
805 "local" => user2.local,
806 "tags" => ["second"],
807 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
808 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
811 |> Enum.sort_by(& &1["nickname"])
813 assert json_response(conn, 200) == %{
820 test "it works with multiple filters" do
821 admin = insert(:user, nickname: "john", info: %{is_admin: true})
822 user = insert(:user, nickname: "bob", local: false, info: %{deactivated: true})
824 insert(:user, nickname: "ken", local: true, info: %{deactivated: true})
825 insert(:user, nickname: "bobb", local: false, info: %{deactivated: false})
829 |> assign(:user, admin)
830 |> get("/api/pleroma/admin/users?filters=deactivated,external")
832 assert json_response(conn, 200) == %{
837 "deactivated" => user.info.deactivated,
839 "nickname" => user.nickname,
840 "roles" => %{"admin" => false, "moderator" => false},
841 "local" => user.local,
843 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
844 "display_name" => HTML.strip_tags(user.name || user.nickname)
851 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
852 admin = insert(:user, info: %{is_admin: true})
857 |> assign(:user, admin)
858 |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
860 assert json_response(conn, 200) ==
862 "deactivated" => !user.info.deactivated,
864 "nickname" => user.nickname,
865 "roles" => %{"admin" => false, "moderator" => false},
868 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
869 "display_name" => HTML.strip_tags(user.name || user.nickname)
873 describe "GET /api/pleroma/admin/users/invite_token" do
875 admin = insert(:user, info: %{is_admin: true})
879 |> assign(:user, admin)
884 test "without options", %{conn: conn} do
885 conn = get(conn, "/api/pleroma/admin/users/invite_token")
887 token = json_response(conn, 200)
888 invite = UserInviteToken.find_by_token!(token)
890 refute invite.expires_at
891 refute invite.max_use
892 assert invite.invite_type == "one_time"
895 test "with expires_at", %{conn: conn} do
897 get(conn, "/api/pleroma/admin/users/invite_token", %{
898 "invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
901 token = json_response(conn, 200)
902 invite = UserInviteToken.find_by_token!(token)
905 assert invite.expires_at == Date.utc_today()
906 refute invite.max_use
907 assert invite.invite_type == "date_limited"
910 test "with max_use", %{conn: conn} do
912 get(conn, "/api/pleroma/admin/users/invite_token", %{
913 "invite" => %{"max_use" => 150}
916 token = json_response(conn, 200)
917 invite = UserInviteToken.find_by_token!(token)
919 refute invite.expires_at
920 assert invite.max_use == 150
921 assert invite.invite_type == "reusable"
924 test "with max use and expires_at", %{conn: conn} do
926 get(conn, "/api/pleroma/admin/users/invite_token", %{
927 "invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
930 token = json_response(conn, 200)
931 invite = UserInviteToken.find_by_token!(token)
933 assert invite.expires_at == Date.utc_today()
934 assert invite.max_use == 150
935 assert invite.invite_type == "reusable_date_limited"
939 describe "GET /api/pleroma/admin/users/invites" do
941 admin = insert(:user, info: %{is_admin: true})
945 |> assign(:user, admin)
950 test "no invites", %{conn: conn} do
951 conn = get(conn, "/api/pleroma/admin/users/invites")
953 assert json_response(conn, 200) == %{"invites" => []}
956 test "with invite", %{conn: conn} do
957 {:ok, invite} = UserInviteToken.create_invite()
959 conn = get(conn, "/api/pleroma/admin/users/invites")
961 assert json_response(conn, 200) == %{
966 "invite_type" => "one_time",
968 "token" => invite.token,
977 describe "POST /api/pleroma/admin/users/revoke_invite" do
979 admin = insert(:user, info: %{is_admin: true})
980 {:ok, invite} = UserInviteToken.create_invite()
984 |> assign(:user, admin)
985 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
987 assert json_response(conn, 200) == %{
990 "invite_type" => "one_time",
992 "token" => invite.token,
998 test "with invalid token" do
999 admin = insert(:user, info: %{is_admin: true})
1003 |> assign(:user, admin)
1004 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
1006 assert json_response(conn, :not_found) == "Not found"
1010 describe "GET /api/pleroma/admin/reports/:id" do
1011 setup %{conn: conn} do
1012 admin = insert(:user, info: %{is_admin: true})
1014 %{conn: assign(conn, :user, admin)}
1017 test "returns report by its id", %{conn: conn} do
1018 [reporter, target_user] = insert_pair(:user)
1019 activity = insert(:note_activity, user: target_user)
1021 {:ok, %{id: report_id}} =
1022 CommonAPI.report(reporter, %{
1023 "account_id" => target_user.id,
1024 "comment" => "I feel offended",
1025 "status_ids" => [activity.id]
1030 |> get("/api/pleroma/admin/reports/#{report_id}")
1031 |> json_response(:ok)
1033 assert response["id"] == report_id
1036 test "returns 404 when report id is invalid", %{conn: conn} do
1037 conn = get(conn, "/api/pleroma/admin/reports/test")
1039 assert json_response(conn, :not_found) == "Not found"
1043 describe "PUT /api/pleroma/admin/reports/:id" do
1044 setup %{conn: conn} do
1045 admin = insert(:user, info: %{is_admin: true})
1046 [reporter, target_user] = insert_pair(:user)
1047 activity = insert(:note_activity, user: target_user)
1049 {:ok, %{id: report_id}} =
1050 CommonAPI.report(reporter, %{
1051 "account_id" => target_user.id,
1052 "comment" => "I feel offended",
1053 "status_ids" => [activity.id]
1056 %{conn: assign(conn, :user, admin), id: report_id}
1059 test "mark report as resolved", %{conn: conn, id: id} do
1062 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
1063 |> json_response(:ok)
1065 assert response["state"] == "resolved"
1068 test "closes report", %{conn: conn, id: id} do
1071 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
1072 |> json_response(:ok)
1074 assert response["state"] == "closed"
1077 test "returns 400 when state is unknown", %{conn: conn, id: id} do
1080 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"})
1082 assert json_response(conn, :bad_request) == "Unsupported state"
1085 test "returns 404 when report is not exist", %{conn: conn} do
1088 |> put("/api/pleroma/admin/reports/test", %{"state" => "closed"})
1090 assert json_response(conn, :not_found) == "Not found"
1094 describe "GET /api/pleroma/admin/reports" do
1095 setup %{conn: conn} do
1096 admin = insert(:user, info: %{is_admin: true})
1098 %{conn: assign(conn, :user, admin)}
1101 test "returns empty response when no reports created", %{conn: conn} do
1104 |> get("/api/pleroma/admin/reports")
1105 |> json_response(:ok)
1107 assert Enum.empty?(response["reports"])
1110 test "returns reports", %{conn: conn} do
1111 [reporter, target_user] = insert_pair(:user)
1112 activity = insert(:note_activity, user: target_user)
1114 {:ok, %{id: report_id}} =
1115 CommonAPI.report(reporter, %{
1116 "account_id" => target_user.id,
1117 "comment" => "I feel offended",
1118 "status_ids" => [activity.id]
1123 |> get("/api/pleroma/admin/reports")
1124 |> json_response(:ok)
1126 [report] = response["reports"]
1128 assert length(response["reports"]) == 1
1129 assert report["id"] == report_id
1132 test "returns reports with specified state", %{conn: conn} do
1133 [reporter, target_user] = insert_pair(:user)
1134 activity = insert(:note_activity, user: target_user)
1136 {:ok, %{id: first_report_id}} =
1137 CommonAPI.report(reporter, %{
1138 "account_id" => target_user.id,
1139 "comment" => "I feel offended",
1140 "status_ids" => [activity.id]
1143 {:ok, %{id: second_report_id}} =
1144 CommonAPI.report(reporter, %{
1145 "account_id" => target_user.id,
1146 "comment" => "I don't like this user"
1149 CommonAPI.update_report_state(second_report_id, "closed")
1153 |> get("/api/pleroma/admin/reports", %{
1156 |> json_response(:ok)
1158 [open_report] = response["reports"]
1160 assert length(response["reports"]) == 1
1161 assert open_report["id"] == first_report_id
1165 |> get("/api/pleroma/admin/reports", %{
1168 |> json_response(:ok)
1170 [closed_report] = response["reports"]
1172 assert length(response["reports"]) == 1
1173 assert closed_report["id"] == second_report_id
1177 |> get("/api/pleroma/admin/reports", %{
1178 "state" => "resolved"
1180 |> json_response(:ok)
1182 assert Enum.empty?(response["reports"])
1185 test "returns 403 when requested by a non-admin" do
1186 user = insert(:user)
1190 |> assign(:user, user)
1191 |> get("/api/pleroma/admin/reports")
1193 assert json_response(conn, :forbidden) == %{"error" => "User is not admin."}
1196 test "returns 403 when requested by anonymous" do
1199 |> get("/api/pleroma/admin/reports")
1201 assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
1205 describe "POST /api/pleroma/admin/reports/:id/respond" do
1206 setup %{conn: conn} do
1207 admin = insert(:user, info: %{is_admin: true})
1209 %{conn: assign(conn, :user, admin)}
1212 test "returns created dm", %{conn: conn} do
1213 [reporter, target_user] = insert_pair(:user)
1214 activity = insert(:note_activity, user: target_user)
1216 {:ok, %{id: report_id}} =
1217 CommonAPI.report(reporter, %{
1218 "account_id" => target_user.id,
1219 "comment" => "I feel offended",
1220 "status_ids" => [activity.id]
1225 |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
1226 "status" => "I will check it out"
1228 |> json_response(:ok)
1230 recipients = Enum.map(response["mentions"], & &1["username"])
1232 assert reporter.nickname in recipients
1233 assert response["content"] == "I will check it out"
1234 assert response["visibility"] == "direct"
1237 test "returns 400 when status is missing", %{conn: conn} do
1238 conn = post(conn, "/api/pleroma/admin/reports/test/respond")
1240 assert json_response(conn, :bad_request) == "Invalid parameters"
1243 test "returns 404 when report id is invalid", %{conn: conn} do
1245 post(conn, "/api/pleroma/admin/reports/test/respond", %{
1249 assert json_response(conn, :not_found) == "Not found"
1253 describe "PUT /api/pleroma/admin/statuses/:id" do
1254 setup %{conn: conn} do
1255 admin = insert(:user, info: %{is_admin: true})
1256 activity = insert(:note_activity)
1258 %{conn: assign(conn, :user, admin), id: activity.id}
1261 test "toggle sensitive flag", %{conn: conn, id: id} do
1264 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
1265 |> json_response(:ok)
1267 assert response["sensitive"]
1271 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
1272 |> json_response(:ok)
1274 refute response["sensitive"]
1277 test "change visibility flag", %{conn: conn, id: id} do
1280 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
1281 |> json_response(:ok)
1283 assert response["visibility"] == "public"
1287 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
1288 |> json_response(:ok)
1290 assert response["visibility"] == "private"
1294 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"})
1295 |> json_response(:ok)
1297 assert response["visibility"] == "unlisted"
1300 test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
1303 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"})
1305 assert json_response(conn, :bad_request) == "Unsupported visibility"
1309 describe "DELETE /api/pleroma/admin/statuses/:id" do
1310 setup %{conn: conn} do
1311 admin = insert(:user, info: %{is_admin: true})
1312 activity = insert(:note_activity)
1314 %{conn: assign(conn, :user, admin), id: activity.id}
1317 test "deletes status", %{conn: conn, id: id} do
1319 |> delete("/api/pleroma/admin/statuses/#{id}")
1320 |> json_response(:ok)
1322 refute Activity.get_by_id(id)
1325 test "returns error when status is not exist", %{conn: conn} do
1328 |> delete("/api/pleroma/admin/statuses/test")
1330 assert json_response(conn, :bad_request) == "Could not delete"
1334 describe "GET /api/pleroma/admin/config" do
1335 setup %{conn: conn} do
1336 admin = insert(:user, info: %{is_admin: true})
1338 %{conn: assign(conn, :user, admin)}
1341 test "without any settings in db", %{conn: conn} do
1342 conn = get(conn, "/api/pleroma/admin/config")
1344 assert json_response(conn, 200) == %{"configs" => []}
1347 test "with settings in db", %{conn: conn} do
1348 config1 = insert(:config)
1349 config2 = insert(:config)
1351 conn = get(conn, "/api/pleroma/admin/config")
1364 } = json_response(conn, 200)
1366 assert key1 == config1.key
1367 assert key2 == config2.key
1371 describe "POST /api/pleroma/admin/config" do
1372 setup %{conn: conn} do
1373 admin = insert(:user, info: %{is_admin: true})
1375 temp_file = "config/test.exported_from_db.secret.exs"
1378 Application.delete_env(:pleroma, :key1)
1379 Application.delete_env(:pleroma, :key2)
1380 Application.delete_env(:pleroma, :key3)
1381 Application.delete_env(:pleroma, :key4)
1382 Application.delete_env(:pleroma, :keyaa1)
1383 Application.delete_env(:pleroma, :keyaa2)
1384 Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
1385 Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
1386 :ok = File.rm(temp_file)
1389 %{conn: assign(conn, :user, admin)}
1392 clear_config([:instance, :dynamic_configuration]) do
1393 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1396 test "create new config setting in db", %{conn: conn} do
1398 post(conn, "/api/pleroma/admin/config", %{
1400 %{group: "pleroma", key: "key1", value: "value1"},
1403 key: "Ueberauth.Strategy.Twitter.OAuth",
1404 value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
1410 ":nested_1" => "nested_value1",
1412 %{":nested_22" => "nested_value222"},
1413 %{":nested_33" => %{":nested_44" => "nested_444"}}
1421 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1422 %{"nested_4" => true}
1428 value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
1433 value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1438 assert json_response(conn, 200) == %{
1441 "group" => "pleroma",
1446 "group" => "ueberauth",
1447 "key" => "Ueberauth.Strategy.Twitter.OAuth",
1448 "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}]
1451 "group" => "pleroma",
1454 ":nested_1" => "nested_value1",
1456 %{":nested_22" => "nested_value222"},
1457 %{":nested_33" => %{":nested_44" => "nested_444"}}
1462 "group" => "pleroma",
1465 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1466 %{"nested_4" => true}
1470 "group" => "pleroma",
1472 "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}
1477 "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1482 assert Application.get_env(:pleroma, :key1) == "value1"
1484 assert Application.get_env(:pleroma, :key2) == %{
1485 nested_1: "nested_value1",
1487 %{nested_22: "nested_value222"},
1488 %{nested_33: %{nested_44: "nested_444"}}
1492 assert Application.get_env(:pleroma, :key3) == [
1493 %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
1494 %{"nested_4" => true}
1497 assert Application.get_env(:pleroma, :key4) == %{
1498 "endpoint" => "https://example.com",
1502 assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
1505 test "update config setting & delete", %{conn: conn} do
1506 config1 = insert(:config, key: "keyaa1")
1507 config2 = insert(:config, key: "keyaa2")
1511 key: "Ueberauth.Strategy.Microsoft.OAuth",
1512 value: :erlang.term_to_binary([])
1516 post(conn, "/api/pleroma/admin/config", %{
1518 %{group: config1.group, key: config1.key, value: "another_value"},
1519 %{group: config2.group, key: config2.key, delete: "true"},
1522 key: "Ueberauth.Strategy.Microsoft.OAuth",
1528 assert json_response(conn, 200) == %{
1531 "group" => "pleroma",
1532 "key" => config1.key,
1533 "value" => "another_value"
1538 assert Application.get_env(:pleroma, :keyaa1) == "another_value"
1539 refute Application.get_env(:pleroma, :keyaa2)
1542 test "common config example", %{conn: conn} do
1544 post(conn, "/api/pleroma/admin/config", %{
1547 "group" => "pleroma",
1548 "key" => "Pleroma.Captcha.NotReal",
1550 %{"tuple" => [":enabled", false]},
1551 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1552 %{"tuple" => [":seconds_valid", 60]},
1553 %{"tuple" => [":path", ""]},
1554 %{"tuple" => [":key1", nil]},
1555 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}
1561 assert json_response(conn, 200) == %{
1564 "group" => "pleroma",
1565 "key" => "Pleroma.Captcha.NotReal",
1567 %{"tuple" => [":enabled", false]},
1568 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1569 %{"tuple" => [":seconds_valid", 60]},
1570 %{"tuple" => [":path", ""]},
1571 %{"tuple" => [":key1", nil]},
1572 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}
1579 test "tuples with more than two values", %{conn: conn} do
1581 post(conn, "/api/pleroma/admin/config", %{
1584 "group" => "pleroma",
1585 "key" => "Pleroma.Web.Endpoint.NotReal",
1601 "/api/v1/streaming",
1602 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1609 "Phoenix.Endpoint.CowboyWebSocket",
1612 "Phoenix.Transports.WebSocket",
1615 "Pleroma.Web.Endpoint",
1616 "Pleroma.Web.UserSocket",
1627 "Phoenix.Endpoint.Cowboy2Handler",
1628 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1645 assert json_response(conn, 200) == %{
1648 "group" => "pleroma",
1649 "key" => "Pleroma.Web.Endpoint.NotReal",
1665 "/api/v1/streaming",
1666 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1673 "Phoenix.Endpoint.CowboyWebSocket",
1676 "Phoenix.Transports.WebSocket",
1679 "Pleroma.Web.Endpoint",
1680 "Pleroma.Web.UserSocket",
1691 "Phoenix.Endpoint.Cowboy2Handler",
1692 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1710 test "settings with nesting map", %{conn: conn} do
1712 post(conn, "/api/pleroma/admin/config", %{
1715 "group" => "pleroma",
1718 %{"tuple" => [":key2", "some_val"]},
1723 ":max_options" => 20,
1724 ":max_option_chars" => 200,
1725 ":min_expiration" => 0,
1726 ":max_expiration" => 31_536_000,
1728 ":max_options" => 20,
1729 ":max_option_chars" => 200,
1730 ":min_expiration" => 0,
1731 ":max_expiration" => 31_536_000
1741 assert json_response(conn, 200) ==
1745 "group" => "pleroma",
1748 %{"tuple" => [":key2", "some_val"]},
1753 ":max_expiration" => 31_536_000,
1754 ":max_option_chars" => 200,
1755 ":max_options" => 20,
1756 ":min_expiration" => 0,
1758 ":max_expiration" => 31_536_000,
1759 ":max_option_chars" => 200,
1760 ":max_options" => 20,
1761 ":min_expiration" => 0
1772 test "value as map", %{conn: conn} do
1774 post(conn, "/api/pleroma/admin/config", %{
1777 "group" => "pleroma",
1779 "value" => %{"key" => "some_val"}
1784 assert json_response(conn, 200) ==
1788 "group" => "pleroma",
1790 "value" => %{"key" => "some_val"}
1796 test "dispatch setting", %{conn: conn} do
1798 post(conn, "/api/pleroma/admin/config", %{
1801 "group" => "pleroma",
1802 "key" => "Pleroma.Web.Endpoint.NotReal",
1808 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
1809 %{"tuple" => [":dispatch", ["{:_,
1811 {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
1812 {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket,
1813 {Phoenix.Transports.WebSocket,
1814 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}},
1815 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
1826 "{:_, [{\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, " <>
1827 "{\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, " <>
1828 "{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, " <>
1829 "{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}]}"
1831 assert json_response(conn, 200) == %{
1834 "group" => "pleroma",
1835 "key" => "Pleroma.Web.Endpoint.NotReal",
1841 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
1859 test "queues key as atom", %{conn: conn} do
1861 post(conn, "/api/pleroma/admin/config", %{
1867 %{"tuple" => [":federator_incoming", 50]},
1868 %{"tuple" => [":federator_outgoing", 50]},
1869 %{"tuple" => [":web_push", 50]},
1870 %{"tuple" => [":mailer", 10]},
1871 %{"tuple" => [":transmogrifier", 20]},
1872 %{"tuple" => [":scheduled_activities", 10]},
1873 %{"tuple" => [":background", 5]}
1879 assert json_response(conn, 200) == %{
1885 %{"tuple" => [":federator_incoming", 50]},
1886 %{"tuple" => [":federator_outgoing", 50]},
1887 %{"tuple" => [":web_push", 50]},
1888 %{"tuple" => [":mailer", 10]},
1889 %{"tuple" => [":transmogrifier", 20]},
1890 %{"tuple" => [":scheduled_activities", 10]},
1891 %{"tuple" => [":background", 5]}
1898 test "delete part of settings by atom subkeys", %{conn: conn} do
1902 value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3")
1906 post(conn, "/api/pleroma/admin/config", %{
1909 group: config.group,
1911 subkeys: [":subkey1", ":subkey3"],
1918 json_response(conn, 200) == %{
1921 "group" => "pleroma",
1923 "value" => [%{"tuple" => [":subkey2", "val2"]}]
1931 describe "config mix tasks run" do
1932 setup %{conn: conn} do
1933 admin = insert(:user, info: %{is_admin: true})
1935 temp_file = "config/test.exported_from_db.secret.exs"
1937 Mix.shell(Mix.Shell.Quiet)
1940 Mix.shell(Mix.Shell.IO)
1941 :ok = File.rm(temp_file)
1944 %{conn: assign(conn, :user, admin), admin: admin}
1947 clear_config([:instance, :dynamic_configuration]) do
1948 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1951 test "transfer settings to DB and to file", %{conn: conn, admin: admin} do
1952 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
1953 conn = get(conn, "/api/pleroma/admin/config/migrate_to_db")
1954 assert json_response(conn, 200) == %{}
1955 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) > 0
1959 |> assign(:user, admin)
1960 |> get("/api/pleroma/admin/config/migrate_from_db")
1962 assert json_response(conn, 200) == %{}
1963 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
1967 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
1969 admin = insert(:user, info: %{is_admin: true})
1970 user = insert(:user)
1972 date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
1973 date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
1974 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
1976 insert(:note_activity, user: user, published: date1)
1977 insert(:note_activity, user: user, published: date2)
1978 insert(:note_activity, user: user, published: date3)
1982 |> assign(:user, admin)
1984 {:ok, conn: conn, user: user}
1987 test "renders user's statuses", %{conn: conn, user: user} do
1988 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
1990 assert json_response(conn, 200) |> length() == 3
1993 test "renders user's statuses with a limit", %{conn: conn, user: user} do
1994 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
1996 assert json_response(conn, 200) |> length() == 2
1999 test "doesn't return private statuses by default", %{conn: conn, user: user} do
2000 {:ok, _private_status} =
2001 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2003 {:ok, _public_status} =
2004 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2006 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2008 assert json_response(conn, 200) |> length() == 4
2011 test "returns private statuses with godmode on", %{conn: conn, user: user} do
2012 {:ok, _private_status} =
2013 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2015 {:ok, _public_status} =
2016 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2018 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
2020 assert json_response(conn, 200) |> length() == 5
2025 # Needed for testing
2026 defmodule Pleroma.Web.Endpoint.NotReal do
2029 defmodule Pleroma.Captcha.NotReal do