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 registrations_open = Pleroma.Config.get([:instance, :registrations_open])
298 invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
299 Pleroma.Config.put([:instance, :registrations_open], false)
300 Pleroma.Config.put([:instance, :invites_enabled], true)
303 Pleroma.Config.put([:instance, :registrations_open], registrations_open)
304 Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
308 [user: insert(:user, info: %{is_admin: true})]
311 test "sends invitation and returns 204", %{conn: conn, user: user} do
312 recipient_email = "foo@bar.com"
313 recipient_name = "J. D."
317 |> assign(:user, user)
319 "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
322 assert json_response(conn, :no_content)
324 token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
326 refute token_record.used
328 notify_email = Pleroma.Config.get([:instance, :notify_email])
329 instance_name = Pleroma.Config.get([:instance, :name])
332 Pleroma.Emails.UserEmail.user_invitation_email(
339 Swoosh.TestAssertions.assert_email_sent(
340 from: {instance_name, notify_email},
341 to: {recipient_name, recipient_email},
342 html_body: email.html_body
346 test "it returns 403 if requested by a non-admin", %{conn: conn} do
347 non_admin_user = insert(:user)
351 |> assign(:user, non_admin_user)
352 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
354 assert json_response(conn, :forbidden)
358 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
360 [user: insert(:user, info: %{is_admin: true})]
363 test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do
364 registrations_open = Pleroma.Config.get([:instance, :registrations_open])
365 invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
366 Pleroma.Config.put([:instance, :registrations_open], false)
367 Pleroma.Config.put([:instance, :invites_enabled], false)
370 Pleroma.Config.put([:instance, :registrations_open], registrations_open)
371 Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
377 |> assign(:user, user)
378 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
380 assert json_response(conn, :internal_server_error)
383 test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do
384 registrations_open = Pleroma.Config.get([:instance, :registrations_open])
385 invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
386 Pleroma.Config.put([:instance, :registrations_open], true)
387 Pleroma.Config.put([:instance, :invites_enabled], true)
390 Pleroma.Config.put([:instance, :registrations_open], registrations_open)
391 Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
397 |> assign(:user, user)
398 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
400 assert json_response(conn, :internal_server_error)
404 test "/api/pleroma/admin/users/invite_token" do
405 admin = insert(:user, info: %{is_admin: true})
409 |> assign(:user, admin)
410 |> put_req_header("accept", "application/json")
411 |> get("/api/pleroma/admin/users/invite_token")
413 assert conn.status == 200
416 test "/api/pleroma/admin/users/:nickname/password_reset" do
417 admin = insert(:user, info: %{is_admin: true})
422 |> assign(:user, admin)
423 |> put_req_header("accept", "application/json")
424 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
426 assert conn.status == 200
429 describe "GET /api/pleroma/admin/users" do
431 admin = insert(:user, info: %{is_admin: true})
435 |> assign(:user, admin)
437 {:ok, conn: conn, admin: admin}
440 test "renders users array for the first page", %{conn: conn, admin: admin} do
441 user = insert(:user, local: false, tags: ["foo", "bar"])
442 conn = get(conn, "/api/pleroma/admin/users?page=1")
447 "deactivated" => admin.info.deactivated,
449 "nickname" => admin.nickname,
450 "roles" => %{"admin" => true, "moderator" => false},
453 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
454 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
457 "deactivated" => user.info.deactivated,
459 "nickname" => user.nickname,
460 "roles" => %{"admin" => false, "moderator" => false},
462 "tags" => ["foo", "bar"],
463 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
464 "display_name" => HTML.strip_tags(user.name || user.nickname)
467 |> Enum.sort_by(& &1["nickname"])
469 assert json_response(conn, 200) == %{
476 test "renders empty array for the second page", %{conn: conn} do
479 conn = get(conn, "/api/pleroma/admin/users?page=2")
481 assert json_response(conn, 200) == %{
488 test "regular search", %{conn: conn} do
489 user = insert(:user, nickname: "bob")
491 conn = get(conn, "/api/pleroma/admin/users?query=bo")
493 assert json_response(conn, 200) == %{
498 "deactivated" => user.info.deactivated,
500 "nickname" => user.nickname,
501 "roles" => %{"admin" => false, "moderator" => false},
504 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
505 "display_name" => HTML.strip_tags(user.name || user.nickname)
511 test "search by domain", %{conn: conn} do
512 user = insert(:user, nickname: "nickname@domain.com")
515 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
517 assert json_response(conn, 200) == %{
522 "deactivated" => user.info.deactivated,
524 "nickname" => user.nickname,
525 "roles" => %{"admin" => false, "moderator" => false},
528 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
529 "display_name" => HTML.strip_tags(user.name || user.nickname)
535 test "search by full nickname", %{conn: conn} do
536 user = insert(:user, nickname: "nickname@domain.com")
539 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
541 assert json_response(conn, 200) == %{
546 "deactivated" => user.info.deactivated,
548 "nickname" => user.nickname,
549 "roles" => %{"admin" => false, "moderator" => false},
552 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
553 "display_name" => HTML.strip_tags(user.name || user.nickname)
559 test "search by display name", %{conn: conn} do
560 user = insert(:user, name: "Display name")
563 conn = get(conn, "/api/pleroma/admin/users?name=display")
565 assert json_response(conn, 200) == %{
570 "deactivated" => user.info.deactivated,
572 "nickname" => user.nickname,
573 "roles" => %{"admin" => false, "moderator" => false},
576 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
577 "display_name" => HTML.strip_tags(user.name || user.nickname)
583 test "search by email", %{conn: conn} do
584 user = insert(:user, email: "email@example.com")
587 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
589 assert json_response(conn, 200) == %{
594 "deactivated" => user.info.deactivated,
596 "nickname" => user.nickname,
597 "roles" => %{"admin" => false, "moderator" => false},
600 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
601 "display_name" => HTML.strip_tags(user.name || user.nickname)
607 test "regular search with page size", %{conn: conn} do
608 user = insert(:user, nickname: "aalice")
609 user2 = insert(:user, nickname: "alice")
611 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
613 assert json_response(conn1, 200) == %{
618 "deactivated" => user.info.deactivated,
620 "nickname" => user.nickname,
621 "roles" => %{"admin" => false, "moderator" => false},
624 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
625 "display_name" => HTML.strip_tags(user.name || user.nickname)
630 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
632 assert json_response(conn2, 200) == %{
637 "deactivated" => user2.info.deactivated,
639 "nickname" => user2.nickname,
640 "roles" => %{"admin" => false, "moderator" => false},
643 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
644 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
650 test "only local users" do
651 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
652 user = insert(:user, nickname: "bob")
654 insert(:user, nickname: "bobb", local: false)
658 |> assign(:user, admin)
659 |> get("/api/pleroma/admin/users?query=bo&filters=local")
661 assert json_response(conn, 200) == %{
666 "deactivated" => user.info.deactivated,
668 "nickname" => user.nickname,
669 "roles" => %{"admin" => false, "moderator" => false},
672 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
673 "display_name" => HTML.strip_tags(user.name || user.nickname)
679 test "only local users with no query", %{admin: old_admin} do
680 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
681 user = insert(:user, nickname: "bob")
683 insert(:user, nickname: "bobb", local: false)
687 |> assign(:user, admin)
688 |> get("/api/pleroma/admin/users?filters=local")
693 "deactivated" => user.info.deactivated,
695 "nickname" => user.nickname,
696 "roles" => %{"admin" => false, "moderator" => false},
699 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
700 "display_name" => HTML.strip_tags(user.name || user.nickname)
703 "deactivated" => admin.info.deactivated,
705 "nickname" => admin.nickname,
706 "roles" => %{"admin" => true, "moderator" => false},
709 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
710 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
713 "deactivated" => false,
714 "id" => old_admin.id,
716 "nickname" => old_admin.nickname,
717 "roles" => %{"admin" => true, "moderator" => false},
719 "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
720 "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname)
723 |> Enum.sort_by(& &1["nickname"])
725 assert json_response(conn, 200) == %{
732 test "load only admins", %{conn: conn, admin: admin} do
733 second_admin = insert(:user, info: %{is_admin: true})
737 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
742 "deactivated" => false,
744 "nickname" => admin.nickname,
745 "roles" => %{"admin" => true, "moderator" => false},
746 "local" => admin.local,
748 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
749 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
752 "deactivated" => false,
753 "id" => second_admin.id,
754 "nickname" => second_admin.nickname,
755 "roles" => %{"admin" => true, "moderator" => false},
756 "local" => second_admin.local,
758 "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
759 "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname)
762 |> Enum.sort_by(& &1["nickname"])
764 assert json_response(conn, 200) == %{
771 test "load only moderators", %{conn: conn} do
772 moderator = insert(:user, info: %{is_moderator: true})
776 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
778 assert json_response(conn, 200) == %{
783 "deactivated" => false,
784 "id" => moderator.id,
785 "nickname" => moderator.nickname,
786 "roles" => %{"admin" => false, "moderator" => true},
787 "local" => moderator.local,
789 "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
790 "display_name" => HTML.strip_tags(moderator.name || moderator.nickname)
796 test "load users with tags list", %{conn: conn} do
797 user1 = insert(:user, tags: ["first"])
798 user2 = insert(:user, tags: ["second"])
802 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
807 "deactivated" => false,
809 "nickname" => user1.nickname,
810 "roles" => %{"admin" => false, "moderator" => false},
811 "local" => user1.local,
813 "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
814 "display_name" => HTML.strip_tags(user1.name || user1.nickname)
817 "deactivated" => false,
819 "nickname" => user2.nickname,
820 "roles" => %{"admin" => false, "moderator" => false},
821 "local" => user2.local,
822 "tags" => ["second"],
823 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
824 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
827 |> Enum.sort_by(& &1["nickname"])
829 assert json_response(conn, 200) == %{
836 test "it works with multiple filters" do
837 admin = insert(:user, nickname: "john", info: %{is_admin: true})
838 user = insert(:user, nickname: "bob", local: false, info: %{deactivated: true})
840 insert(:user, nickname: "ken", local: true, info: %{deactivated: true})
841 insert(:user, nickname: "bobb", local: false, info: %{deactivated: false})
845 |> assign(:user, admin)
846 |> get("/api/pleroma/admin/users?filters=deactivated,external")
848 assert json_response(conn, 200) == %{
853 "deactivated" => user.info.deactivated,
855 "nickname" => user.nickname,
856 "roles" => %{"admin" => false, "moderator" => false},
857 "local" => user.local,
859 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
860 "display_name" => HTML.strip_tags(user.name || user.nickname)
867 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
868 admin = insert(:user, info: %{is_admin: true})
873 |> assign(:user, admin)
874 |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
876 assert json_response(conn, 200) ==
878 "deactivated" => !user.info.deactivated,
880 "nickname" => user.nickname,
881 "roles" => %{"admin" => false, "moderator" => false},
884 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
885 "display_name" => HTML.strip_tags(user.name || user.nickname)
889 describe "GET /api/pleroma/admin/users/invite_token" do
891 admin = insert(:user, info: %{is_admin: true})
895 |> assign(:user, admin)
900 test "without options", %{conn: conn} do
901 conn = get(conn, "/api/pleroma/admin/users/invite_token")
903 token = json_response(conn, 200)
904 invite = UserInviteToken.find_by_token!(token)
906 refute invite.expires_at
907 refute invite.max_use
908 assert invite.invite_type == "one_time"
911 test "with expires_at", %{conn: conn} do
913 get(conn, "/api/pleroma/admin/users/invite_token", %{
914 "invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
917 token = json_response(conn, 200)
918 invite = UserInviteToken.find_by_token!(token)
921 assert invite.expires_at == Date.utc_today()
922 refute invite.max_use
923 assert invite.invite_type == "date_limited"
926 test "with max_use", %{conn: conn} do
928 get(conn, "/api/pleroma/admin/users/invite_token", %{
929 "invite" => %{"max_use" => 150}
932 token = json_response(conn, 200)
933 invite = UserInviteToken.find_by_token!(token)
935 refute invite.expires_at
936 assert invite.max_use == 150
937 assert invite.invite_type == "reusable"
940 test "with max use and expires_at", %{conn: conn} do
942 get(conn, "/api/pleroma/admin/users/invite_token", %{
943 "invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
946 token = json_response(conn, 200)
947 invite = UserInviteToken.find_by_token!(token)
949 assert invite.expires_at == Date.utc_today()
950 assert invite.max_use == 150
951 assert invite.invite_type == "reusable_date_limited"
955 describe "GET /api/pleroma/admin/users/invites" do
957 admin = insert(:user, info: %{is_admin: true})
961 |> assign(:user, admin)
966 test "no invites", %{conn: conn} do
967 conn = get(conn, "/api/pleroma/admin/users/invites")
969 assert json_response(conn, 200) == %{"invites" => []}
972 test "with invite", %{conn: conn} do
973 {:ok, invite} = UserInviteToken.create_invite()
975 conn = get(conn, "/api/pleroma/admin/users/invites")
977 assert json_response(conn, 200) == %{
982 "invite_type" => "one_time",
984 "token" => invite.token,
993 describe "POST /api/pleroma/admin/users/revoke_invite" do
995 admin = insert(:user, info: %{is_admin: true})
996 {:ok, invite} = UserInviteToken.create_invite()
1000 |> assign(:user, admin)
1001 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
1003 assert json_response(conn, 200) == %{
1004 "expires_at" => nil,
1006 "invite_type" => "one_time",
1008 "token" => invite.token,
1014 test "with invalid token" do
1015 admin = insert(:user, info: %{is_admin: true})
1019 |> assign(:user, admin)
1020 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
1022 assert json_response(conn, :not_found) == "Not found"
1026 describe "GET /api/pleroma/admin/reports/:id" do
1027 setup %{conn: conn} do
1028 admin = insert(:user, info: %{is_admin: true})
1030 %{conn: assign(conn, :user, admin)}
1033 test "returns report by its id", %{conn: conn} do
1034 [reporter, target_user] = insert_pair(:user)
1035 activity = insert(:note_activity, user: target_user)
1037 {:ok, %{id: report_id}} =
1038 CommonAPI.report(reporter, %{
1039 "account_id" => target_user.id,
1040 "comment" => "I feel offended",
1041 "status_ids" => [activity.id]
1046 |> get("/api/pleroma/admin/reports/#{report_id}")
1047 |> json_response(:ok)
1049 assert response["id"] == report_id
1052 test "returns 404 when report id is invalid", %{conn: conn} do
1053 conn = get(conn, "/api/pleroma/admin/reports/test")
1055 assert json_response(conn, :not_found) == "Not found"
1059 describe "PUT /api/pleroma/admin/reports/:id" do
1060 setup %{conn: conn} do
1061 admin = insert(:user, info: %{is_admin: true})
1062 [reporter, target_user] = insert_pair(:user)
1063 activity = insert(:note_activity, user: target_user)
1065 {:ok, %{id: report_id}} =
1066 CommonAPI.report(reporter, %{
1067 "account_id" => target_user.id,
1068 "comment" => "I feel offended",
1069 "status_ids" => [activity.id]
1072 %{conn: assign(conn, :user, admin), id: report_id}
1075 test "mark report as resolved", %{conn: conn, id: id} do
1078 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
1079 |> json_response(:ok)
1081 assert response["state"] == "resolved"
1084 test "closes report", %{conn: conn, id: id} do
1087 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
1088 |> json_response(:ok)
1090 assert response["state"] == "closed"
1093 test "returns 400 when state is unknown", %{conn: conn, id: id} do
1096 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"})
1098 assert json_response(conn, :bad_request) == "Unsupported state"
1101 test "returns 404 when report is not exist", %{conn: conn} do
1104 |> put("/api/pleroma/admin/reports/test", %{"state" => "closed"})
1106 assert json_response(conn, :not_found) == "Not found"
1110 describe "GET /api/pleroma/admin/reports" do
1111 setup %{conn: conn} do
1112 admin = insert(:user, info: %{is_admin: true})
1114 %{conn: assign(conn, :user, admin)}
1117 test "returns empty response when no reports created", %{conn: conn} do
1120 |> get("/api/pleroma/admin/reports")
1121 |> json_response(:ok)
1123 assert Enum.empty?(response["reports"])
1126 test "returns reports", %{conn: conn} do
1127 [reporter, target_user] = insert_pair(:user)
1128 activity = insert(:note_activity, user: target_user)
1130 {:ok, %{id: report_id}} =
1131 CommonAPI.report(reporter, %{
1132 "account_id" => target_user.id,
1133 "comment" => "I feel offended",
1134 "status_ids" => [activity.id]
1139 |> get("/api/pleroma/admin/reports")
1140 |> json_response(:ok)
1142 [report] = response["reports"]
1144 assert length(response["reports"]) == 1
1145 assert report["id"] == report_id
1148 test "returns reports with specified state", %{conn: conn} do
1149 [reporter, target_user] = insert_pair(:user)
1150 activity = insert(:note_activity, user: target_user)
1152 {:ok, %{id: first_report_id}} =
1153 CommonAPI.report(reporter, %{
1154 "account_id" => target_user.id,
1155 "comment" => "I feel offended",
1156 "status_ids" => [activity.id]
1159 {:ok, %{id: second_report_id}} =
1160 CommonAPI.report(reporter, %{
1161 "account_id" => target_user.id,
1162 "comment" => "I don't like this user"
1165 CommonAPI.update_report_state(second_report_id, "closed")
1169 |> get("/api/pleroma/admin/reports", %{
1172 |> json_response(:ok)
1174 [open_report] = response["reports"]
1176 assert length(response["reports"]) == 1
1177 assert open_report["id"] == first_report_id
1181 |> get("/api/pleroma/admin/reports", %{
1184 |> json_response(:ok)
1186 [closed_report] = response["reports"]
1188 assert length(response["reports"]) == 1
1189 assert closed_report["id"] == second_report_id
1193 |> get("/api/pleroma/admin/reports", %{
1194 "state" => "resolved"
1196 |> json_response(:ok)
1198 assert Enum.empty?(response["reports"])
1201 test "returns 403 when requested by a non-admin" do
1202 user = insert(:user)
1206 |> assign(:user, user)
1207 |> get("/api/pleroma/admin/reports")
1209 assert json_response(conn, :forbidden) == %{"error" => "User is not admin."}
1212 test "returns 403 when requested by anonymous" do
1215 |> get("/api/pleroma/admin/reports")
1217 assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
1221 describe "POST /api/pleroma/admin/reports/:id/respond" do
1222 setup %{conn: conn} do
1223 admin = insert(:user, info: %{is_admin: true})
1225 %{conn: assign(conn, :user, admin)}
1228 test "returns created dm", %{conn: conn} do
1229 [reporter, target_user] = insert_pair(:user)
1230 activity = insert(:note_activity, user: target_user)
1232 {:ok, %{id: report_id}} =
1233 CommonAPI.report(reporter, %{
1234 "account_id" => target_user.id,
1235 "comment" => "I feel offended",
1236 "status_ids" => [activity.id]
1241 |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
1242 "status" => "I will check it out"
1244 |> json_response(:ok)
1246 recipients = Enum.map(response["mentions"], & &1["username"])
1248 assert reporter.nickname in recipients
1249 assert response["content"] == "I will check it out"
1250 assert response["visibility"] == "direct"
1253 test "returns 400 when status is missing", %{conn: conn} do
1254 conn = post(conn, "/api/pleroma/admin/reports/test/respond")
1256 assert json_response(conn, :bad_request) == "Invalid parameters"
1259 test "returns 404 when report id is invalid", %{conn: conn} do
1261 post(conn, "/api/pleroma/admin/reports/test/respond", %{
1265 assert json_response(conn, :not_found) == "Not found"
1269 describe "PUT /api/pleroma/admin/statuses/:id" do
1270 setup %{conn: conn} do
1271 admin = insert(:user, info: %{is_admin: true})
1272 activity = insert(:note_activity)
1274 %{conn: assign(conn, :user, admin), id: activity.id}
1277 test "toggle sensitive flag", %{conn: conn, id: id} do
1280 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
1281 |> json_response(:ok)
1283 assert response["sensitive"]
1287 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
1288 |> json_response(:ok)
1290 refute response["sensitive"]
1293 test "change visibility flag", %{conn: conn, id: id} do
1296 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
1297 |> json_response(:ok)
1299 assert response["visibility"] == "public"
1303 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
1304 |> json_response(:ok)
1306 assert response["visibility"] == "private"
1310 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"})
1311 |> json_response(:ok)
1313 assert response["visibility"] == "unlisted"
1316 test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
1319 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"})
1321 assert json_response(conn, :bad_request) == "Unsupported visibility"
1325 describe "DELETE /api/pleroma/admin/statuses/:id" do
1326 setup %{conn: conn} do
1327 admin = insert(:user, info: %{is_admin: true})
1328 activity = insert(:note_activity)
1330 %{conn: assign(conn, :user, admin), id: activity.id}
1333 test "deletes status", %{conn: conn, id: id} do
1335 |> delete("/api/pleroma/admin/statuses/#{id}")
1336 |> json_response(:ok)
1338 refute Activity.get_by_id(id)
1341 test "returns error when status is not exist", %{conn: conn} do
1344 |> delete("/api/pleroma/admin/statuses/test")
1346 assert json_response(conn, :bad_request) == "Could not delete"
1350 describe "GET /api/pleroma/admin/config" do
1351 setup %{conn: conn} do
1352 admin = insert(:user, info: %{is_admin: true})
1354 %{conn: assign(conn, :user, admin)}
1357 test "without any settings in db", %{conn: conn} do
1358 conn = get(conn, "/api/pleroma/admin/config")
1360 assert json_response(conn, 200) == %{"configs" => []}
1363 test "with settings in db", %{conn: conn} do
1364 config1 = insert(:config)
1365 config2 = insert(:config)
1367 conn = get(conn, "/api/pleroma/admin/config")
1380 } = json_response(conn, 200)
1382 assert key1 == config1.key
1383 assert key2 == config2.key
1387 describe "POST /api/pleroma/admin/config" do
1388 setup %{conn: conn} do
1389 admin = insert(:user, info: %{is_admin: true})
1391 temp_file = "config/test.exported_from_db.secret.exs"
1394 Application.delete_env(:pleroma, :key1)
1395 Application.delete_env(:pleroma, :key2)
1396 Application.delete_env(:pleroma, :key3)
1397 Application.delete_env(:pleroma, :key4)
1398 Application.delete_env(:pleroma, :keyaa1)
1399 Application.delete_env(:pleroma, :keyaa2)
1400 Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
1401 Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
1402 :ok = File.rm(temp_file)
1405 dynamic = Pleroma.Config.get([:instance, :dynamic_configuration])
1407 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1410 Pleroma.Config.put([:instance, :dynamic_configuration], dynamic)
1413 %{conn: assign(conn, :user, admin)}
1416 test "create new config setting in db", %{conn: conn} do
1418 post(conn, "/api/pleroma/admin/config", %{
1420 %{group: "pleroma", key: "key1", value: "value1"},
1423 key: "Ueberauth.Strategy.Twitter.OAuth",
1424 value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
1430 ":nested_1" => "nested_value1",
1432 %{":nested_22" => "nested_value222"},
1433 %{":nested_33" => %{":nested_44" => "nested_444"}}
1441 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1442 %{"nested_4" => true}
1448 value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
1453 value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1458 assert json_response(conn, 200) == %{
1461 "group" => "pleroma",
1466 "group" => "ueberauth",
1467 "key" => "Ueberauth.Strategy.Twitter.OAuth",
1468 "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}]
1471 "group" => "pleroma",
1474 ":nested_1" => "nested_value1",
1476 %{":nested_22" => "nested_value222"},
1477 %{":nested_33" => %{":nested_44" => "nested_444"}}
1482 "group" => "pleroma",
1485 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1486 %{"nested_4" => true}
1490 "group" => "pleroma",
1492 "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}
1497 "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1502 assert Application.get_env(:pleroma, :key1) == "value1"
1504 assert Application.get_env(:pleroma, :key2) == %{
1505 nested_1: "nested_value1",
1507 %{nested_22: "nested_value222"},
1508 %{nested_33: %{nested_44: "nested_444"}}
1512 assert Application.get_env(:pleroma, :key3) == [
1513 %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
1514 %{"nested_4" => true}
1517 assert Application.get_env(:pleroma, :key4) == %{
1518 "endpoint" => "https://example.com",
1522 assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
1525 test "update config setting & delete", %{conn: conn} do
1526 config1 = insert(:config, key: "keyaa1")
1527 config2 = insert(:config, key: "keyaa2")
1531 key: "Ueberauth.Strategy.Microsoft.OAuth",
1532 value: :erlang.term_to_binary([])
1536 post(conn, "/api/pleroma/admin/config", %{
1538 %{group: config1.group, key: config1.key, value: "another_value"},
1539 %{group: config2.group, key: config2.key, delete: "true"},
1542 key: "Ueberauth.Strategy.Microsoft.OAuth",
1548 assert json_response(conn, 200) == %{
1551 "group" => "pleroma",
1552 "key" => config1.key,
1553 "value" => "another_value"
1558 assert Application.get_env(:pleroma, :keyaa1) == "another_value"
1559 refute Application.get_env(:pleroma, :keyaa2)
1562 test "common config example", %{conn: conn} do
1564 post(conn, "/api/pleroma/admin/config", %{
1567 "group" => "pleroma",
1568 "key" => "Pleroma.Captcha.NotReal",
1570 %{"tuple" => [":enabled", false]},
1571 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1572 %{"tuple" => [":seconds_valid", 60]},
1573 %{"tuple" => [":path", ""]},
1574 %{"tuple" => [":key1", nil]},
1575 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}
1581 assert json_response(conn, 200) == %{
1584 "group" => "pleroma",
1585 "key" => "Pleroma.Captcha.NotReal",
1587 %{"tuple" => [":enabled", false]},
1588 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1589 %{"tuple" => [":seconds_valid", 60]},
1590 %{"tuple" => [":path", ""]},
1591 %{"tuple" => [":key1", nil]},
1592 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}
1599 test "tuples with more than two values", %{conn: conn} do
1601 post(conn, "/api/pleroma/admin/config", %{
1604 "group" => "pleroma",
1605 "key" => "Pleroma.Web.Endpoint.NotReal",
1621 "/api/v1/streaming",
1622 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1629 "Phoenix.Endpoint.CowboyWebSocket",
1632 "Phoenix.Transports.WebSocket",
1635 "Pleroma.Web.Endpoint",
1636 "Pleroma.Web.UserSocket",
1647 "Phoenix.Endpoint.Cowboy2Handler",
1648 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1665 assert json_response(conn, 200) == %{
1668 "group" => "pleroma",
1669 "key" => "Pleroma.Web.Endpoint.NotReal",
1685 "/api/v1/streaming",
1686 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1693 "Phoenix.Endpoint.CowboyWebSocket",
1696 "Phoenix.Transports.WebSocket",
1699 "Pleroma.Web.Endpoint",
1700 "Pleroma.Web.UserSocket",
1711 "Phoenix.Endpoint.Cowboy2Handler",
1712 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1730 test "settings with nesting map", %{conn: conn} do
1732 post(conn, "/api/pleroma/admin/config", %{
1735 "group" => "pleroma",
1738 %{"tuple" => [":key2", "some_val"]},
1743 ":max_options" => 20,
1744 ":max_option_chars" => 200,
1745 ":min_expiration" => 0,
1746 ":max_expiration" => 31_536_000,
1748 ":max_options" => 20,
1749 ":max_option_chars" => 200,
1750 ":min_expiration" => 0,
1751 ":max_expiration" => 31_536_000
1761 assert json_response(conn, 200) ==
1765 "group" => "pleroma",
1768 %{"tuple" => [":key2", "some_val"]},
1773 ":max_expiration" => 31_536_000,
1774 ":max_option_chars" => 200,
1775 ":max_options" => 20,
1776 ":min_expiration" => 0,
1778 ":max_expiration" => 31_536_000,
1779 ":max_option_chars" => 200,
1780 ":max_options" => 20,
1781 ":min_expiration" => 0
1792 test "value as map", %{conn: conn} do
1794 post(conn, "/api/pleroma/admin/config", %{
1797 "group" => "pleroma",
1799 "value" => %{"key" => "some_val"}
1804 assert json_response(conn, 200) ==
1808 "group" => "pleroma",
1810 "value" => %{"key" => "some_val"}
1816 test "dispatch setting", %{conn: conn} do
1818 post(conn, "/api/pleroma/admin/config", %{
1821 "group" => "pleroma",
1822 "key" => "Pleroma.Web.Endpoint.NotReal",
1828 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
1829 %{"tuple" => [":dispatch", ["{:_,
1831 {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
1832 {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket,
1833 {Phoenix.Transports.WebSocket,
1834 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}},
1835 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
1846 "{:_, [{\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, " <>
1847 "{\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, " <>
1848 "{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, " <>
1849 "{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}]}"
1851 assert json_response(conn, 200) == %{
1854 "group" => "pleroma",
1855 "key" => "Pleroma.Web.Endpoint.NotReal",
1861 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
1879 test "queues key as atom", %{conn: conn} do
1881 post(conn, "/api/pleroma/admin/config", %{
1884 "group" => "pleroma_job_queue",
1887 %{"tuple" => [":federator_incoming", 50]},
1888 %{"tuple" => [":federator_outgoing", 50]},
1889 %{"tuple" => [":web_push", 50]},
1890 %{"tuple" => [":mailer", 10]},
1891 %{"tuple" => [":transmogrifier", 20]},
1892 %{"tuple" => [":scheduled_activities", 10]},
1893 %{"tuple" => [":background", 5]}
1899 assert json_response(conn, 200) == %{
1902 "group" => "pleroma_job_queue",
1905 %{"tuple" => [":federator_incoming", 50]},
1906 %{"tuple" => [":federator_outgoing", 50]},
1907 %{"tuple" => [":web_push", 50]},
1908 %{"tuple" => [":mailer", 10]},
1909 %{"tuple" => [":transmogrifier", 20]},
1910 %{"tuple" => [":scheduled_activities", 10]},
1911 %{"tuple" => [":background", 5]}
1919 describe "config mix tasks run" do
1920 setup %{conn: conn} do
1921 admin = insert(:user, info: %{is_admin: true})
1923 temp_file = "config/test.exported_from_db.secret.exs"
1925 Mix.shell(Mix.Shell.Quiet)
1928 Mix.shell(Mix.Shell.IO)
1929 :ok = File.rm(temp_file)
1932 dynamic = Pleroma.Config.get([:instance, :dynamic_configuration])
1934 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1937 Pleroma.Config.put([:instance, :dynamic_configuration], dynamic)
1940 %{conn: assign(conn, :user, admin), admin: admin}
1943 test "transfer settings to DB and to file", %{conn: conn, admin: admin} do
1944 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
1945 conn = get(conn, "/api/pleroma/admin/config/migrate_to_db")
1946 assert json_response(conn, 200) == %{}
1947 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) > 0
1951 |> assign(:user, admin)
1952 |> get("/api/pleroma/admin/config/migrate_from_db")
1954 assert json_response(conn, 200) == %{}
1955 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
1959 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
1961 admin = insert(:user, info: %{is_admin: true})
1962 user = insert(:user)
1964 date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
1965 date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
1966 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
1968 insert(:note_activity, user: user, published: date1)
1969 insert(:note_activity, user: user, published: date2)
1970 insert(:note_activity, user: user, published: date3)
1974 |> assign(:user, admin)
1976 {:ok, conn: conn, user: user}
1979 test "renders user's statuses", %{conn: conn, user: user} do
1980 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
1982 assert json_response(conn, 200) |> length() == 3
1985 test "renders user's statuses with a limit", %{conn: conn, user: user} do
1986 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
1988 assert json_response(conn, 200) |> length() == 2
1991 test "doesn't return private statuses by default", %{conn: conn, user: user} do
1992 {:ok, _private_status} =
1993 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
1995 {:ok, _public_status} =
1996 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
1998 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2000 assert json_response(conn, 200) |> length() == 4
2003 test "returns private statuses with godmode on", %{conn: conn, user: user} do
2004 {:ok, _private_status} =
2005 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2007 {:ok, _public_status} =
2008 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2010 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
2012 assert json_response(conn, 200) |> length() == 5
2017 # Needed for testing
2018 defmodule Pleroma.Web.Endpoint.NotReal do
2021 defmodule Pleroma.Captcha.NotReal do