1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.TwitterAPI.ControllerTest do
6 use Pleroma.Web.ConnCase
10 alias Pleroma.Builders.ActivityBuilder
11 alias Pleroma.Builders.UserBuilder
12 alias Pleroma.Notification
16 alias Pleroma.Web.ActivityPub.ActivityPub
17 alias Pleroma.Web.CommonAPI
18 alias Pleroma.Web.OAuth.Token
19 alias Pleroma.Web.TwitterAPI.ActivityView
20 alias Pleroma.Web.TwitterAPI.Controller
21 alias Pleroma.Web.TwitterAPI.NotificationView
22 alias Pleroma.Web.TwitterAPI.TwitterAPI
23 alias Pleroma.Web.TwitterAPI.UserView
26 import Pleroma.Factory
27 import Swoosh.TestAssertions
29 @banner "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
31 describe "POST /api/account/update_profile_banner" do
32 test "it updates the banner", %{conn: conn} do
36 |> assign(:user, user)
37 |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => @banner})
40 user = refresh_record(user)
41 assert user.info.banner["type"] == "Image"
44 test "profile banner can be reset", %{conn: conn} do
48 |> assign(:user, user)
49 |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => ""})
52 user = refresh_record(user)
53 assert user.info.banner == %{}
57 describe "POST /api/qvitter/update_background_image" do
58 test "it updates the background", %{conn: conn} do
62 |> assign(:user, user)
63 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => @banner})
66 user = refresh_record(user)
67 assert user.info.background["type"] == "Image"
70 test "background can be reset", %{conn: conn} do
74 |> assign(:user, user)
75 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => ""})
78 user = refresh_record(user)
79 assert user.info.background == %{}
83 describe "POST /api/account/verify_credentials" do
86 test "without valid credentials", %{conn: conn} do
87 conn = post(conn, "/api/account/verify_credentials.json")
88 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
91 test "with credentials", %{conn: conn, user: user} do
94 |> with_credentials(user.nickname, "test")
95 |> post("/api/account/verify_credentials.json")
99 UserView.render("show.json", %{user: user, token: response["token"], for: user})
103 describe "POST /statuses/update.json" do
106 test "without valid credentials", %{conn: conn} do
107 conn = post(conn, "/api/statuses/update.json")
108 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
111 test "with credentials", %{conn: conn, user: user} do
112 conn_with_creds = conn |> with_credentials(user.nickname, "test")
113 request_path = "/api/statuses/update.json"
116 "request" => request_path,
117 "error" => "Client must provide a 'status' parameter with a value."
122 |> post(request_path)
124 assert json_response(conn, 400) == error_response
128 |> post(request_path, %{status: ""})
130 assert json_response(conn, 400) == error_response
134 |> post(request_path, %{status: " "})
136 assert json_response(conn, 400) == error_response
138 # we post with visibility private in order to avoid triggering relay
141 |> post(request_path, %{status: "Nice meme.", visibility: "private"})
143 assert json_response(conn, 200) ==
144 ActivityView.render("activity.json", %{
145 activity: Repo.one(Activity),
152 describe "GET /statuses/public_timeline.json" do
155 test "returns statuses", %{conn: conn} do
157 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
158 ActivityBuilder.insert_list(10, %{}, %{user: user})
159 since_id = List.last(activities).id
163 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
165 response = json_response(conn, 200)
167 assert length(response) == 10
170 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
171 Pleroma.Config.put([:instance, :public], false)
174 |> get("/api/statuses/public_timeline.json")
175 |> json_response(403)
177 Pleroma.Config.put([:instance, :public], true)
180 test "returns 200 to authenticated request when the instance is not public",
181 %{conn: conn, user: user} do
182 Pleroma.Config.put([:instance, :public], false)
185 |> with_credentials(user.nickname, "test")
186 |> get("/api/statuses/public_timeline.json")
187 |> json_response(200)
189 Pleroma.Config.put([:instance, :public], true)
192 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
194 |> get("/api/statuses/public_timeline.json")
195 |> json_response(200)
198 test "returns 200 to authenticated request when the instance is public",
199 %{conn: conn, user: user} do
201 |> with_credentials(user.nickname, "test")
202 |> get("/api/statuses/public_timeline.json")
203 |> json_response(200)
206 test_with_mock "treats user as unauthenticated if `assigns[:token]` is present but lacks `read` permission",
210 token = insert(:oauth_token, scopes: ["write"])
213 |> put_req_header("authorization", "Bearer #{token.token}")
214 |> get("/api/statuses/public_timeline.json")
215 |> json_response(200)
217 assert called(Controller.public_timeline(%{assigns: %{user: nil}}, :_))
221 describe "GET /statuses/public_and_external_timeline.json" do
224 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
225 Pleroma.Config.put([:instance, :public], false)
228 |> get("/api/statuses/public_and_external_timeline.json")
229 |> json_response(403)
231 Pleroma.Config.put([:instance, :public], true)
234 test "returns 200 to authenticated request when the instance is not public",
235 %{conn: conn, user: user} do
236 Pleroma.Config.put([:instance, :public], false)
239 |> with_credentials(user.nickname, "test")
240 |> get("/api/statuses/public_and_external_timeline.json")
241 |> json_response(200)
243 Pleroma.Config.put([:instance, :public], true)
246 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
248 |> get("/api/statuses/public_and_external_timeline.json")
249 |> json_response(200)
252 test "returns 200 to authenticated request when the instance is public",
253 %{conn: conn, user: user} do
255 |> with_credentials(user.nickname, "test")
256 |> get("/api/statuses/public_and_external_timeline.json")
257 |> json_response(200)
261 describe "GET /statuses/show/:id.json" do
262 test "returns one status", %{conn: conn} do
264 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
265 actor = User.get_cached_by_ap_id(activity.data["actor"])
269 |> get("/api/statuses/show/#{activity.id}.json")
271 response = json_response(conn, 200)
273 assert response == ActivityView.render("activity.json", %{activity: activity, user: actor})
277 describe "GET /users/show.json" do
278 test "gets user with screen_name", %{conn: conn} do
283 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
285 response = json_response(conn, 200)
287 assert response["id"] == user.id
290 test "gets user with user_id", %{conn: conn} do
295 |> get("/api/users/show.json", %{"user_id" => user.id})
297 response = json_response(conn, 200)
299 assert response["id"] == user.id
302 test "gets a user for a logged in user", %{conn: conn} do
304 logged_in = insert(:user)
306 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
310 |> with_credentials(logged_in.nickname, "test")
311 |> get("/api/users/show.json", %{"user_id" => user.id})
313 response = json_response(conn, 200)
315 assert response["following"] == true
319 describe "GET /statusnet/conversation/:id.json" do
320 test "returns the statuses in the conversation", %{conn: conn} do
321 {:ok, _user} = UserBuilder.insert()
322 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
323 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
324 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
328 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
330 response = json_response(conn, 200)
332 assert length(response) == 2
336 describe "GET /statuses/friends_timeline.json" do
339 test "without valid credentials", %{conn: conn} do
340 conn = get(conn, "/api/statuses/friends_timeline.json")
341 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
344 test "with credentials", %{conn: conn, user: current_user} do
348 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
350 returned_activities =
351 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
353 other_user = insert(:user)
354 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
355 since_id = List.last(activities).id
358 Changeset.change(current_user, following: [User.ap_followers(user)])
363 |> with_credentials(current_user.nickname, "test")
364 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
366 response = json_response(conn, 200)
368 assert length(response) == 10
371 Enum.map(returned_activities, fn activity ->
372 ActivityView.render("activity.json", %{
374 user: User.get_cached_by_ap_id(activity.data["actor"]),
381 describe "GET /statuses/dm_timeline.json" do
382 test "it show direct messages", %{conn: conn} do
383 user_one = insert(:user)
384 user_two = insert(:user)
386 {:ok, user_two} = User.follow(user_two, user_one)
389 CommonAPI.post(user_one, %{
390 "status" => "Hi @#{user_two.nickname}!",
391 "visibility" => "direct"
395 CommonAPI.post(user_two, %{
396 "status" => "Hi @#{user_one.nickname}!",
397 "visibility" => "direct"
400 {:ok, _follower_only} =
401 CommonAPI.post(user_one, %{
402 "status" => "Hi @#{user_two.nickname}!",
403 "visibility" => "private"
406 # Only direct should be visible here
409 |> assign(:user, user_two)
410 |> get("/api/statuses/dm_timeline.json")
412 [status, status_two] = json_response(res_conn, 200)
413 assert status["id"] == direct_two.id
414 assert status_two["id"] == direct.id
417 test "doesn't include DMs from blocked users", %{conn: conn} do
418 blocker = insert(:user)
419 blocked = insert(:user)
421 {:ok, blocker} = User.block(blocker, blocked)
423 {:ok, _blocked_direct} =
424 CommonAPI.post(blocked, %{
425 "status" => "Hi @#{blocker.nickname}!",
426 "visibility" => "direct"
430 CommonAPI.post(user, %{
431 "status" => "Hi @#{blocker.nickname}!",
432 "visibility" => "direct"
437 |> assign(:user, blocker)
438 |> get("/api/statuses/dm_timeline.json")
440 [status] = json_response(res_conn, 200)
441 assert status["id"] == direct.id
445 describe "GET /statuses/mentions.json" do
448 test "without valid credentials", %{conn: conn} do
449 conn = get(conn, "/api/statuses/mentions.json")
450 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
453 test "with credentials", %{conn: conn, user: current_user} do
455 CommonAPI.post(current_user, %{
456 "status" => "why is tenshi eating a corndog so cute?",
457 "visibility" => "public"
462 |> with_credentials(current_user.nickname, "test")
463 |> get("/api/statuses/mentions.json")
465 response = json_response(conn, 200)
467 assert length(response) == 1
469 assert Enum.at(response, 0) ==
470 ActivityView.render("activity.json", %{
477 test "does not show DMs in mentions timeline", %{conn: conn, user: current_user} do
479 CommonAPI.post(current_user, %{
480 "status" => "Have you guys ever seen how cute tenshi eating a corndog is?",
481 "visibility" => "direct"
486 |> with_credentials(current_user.nickname, "test")
487 |> get("/api/statuses/mentions.json")
489 response = json_response(conn, 200)
491 assert Enum.empty?(response)
495 describe "GET /api/qvitter/statuses/notifications.json" do
498 test "without valid credentials", %{conn: conn} do
499 conn = get(conn, "/api/qvitter/statuses/notifications.json")
500 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
503 test "with credentials", %{conn: conn, user: current_user} do
504 other_user = insert(:user)
507 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
511 |> with_credentials(current_user.nickname, "test")
512 |> get("/api/qvitter/statuses/notifications.json")
514 response = json_response(conn, 200)
516 assert length(response) == 1
519 NotificationView.render("notification.json", %{
520 notifications: Notification.for_user(current_user),
525 test "muted user", %{conn: conn, user: current_user} do
526 other_user = insert(:user)
528 {:ok, current_user} = User.mute(current_user, other_user)
531 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
535 |> with_credentials(current_user.nickname, "test")
536 |> get("/api/qvitter/statuses/notifications.json")
538 assert json_response(conn, 200) == []
541 test "muted user with with_muted parameter", %{conn: conn, user: current_user} do
542 other_user = insert(:user)
544 {:ok, current_user} = User.mute(current_user, other_user)
547 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
551 |> with_credentials(current_user.nickname, "test")
552 |> get("/api/qvitter/statuses/notifications.json", %{"with_muted" => "true"})
554 assert length(json_response(conn, 200)) == 1
558 describe "POST /api/qvitter/statuses/notifications/read" do
561 test "without valid credentials", %{conn: conn} do
562 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
563 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
566 test "with credentials, without any params", %{conn: conn, user: current_user} do
569 |> with_credentials(current_user.nickname, "test")
570 |> post("/api/qvitter/statuses/notifications/read")
572 assert json_response(conn, 400) == %{
573 "error" => "You need to specify latest_id",
574 "request" => "/api/qvitter/statuses/notifications/read"
578 test "with credentials, with params", %{conn: conn, user: current_user} do
579 other_user = insert(:user)
582 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
586 |> with_credentials(current_user.nickname, "test")
587 |> get("/api/qvitter/statuses/notifications.json")
589 [notification] = response = json_response(response_conn, 200)
591 assert length(response) == 1
593 assert notification["is_seen"] == 0
597 |> with_credentials(current_user.nickname, "test")
598 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
600 [notification] = response = json_response(response_conn, 200)
602 assert length(response) == 1
604 assert notification["is_seen"] == 1
608 describe "GET /statuses/user_timeline.json" do
611 test "without any params", %{conn: conn} do
612 conn = get(conn, "/api/statuses/user_timeline.json")
614 assert json_response(conn, 400) == %{
615 "error" => "You need to specify screen_name or user_id",
616 "request" => "/api/statuses/user_timeline.json"
620 test "with user_id", %{conn: conn} do
622 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
624 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
625 response = json_response(conn, 200)
626 assert length(response) == 1
628 assert Enum.at(response, 0) ==
629 ActivityView.render("activity.json", %{user: user, activity: activity})
632 test "with screen_name", %{conn: conn} do
634 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
636 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
637 response = json_response(conn, 200)
638 assert length(response) == 1
640 assert Enum.at(response, 0) ==
641 ActivityView.render("activity.json", %{user: user, activity: activity})
644 test "with credentials", %{conn: conn, user: current_user} do
645 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
649 |> with_credentials(current_user.nickname, "test")
650 |> get("/api/statuses/user_timeline.json")
652 response = json_response(conn, 200)
654 assert length(response) == 1
656 assert Enum.at(response, 0) ==
657 ActivityView.render("activity.json", %{
664 test "with credentials with user_id", %{conn: conn, user: current_user} do
666 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
670 |> with_credentials(current_user.nickname, "test")
671 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
673 response = json_response(conn, 200)
675 assert length(response) == 1
677 assert Enum.at(response, 0) ==
678 ActivityView.render("activity.json", %{user: user, activity: activity})
681 test "with credentials screen_name", %{conn: conn, user: current_user} do
683 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
687 |> with_credentials(current_user.nickname, "test")
688 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
690 response = json_response(conn, 200)
692 assert length(response) == 1
694 assert Enum.at(response, 0) ==
695 ActivityView.render("activity.json", %{user: user, activity: activity})
698 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
700 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
701 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
705 |> with_credentials(current_user.nickname, "test")
706 |> get("/api/statuses/user_timeline.json", %{
707 "user_id" => user.id,
708 "include_rts" => "false"
711 response = json_response(conn, 200)
713 assert length(response) == 1
715 assert Enum.at(response, 0) ==
716 ActivityView.render("activity.json", %{user: user, activity: activity})
720 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
722 response = json_response(conn, 200)
724 assert length(response) == 1
726 assert Enum.at(response, 0) ==
727 ActivityView.render("activity.json", %{user: user, activity: activity})
731 describe "POST /friendships/create.json" do
734 test "without valid credentials", %{conn: conn} do
735 conn = post(conn, "/api/friendships/create.json")
736 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
739 test "with credentials", %{conn: conn, user: current_user} do
740 followed = insert(:user)
744 |> with_credentials(current_user.nickname, "test")
745 |> post("/api/friendships/create.json", %{user_id: followed.id})
747 current_user = User.get_cached_by_id(current_user.id)
748 assert User.ap_followers(followed) in current_user.following
750 assert json_response(conn, 200) ==
751 UserView.render("show.json", %{user: followed, for: current_user})
754 test "for restricted account", %{conn: conn, user: current_user} do
755 followed = insert(:user, info: %User.Info{locked: true})
759 |> with_credentials(current_user.nickname, "test")
760 |> post("/api/friendships/create.json", %{user_id: followed.id})
762 current_user = User.get_cached_by_id(current_user.id)
763 followed = User.get_cached_by_id(followed.id)
765 refute User.ap_followers(followed) in current_user.following
767 assert json_response(conn, 200) ==
768 UserView.render("show.json", %{user: followed, for: current_user})
772 describe "POST /friendships/destroy.json" do
775 test "without valid credentials", %{conn: conn} do
776 conn = post(conn, "/api/friendships/destroy.json")
777 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
780 test "with credentials", %{conn: conn, user: current_user} do
781 followed = insert(:user)
783 {:ok, current_user} = User.follow(current_user, followed)
784 assert User.ap_followers(followed) in current_user.following
785 ActivityPub.follow(current_user, followed)
789 |> with_credentials(current_user.nickname, "test")
790 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
792 current_user = User.get_cached_by_id(current_user.id)
793 assert current_user.following == [current_user.ap_id]
795 assert json_response(conn, 200) ==
796 UserView.render("show.json", %{user: followed, for: current_user})
800 describe "POST /blocks/create.json" do
803 test "without valid credentials", %{conn: conn} do
804 conn = post(conn, "/api/blocks/create.json")
805 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
808 test "with credentials", %{conn: conn, user: current_user} do
809 blocked = insert(:user)
813 |> with_credentials(current_user.nickname, "test")
814 |> post("/api/blocks/create.json", %{user_id: blocked.id})
816 current_user = User.get_cached_by_id(current_user.id)
817 assert User.blocks?(current_user, blocked)
819 assert json_response(conn, 200) ==
820 UserView.render("show.json", %{user: blocked, for: current_user})
824 describe "POST /blocks/destroy.json" do
827 test "without valid credentials", %{conn: conn} do
828 conn = post(conn, "/api/blocks/destroy.json")
829 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
832 test "with credentials", %{conn: conn, user: current_user} do
833 blocked = insert(:user)
835 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
836 assert User.blocks?(current_user, blocked)
840 |> with_credentials(current_user.nickname, "test")
841 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
843 current_user = User.get_cached_by_id(current_user.id)
844 assert current_user.info.blocks == []
846 assert json_response(conn, 200) ==
847 UserView.render("show.json", %{user: blocked, for: current_user})
851 describe "GET /help/test.json" do
852 test "returns \"ok\"", %{conn: conn} do
853 conn = get(conn, "/api/help/test.json")
854 assert json_response(conn, 200) == "ok"
858 describe "POST /api/qvitter/update_avatar.json" do
861 test "without valid credentials", %{conn: conn} do
862 conn = post(conn, "/api/qvitter/update_avatar.json")
863 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
866 test "with credentials", %{conn: conn, user: current_user} do
867 avatar_image = File.read!("test/fixtures/avatar_data_uri")
871 |> with_credentials(current_user.nickname, "test")
872 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
874 current_user = User.get_cached_by_id(current_user.id)
875 assert is_map(current_user.avatar)
877 assert json_response(conn, 200) ==
878 UserView.render("show.json", %{user: current_user, for: current_user})
881 test "user avatar can be reset", %{conn: conn, user: current_user} do
884 |> with_credentials(current_user.nickname, "test")
885 |> post("/api/qvitter/update_avatar.json", %{img: ""})
887 current_user = User.get_cached_by_id(current_user.id)
888 assert current_user.avatar == nil
890 assert json_response(conn, 200) ==
891 UserView.render("show.json", %{user: current_user, for: current_user})
895 describe "GET /api/qvitter/mutes.json" do
898 test "unimplemented mutes without valid credentials", %{conn: conn} do
899 conn = get(conn, "/api/qvitter/mutes.json")
900 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
903 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
906 |> with_credentials(current_user.nickname, "test")
907 |> get("/api/qvitter/mutes.json")
908 |> json_response(200)
914 describe "POST /api/favorites/create/:id" do
917 test "without valid credentials", %{conn: conn} do
918 note_activity = insert(:note_activity)
919 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
920 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
923 test "with credentials", %{conn: conn, user: current_user} do
924 note_activity = insert(:note_activity)
928 |> with_credentials(current_user.nickname, "test")
929 |> post("/api/favorites/create/#{note_activity.id}.json")
931 assert json_response(conn, 200)
934 test "with credentials, invalid param", %{conn: conn, user: current_user} do
937 |> with_credentials(current_user.nickname, "test")
938 |> post("/api/favorites/create/wrong.json")
940 assert json_response(conn, 400)
943 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
946 |> with_credentials(current_user.nickname, "test")
947 |> post("/api/favorites/create/1.json")
949 assert json_response(conn, 400)
953 describe "POST /api/favorites/destroy/:id" do
956 test "without valid credentials", %{conn: conn} do
957 note_activity = insert(:note_activity)
958 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
959 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
962 test "with credentials", %{conn: conn, user: current_user} do
963 note_activity = insert(:note_activity)
964 object = Object.normalize(note_activity)
965 ActivityPub.like(current_user, object)
969 |> with_credentials(current_user.nickname, "test")
970 |> post("/api/favorites/destroy/#{note_activity.id}.json")
972 assert json_response(conn, 200)
976 describe "POST /api/statuses/retweet/:id" do
979 test "without valid credentials", %{conn: conn} do
980 note_activity = insert(:note_activity)
981 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
982 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
985 test "with credentials", %{conn: conn, user: current_user} do
986 note_activity = insert(:note_activity)
988 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
992 |> with_credentials(current_user.nickname, "test")
993 |> post(request_path)
995 activity = Activity.get_by_id(note_activity.id)
996 activity_user = User.get_cached_by_ap_id(note_activity.data["actor"])
998 assert json_response(response, 200) ==
999 ActivityView.render("activity.json", %{
1000 user: activity_user,
1007 describe "POST /api/statuses/unretweet/:id" do
1010 test "without valid credentials", %{conn: conn} do
1011 note_activity = insert(:note_activity)
1012 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
1013 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1016 test "with credentials", %{conn: conn, user: current_user} do
1017 note_activity = insert(:note_activity)
1019 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
1023 |> with_credentials(current_user.nickname, "test")
1024 |> post(request_path)
1026 request_path = String.replace(request_path, "retweet", "unretweet")
1030 |> with_credentials(current_user.nickname, "test")
1031 |> post(request_path)
1033 activity = Activity.get_by_id(note_activity.id)
1034 activity_user = User.get_cached_by_ap_id(note_activity.data["actor"])
1036 assert json_response(response, 200) ==
1037 ActivityView.render("activity.json", %{
1038 user: activity_user,
1045 describe "POST /api/account/register" do
1046 test "it creates a new user", %{conn: conn} do
1048 "nickname" => "lain",
1049 "email" => "lain@wired.jp",
1050 "fullname" => "lain iwakura",
1051 "bio" => "close the world.",
1052 "password" => "bear",
1058 |> post("/api/account/register", data)
1060 user = json_response(conn, 200)
1062 fetched_user = User.get_cached_by_nickname("lain")
1063 assert user == UserView.render("show.json", %{user: fetched_user})
1066 test "it returns errors on a problem", %{conn: conn} do
1068 "email" => "lain@wired.jp",
1069 "fullname" => "lain iwakura",
1070 "bio" => "close the world.",
1071 "password" => "bear",
1077 |> post("/api/account/register", data)
1079 errors = json_response(conn, 400)
1081 assert is_binary(errors["error"])
1085 describe "POST /api/account/password_reset, with valid parameters" do
1086 setup %{conn: conn} do
1087 user = insert(:user)
1088 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1089 %{conn: conn, user: user}
1092 test "it returns 204", %{conn: conn} do
1093 assert json_response(conn, :no_content)
1096 test "it creates a PasswordResetToken record for user", %{user: user} do
1097 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1101 test "it sends an email to user", %{user: user} do
1102 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1104 email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
1105 notify_email = Pleroma.Config.get([:instance, :notify_email])
1106 instance_name = Pleroma.Config.get([:instance, :name])
1109 from: {instance_name, notify_email},
1110 to: {user.name, user.email},
1111 html_body: email.html_body
1116 describe "POST /api/account/password_reset, with invalid parameters" do
1119 test "it returns 404 when user is not found", %{conn: conn, user: user} do
1120 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1121 assert conn.status == 404
1122 assert conn.resp_body == ""
1125 test "it returns 400 when user is not local", %{conn: conn, user: user} do
1126 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1127 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1128 assert conn.status == 400
1129 assert conn.resp_body == ""
1133 describe "GET /api/account/confirm_email/:id/:token" do
1135 user = insert(:user)
1136 info_change = User.Info.confirmation_changeset(user.info, need_confirmation: true)
1140 |> Changeset.change()
1141 |> Changeset.put_embed(:info, info_change)
1144 assert user.info.confirmation_pending
1149 test "it redirects to root url", %{conn: conn, user: user} do
1150 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1152 assert 302 == conn.status
1155 test "it confirms the user account", %{conn: conn, user: user} do
1156 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1158 user = User.get_cached_by_id(user.id)
1160 refute user.info.confirmation_pending
1161 refute user.info.confirmation_token
1164 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1165 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1167 assert 500 == conn.status
1170 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1171 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1173 assert 500 == conn.status
1177 describe "POST /api/account/resend_confirmation_email" do
1179 setting = Pleroma.Config.get([:instance, :account_activation_required])
1182 Pleroma.Config.put([:instance, :account_activation_required], true)
1183 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1186 user = insert(:user)
1187 info_change = User.Info.confirmation_changeset(user.info, need_confirmation: true)
1191 |> Changeset.change()
1192 |> Changeset.put_embed(:info, info_change)
1195 assert user.info.confirmation_pending
1200 test "it returns 204 No Content", %{conn: conn, user: user} do
1202 |> assign(:user, user)
1203 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1204 |> json_response(:no_content)
1207 test "it sends confirmation email", %{conn: conn, user: user} do
1209 |> assign(:user, user)
1210 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1212 email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
1213 notify_email = Pleroma.Config.get([:instance, :notify_email])
1214 instance_name = Pleroma.Config.get([:instance, :name])
1217 from: {instance_name, notify_email},
1218 to: {user.name, user.email},
1219 html_body: email.html_body
1224 describe "GET /api/externalprofile/show" do
1225 test "it returns the user", %{conn: conn} do
1226 user = insert(:user)
1227 other_user = insert(:user)
1231 |> assign(:user, user)
1232 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1234 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1238 describe "GET /api/statuses/followers" do
1239 test "it returns a user's followers", %{conn: conn} do
1240 user = insert(:user)
1241 follower_one = insert(:user)
1242 follower_two = insert(:user)
1243 _not_follower = insert(:user)
1245 {:ok, follower_one} = User.follow(follower_one, user)
1246 {:ok, follower_two} = User.follow(follower_two, user)
1250 |> assign(:user, user)
1251 |> get("/api/statuses/followers")
1253 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1254 result = json_response(conn, 200)
1255 assert Enum.sort(expected) == Enum.sort(result)
1258 test "it returns 20 followers per page", %{conn: conn} do
1259 user = insert(:user)
1260 followers = insert_list(21, :user)
1262 Enum.each(followers, fn follower ->
1263 User.follow(follower, user)
1268 |> assign(:user, user)
1269 |> get("/api/statuses/followers")
1271 result = json_response(res_conn, 200)
1272 assert length(result) == 20
1276 |> assign(:user, user)
1277 |> get("/api/statuses/followers?page=2")
1279 result = json_response(res_conn, 200)
1280 assert length(result) == 1
1283 test "it returns a given user's followers with user_id", %{conn: conn} do
1284 user = insert(:user)
1285 follower_one = insert(:user)
1286 follower_two = insert(:user)
1287 not_follower = insert(:user)
1289 {:ok, follower_one} = User.follow(follower_one, user)
1290 {:ok, follower_two} = User.follow(follower_two, user)
1294 |> assign(:user, not_follower)
1295 |> get("/api/statuses/followers", %{"user_id" => user.id})
1297 assert MapSet.equal?(
1298 MapSet.new(json_response(conn, 200)),
1300 UserView.render("index.json", %{
1301 users: [follower_one, follower_two],
1308 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1309 user = insert(:user, %{info: %{hide_followers: true}})
1310 follower_one = insert(:user)
1311 follower_two = insert(:user)
1312 not_follower = insert(:user)
1314 {:ok, _follower_one} = User.follow(follower_one, user)
1315 {:ok, _follower_two} = User.follow(follower_two, user)
1319 |> assign(:user, not_follower)
1320 |> get("/api/statuses/followers", %{"user_id" => user.id})
1321 |> json_response(200)
1323 assert [] == response
1326 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1330 user = insert(:user, %{info: %{hide_followers: true}})
1331 follower_one = insert(:user)
1332 follower_two = insert(:user)
1333 _not_follower = insert(:user)
1335 {:ok, _follower_one} = User.follow(follower_one, user)
1336 {:ok, _follower_two} = User.follow(follower_two, user)
1340 |> assign(:user, user)
1341 |> get("/api/statuses/followers", %{"user_id" => user.id})
1343 refute [] == json_response(conn, 200)
1347 describe "GET /api/statuses/blocks" do
1348 test "it returns the list of users blocked by requester", %{conn: conn} do
1349 user = insert(:user)
1350 other_user = insert(:user)
1352 {:ok, user} = User.block(user, other_user)
1356 |> assign(:user, user)
1357 |> get("/api/statuses/blocks")
1359 expected = UserView.render("index.json", %{users: [other_user], for: user})
1360 result = json_response(conn, 200)
1361 assert Enum.sort(expected) == Enum.sort(result)
1365 describe "GET /api/statuses/friends" do
1366 test "it returns the logged in user's friends", %{conn: conn} do
1367 user = insert(:user)
1368 followed_one = insert(:user)
1369 followed_two = insert(:user)
1370 _not_followed = insert(:user)
1372 {:ok, user} = User.follow(user, followed_one)
1373 {:ok, user} = User.follow(user, followed_two)
1377 |> assign(:user, user)
1378 |> get("/api/statuses/friends")
1380 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1381 result = json_response(conn, 200)
1382 assert Enum.sort(expected) == Enum.sort(result)
1385 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1386 user = insert(:user)
1387 followeds = insert_list(21, :user)
1390 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1391 User.follow(user, followed)
1396 |> assign(:user, user)
1397 |> get("/api/statuses/friends")
1399 result = json_response(res_conn, 200)
1400 assert length(result) == 20
1404 |> assign(:user, user)
1405 |> get("/api/statuses/friends", %{page: 2})
1407 result = json_response(res_conn, 200)
1408 assert length(result) == 1
1412 |> assign(:user, user)
1413 |> get("/api/statuses/friends", %{all: true})
1415 result = json_response(res_conn, 200)
1416 assert length(result) == 21
1419 test "it returns a given user's friends with user_id", %{conn: conn} do
1420 user = insert(:user)
1421 followed_one = insert(:user)
1422 followed_two = insert(:user)
1423 _not_followed = insert(:user)
1425 {:ok, user} = User.follow(user, followed_one)
1426 {:ok, user} = User.follow(user, followed_two)
1430 |> assign(:user, user)
1431 |> get("/api/statuses/friends", %{"user_id" => user.id})
1433 assert MapSet.equal?(
1434 MapSet.new(json_response(conn, 200)),
1436 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1441 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1442 user = insert(:user, %{info: %{hide_follows: true}})
1443 followed_one = insert(:user)
1444 followed_two = insert(:user)
1445 not_followed = insert(:user)
1447 {:ok, user} = User.follow(user, followed_one)
1448 {:ok, user} = User.follow(user, followed_two)
1452 |> assign(:user, not_followed)
1453 |> get("/api/statuses/friends", %{"user_id" => user.id})
1455 assert [] == json_response(conn, 200)
1458 test "it returns friends when hide_follows is set to true if the user themselves request it",
1462 user = insert(:user, %{info: %{hide_follows: true}})
1463 followed_one = insert(:user)
1464 followed_two = insert(:user)
1465 _not_followed = insert(:user)
1467 {:ok, _user} = User.follow(user, followed_one)
1468 {:ok, _user} = User.follow(user, followed_two)
1472 |> assign(:user, user)
1473 |> get("/api/statuses/friends", %{"user_id" => user.id})
1474 |> json_response(200)
1476 refute [] == response
1479 test "it returns a given user's friends with screen_name", %{conn: conn} do
1480 user = insert(:user)
1481 followed_one = insert(:user)
1482 followed_two = insert(:user)
1483 _not_followed = insert(:user)
1485 {:ok, user} = User.follow(user, followed_one)
1486 {:ok, user} = User.follow(user, followed_two)
1490 |> assign(:user, user)
1491 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1493 assert MapSet.equal?(
1494 MapSet.new(json_response(conn, 200)),
1496 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1502 describe "GET /friends/ids" do
1503 test "it returns a user's friends", %{conn: conn} do
1504 user = insert(:user)
1505 followed_one = insert(:user)
1506 followed_two = insert(:user)
1507 _not_followed = insert(:user)
1509 {:ok, user} = User.follow(user, followed_one)
1510 {:ok, user} = User.follow(user, followed_two)
1514 |> assign(:user, user)
1515 |> get("/api/friends/ids")
1517 expected = [followed_one.id, followed_two.id]
1519 assert MapSet.equal?(
1520 MapSet.new(Poison.decode!(json_response(conn, 200))),
1521 MapSet.new(expected)
1526 describe "POST /api/account/update_profile.json" do
1527 test "it updates a user's profile", %{conn: conn} do
1528 user = insert(:user)
1529 user2 = insert(:user)
1533 |> assign(:user, user)
1534 |> post("/api/account/update_profile.json", %{
1535 "name" => "new name",
1536 "description" => "hi @#{user2.nickname}"
1539 user = Repo.get!(User, user.id)
1540 assert user.name == "new name"
1543 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1545 }'>@<span>#{user2.nickname}</span></a></span>"
1547 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1550 test "it sets and un-sets hide_follows", %{conn: conn} do
1551 user = insert(:user)
1554 |> assign(:user, user)
1555 |> post("/api/account/update_profile.json", %{
1556 "hide_follows" => "true"
1559 user = Repo.get!(User, user.id)
1560 assert user.info.hide_follows == true
1564 |> assign(:user, user)
1565 |> post("/api/account/update_profile.json", %{
1566 "hide_follows" => "false"
1569 user = refresh_record(user)
1570 assert user.info.hide_follows == false
1571 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1574 test "it sets and un-sets hide_followers", %{conn: conn} do
1575 user = insert(:user)
1578 |> assign(:user, user)
1579 |> post("/api/account/update_profile.json", %{
1580 "hide_followers" => "true"
1583 user = Repo.get!(User, user.id)
1584 assert user.info.hide_followers == true
1588 |> assign(:user, user)
1589 |> post("/api/account/update_profile.json", %{
1590 "hide_followers" => "false"
1593 user = Repo.get!(User, user.id)
1594 assert user.info.hide_followers == false
1595 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1598 test "it sets and un-sets show_role", %{conn: conn} do
1599 user = insert(:user)
1602 |> assign(:user, user)
1603 |> post("/api/account/update_profile.json", %{
1604 "show_role" => "true"
1607 user = Repo.get!(User, user.id)
1608 assert user.info.show_role == true
1612 |> assign(:user, user)
1613 |> post("/api/account/update_profile.json", %{
1614 "show_role" => "false"
1617 user = Repo.get!(User, user.id)
1618 assert user.info.show_role == false
1619 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1622 test "it sets and un-sets skip_thread_containment", %{conn: conn} do
1623 user = insert(:user)
1627 |> assign(:user, user)
1628 |> post("/api/account/update_profile.json", %{"skip_thread_containment" => "true"})
1629 |> json_response(200)
1631 assert response["pleroma"]["skip_thread_containment"] == true
1632 user = refresh_record(user)
1633 assert user.info.skip_thread_containment
1637 |> assign(:user, user)
1638 |> post("/api/account/update_profile.json", %{"skip_thread_containment" => "false"})
1639 |> json_response(200)
1641 assert response["pleroma"]["skip_thread_containment"] == false
1642 refute refresh_record(user).info.skip_thread_containment
1645 test "it locks an account", %{conn: conn} do
1646 user = insert(:user)
1650 |> assign(:user, user)
1651 |> post("/api/account/update_profile.json", %{
1655 user = Repo.get!(User, user.id)
1656 assert user.info.locked == true
1658 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1661 test "it unlocks an account", %{conn: conn} do
1662 user = insert(:user)
1666 |> assign(:user, user)
1667 |> post("/api/account/update_profile.json", %{
1671 user = Repo.get!(User, user.id)
1672 assert user.info.locked == false
1674 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1677 # Broken before the change to class="emoji" and non-<img/> in the DB
1679 test "it formats emojos", %{conn: conn} do
1680 user = insert(:user)
1684 |> assign(:user, user)
1685 |> post("/api/account/update_profile.json", %{
1686 "bio" => "I love our :moominmamma:"
1689 assert response = json_response(conn, 200)
1692 "description" => "I love our :moominmamma:",
1693 "description_html" =>
1694 ~s{I love our <img class="emoji" alt="moominmamma" title="moominmamma" src="} <>
1700 |> get("/api/users/show.json?user_id=#{user.nickname}")
1702 assert response == json_response(conn, 200)
1706 defp valid_user(_context) do
1707 user = insert(:user)
1711 defp with_credentials(conn, username, password) do
1712 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1713 put_req_header(conn, "authorization", header_content)
1716 describe "GET /api/search.json" do
1717 test "it returns search results", %{conn: conn} do
1718 user = insert(:user)
1719 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1721 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1722 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1726 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1728 assert [status] = json_response(conn, 200)
1729 assert status["id"] == activity.id
1733 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1734 test "it returns the tags timeline", %{conn: conn} do
1735 user = insert(:user)
1736 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1738 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1739 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1743 |> get("/api/statusnet/tags/timeline/2hu.json")
1745 assert [status] = json_response(conn, 200)
1746 assert status["id"] == activity.id
1750 test "Convert newlines to <br> in bio", %{conn: conn} do
1751 user = insert(:user)
1755 |> assign(:user, user)
1756 |> post("/api/account/update_profile.json", %{
1757 "description" => "Hello,\r\nWorld! I\n am a test."
1760 user = Repo.get!(User, user.id)
1761 assert user.bio == "Hello,<br>World! I<br> am a test."
1764 describe "POST /api/pleroma/change_password" do
1767 test "without credentials", %{conn: conn} do
1768 conn = post(conn, "/api/pleroma/change_password")
1769 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1772 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1775 |> with_credentials(current_user.nickname, "test")
1776 |> post("/api/pleroma/change_password", %{
1778 "new_password" => "newpass",
1779 "new_password_confirmation" => "newpass"
1782 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1785 test "with credentials, valid password and new password and confirmation not matching", %{
1791 |> with_credentials(current_user.nickname, "test")
1792 |> post("/api/pleroma/change_password", %{
1793 "password" => "test",
1794 "new_password" => "newpass",
1795 "new_password_confirmation" => "notnewpass"
1798 assert json_response(conn, 200) == %{
1799 "error" => "New password does not match confirmation."
1803 test "with credentials, valid password and invalid new password", %{
1809 |> with_credentials(current_user.nickname, "test")
1810 |> post("/api/pleroma/change_password", %{
1811 "password" => "test",
1812 "new_password" => "",
1813 "new_password_confirmation" => ""
1816 assert json_response(conn, 200) == %{
1817 "error" => "New password can't be blank."
1821 test "with credentials, valid password and matching new password and confirmation", %{
1827 |> with_credentials(current_user.nickname, "test")
1828 |> post("/api/pleroma/change_password", %{
1829 "password" => "test",
1830 "new_password" => "newpass",
1831 "new_password_confirmation" => "newpass"
1834 assert json_response(conn, 200) == %{"status" => "success"}
1835 fetched_user = User.get_cached_by_id(current_user.id)
1836 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1840 describe "POST /api/pleroma/delete_account" do
1843 test "without credentials", %{conn: conn} do
1844 conn = post(conn, "/api/pleroma/delete_account")
1845 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1848 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1851 |> with_credentials(current_user.nickname, "test")
1852 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1854 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1857 test "with credentials and valid password", %{conn: conn, user: current_user} do
1860 |> with_credentials(current_user.nickname, "test")
1861 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1863 assert json_response(conn, 200) == %{"status" => "success"}
1864 # Wait a second for the started task to end
1869 describe "GET /api/pleroma/friend_requests" do
1870 test "it lists friend requests" do
1871 user = insert(:user)
1872 other_user = insert(:user)
1874 {:ok, _activity} = ActivityPub.follow(other_user, user)
1876 user = User.get_cached_by_id(user.id)
1877 other_user = User.get_cached_by_id(other_user.id)
1879 assert User.following?(other_user, user) == false
1883 |> assign(:user, user)
1884 |> get("/api/pleroma/friend_requests")
1886 assert [relationship] = json_response(conn, 200)
1887 assert other_user.id == relationship["id"]
1890 test "requires 'read' permission", %{conn: conn} do
1891 token1 = insert(:oauth_token, scopes: ["write"])
1892 token2 = insert(:oauth_token, scopes: ["read"])
1894 for token <- [token1, token2] do
1897 |> put_req_header("authorization", "Bearer #{token.token}")
1898 |> get("/api/pleroma/friend_requests")
1900 if token == token1 do
1901 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1903 assert json_response(conn, 200)
1909 describe "POST /api/pleroma/friendships/approve" do
1910 test "it approves a friend request" do
1911 user = insert(:user)
1912 other_user = insert(:user)
1914 {:ok, _activity} = ActivityPub.follow(other_user, user)
1916 user = User.get_cached_by_id(user.id)
1917 other_user = User.get_cached_by_id(other_user.id)
1919 assert User.following?(other_user, user) == false
1923 |> assign(:user, user)
1924 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1926 assert relationship = json_response(conn, 200)
1927 assert other_user.id == relationship["id"]
1928 assert relationship["follows_you"] == true
1932 describe "POST /api/pleroma/friendships/deny" do
1933 test "it denies a friend request" do
1934 user = insert(:user)
1935 other_user = insert(:user)
1937 {:ok, _activity} = ActivityPub.follow(other_user, user)
1939 user = User.get_cached_by_id(user.id)
1940 other_user = User.get_cached_by_id(other_user.id)
1942 assert User.following?(other_user, user) == false
1946 |> assign(:user, user)
1947 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1949 assert relationship = json_response(conn, 200)
1950 assert other_user.id == relationship["id"]
1951 assert relationship["follows_you"] == false
1955 describe "GET /api/pleroma/search_user" do
1956 test "it returns users, ordered by similarity", %{conn: conn} do
1957 user = insert(:user, %{name: "eal"})
1958 user_two = insert(:user, %{name: "eal me"})
1959 _user_three = insert(:user, %{name: "zzz"})
1963 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1964 |> json_response(200)
1966 assert length(resp) == 2
1967 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1971 describe "POST /api/media/upload" do
1973 Pleroma.DataCase.ensure_local_uploader(context)
1976 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1979 user = insert(:user)
1981 upload_filename = "test/fixtures/image_tmp.jpg"
1982 File.cp!("test/fixtures/image.jpg", upload_filename)
1984 file = %Plug.Upload{
1985 content_type: "image/jpg",
1986 path: Path.absname(upload_filename),
1987 filename: "image.jpg"
1992 |> assign(:user, user)
1993 |> put_req_header("content-type", "application/octet-stream")
1994 |> post("/api/media/upload", %{
1997 |> json_response(:ok)
1999 assert response["media_id"]
2000 object = Repo.get(Object, response["media_id"])
2002 assert object.data["actor"] == User.ap_id(user)
2006 describe "POST /api/media/metadata/create" do
2008 object = insert(:note)
2009 user = User.get_cached_by_ap_id(object.data["actor"])
2010 %{object: object, user: user}
2013 test "it returns :forbidden status on attempt to modify someone else's upload", %{
2017 initial_description = object.data["name"]
2018 another_user = insert(:user)
2021 |> assign(:user, another_user)
2022 |> post("/api/media/metadata/create", %{"media_id" => object.id})
2023 |> json_response(:forbidden)
2025 object = Repo.get(Object, object.id)
2026 assert object.data["name"] == initial_description
2029 test "it updates `data[name]` of referenced Object with provided value", %{
2034 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
2037 |> assign(:user, user)
2038 |> post("/api/media/metadata/create", %{
2039 "media_id" => object.id,
2040 "alt_text" => %{"text" => description}
2042 |> json_response(:no_content)
2044 object = Repo.get(Object, object.id)
2045 assert object.data["name"] == description
2049 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
2050 test "it returns a list of pinned statuses", %{conn: conn} do
2051 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2053 user = insert(:user, %{name: "egor"})
2054 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
2055 {:ok, _} = CommonAPI.pin(activity_id, user)
2059 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
2060 |> json_response(200)
2062 assert length(resp) == 1
2063 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
2067 describe "POST /api/statuses/pin/:id" do
2069 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2070 [user: insert(:user)]
2073 test "without valid credentials", %{conn: conn} do
2074 note_activity = insert(:note_activity)
2075 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
2076 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
2079 test "with credentials", %{conn: conn, user: user} do
2080 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
2082 request_path = "/api/statuses/pin/#{activity.id}.json"
2086 |> with_credentials(user.nickname, "test")
2087 |> post(request_path)
2089 user = refresh_record(user)
2091 assert json_response(response, 200) ==
2092 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2096 describe "POST /api/statuses/unpin/:id" do
2098 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2099 [user: insert(:user)]
2102 test "without valid credentials", %{conn: conn} do
2103 note_activity = insert(:note_activity)
2104 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
2105 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
2108 test "with credentials", %{conn: conn, user: user} do
2109 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
2110 {:ok, activity} = CommonAPI.pin(activity.id, user)
2112 request_path = "/api/statuses/unpin/#{activity.id}.json"
2116 |> with_credentials(user.nickname, "test")
2117 |> post(request_path)
2119 user = refresh_record(user)
2121 assert json_response(response, 200) ==
2122 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2126 describe "GET /api/oauth_tokens" do
2128 token = insert(:oauth_token) |> Repo.preload(:user)
2133 test "renders list", %{token: token} do
2136 |> assign(:user, token.user)
2137 |> get("/api/oauth_tokens")
2140 json_response(response, 200)
2144 assert keys -- ["id", "app_name", "valid_until"] == []
2147 test "revoke token", %{token: token} do
2150 |> assign(:user, token.user)
2151 |> delete("/api/oauth_tokens/#{token.id}")
2153 tokens = Token.get_user_tokens(token.user)
2156 assert response.status == 201