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 500 when user is not found", %{conn: conn, user: user} do
1120 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1121 assert json_response(conn, :internal_server_error)
1124 test "it returns 500 when user is not local", %{conn: conn, user: user} do
1125 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1126 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1127 assert json_response(conn, :internal_server_error)
1131 describe "GET /api/account/confirm_email/:id/:token" do
1133 user = insert(:user)
1134 info_change = User.Info.confirmation_changeset(user.info, need_confirmation: true)
1138 |> Changeset.change()
1139 |> Changeset.put_embed(:info, info_change)
1142 assert user.info.confirmation_pending
1147 test "it redirects to root url", %{conn: conn, user: user} do
1148 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1150 assert 302 == conn.status
1153 test "it confirms the user account", %{conn: conn, user: user} do
1154 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1156 user = User.get_cached_by_id(user.id)
1158 refute user.info.confirmation_pending
1159 refute user.info.confirmation_token
1162 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1163 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1165 assert 500 == conn.status
1168 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1169 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1171 assert 500 == conn.status
1175 describe "POST /api/account/resend_confirmation_email" do
1177 setting = Pleroma.Config.get([:instance, :account_activation_required])
1180 Pleroma.Config.put([:instance, :account_activation_required], true)
1181 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1184 user = insert(:user)
1185 info_change = User.Info.confirmation_changeset(user.info, need_confirmation: true)
1189 |> Changeset.change()
1190 |> Changeset.put_embed(:info, info_change)
1193 assert user.info.confirmation_pending
1198 test "it returns 204 No Content", %{conn: conn, user: user} do
1200 |> assign(:user, user)
1201 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1202 |> json_response(:no_content)
1205 test "it sends confirmation email", %{conn: conn, user: user} do
1207 |> assign(:user, user)
1208 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1210 email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
1211 notify_email = Pleroma.Config.get([:instance, :notify_email])
1212 instance_name = Pleroma.Config.get([:instance, :name])
1215 from: {instance_name, notify_email},
1216 to: {user.name, user.email},
1217 html_body: email.html_body
1222 describe "GET /api/externalprofile/show" do
1223 test "it returns the user", %{conn: conn} do
1224 user = insert(:user)
1225 other_user = insert(:user)
1229 |> assign(:user, user)
1230 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1232 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1236 describe "GET /api/statuses/followers" do
1237 test "it returns a user's followers", %{conn: conn} do
1238 user = insert(:user)
1239 follower_one = insert(:user)
1240 follower_two = insert(:user)
1241 _not_follower = insert(:user)
1243 {:ok, follower_one} = User.follow(follower_one, user)
1244 {:ok, follower_two} = User.follow(follower_two, user)
1248 |> assign(:user, user)
1249 |> get("/api/statuses/followers")
1251 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1252 result = json_response(conn, 200)
1253 assert Enum.sort(expected) == Enum.sort(result)
1256 test "it returns 20 followers per page", %{conn: conn} do
1257 user = insert(:user)
1258 followers = insert_list(21, :user)
1260 Enum.each(followers, fn follower ->
1261 User.follow(follower, user)
1266 |> assign(:user, user)
1267 |> get("/api/statuses/followers")
1269 result = json_response(res_conn, 200)
1270 assert length(result) == 20
1274 |> assign(:user, user)
1275 |> get("/api/statuses/followers?page=2")
1277 result = json_response(res_conn, 200)
1278 assert length(result) == 1
1281 test "it returns a given user's followers with user_id", %{conn: conn} do
1282 user = insert(:user)
1283 follower_one = insert(:user)
1284 follower_two = insert(:user)
1285 not_follower = insert(:user)
1287 {:ok, follower_one} = User.follow(follower_one, user)
1288 {:ok, follower_two} = User.follow(follower_two, user)
1292 |> assign(:user, not_follower)
1293 |> get("/api/statuses/followers", %{"user_id" => user.id})
1295 assert MapSet.equal?(
1296 MapSet.new(json_response(conn, 200)),
1298 UserView.render("index.json", %{
1299 users: [follower_one, follower_two],
1306 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1307 user = insert(:user, %{info: %{hide_followers: true}})
1308 follower_one = insert(:user)
1309 follower_two = insert(:user)
1310 not_follower = insert(:user)
1312 {:ok, _follower_one} = User.follow(follower_one, user)
1313 {:ok, _follower_two} = User.follow(follower_two, user)
1317 |> assign(:user, not_follower)
1318 |> get("/api/statuses/followers", %{"user_id" => user.id})
1319 |> json_response(200)
1321 assert [] == response
1324 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1328 user = insert(:user, %{info: %{hide_followers: true}})
1329 follower_one = insert(:user)
1330 follower_two = insert(:user)
1331 _not_follower = insert(:user)
1333 {:ok, _follower_one} = User.follow(follower_one, user)
1334 {:ok, _follower_two} = User.follow(follower_two, user)
1338 |> assign(:user, user)
1339 |> get("/api/statuses/followers", %{"user_id" => user.id})
1341 refute [] == json_response(conn, 200)
1345 describe "GET /api/statuses/blocks" do
1346 test "it returns the list of users blocked by requester", %{conn: conn} do
1347 user = insert(:user)
1348 other_user = insert(:user)
1350 {:ok, user} = User.block(user, other_user)
1354 |> assign(:user, user)
1355 |> get("/api/statuses/blocks")
1357 expected = UserView.render("index.json", %{users: [other_user], for: user})
1358 result = json_response(conn, 200)
1359 assert Enum.sort(expected) == Enum.sort(result)
1363 describe "GET /api/statuses/friends" do
1364 test "it returns the logged in user's friends", %{conn: conn} do
1365 user = insert(:user)
1366 followed_one = insert(:user)
1367 followed_two = insert(:user)
1368 _not_followed = insert(:user)
1370 {:ok, user} = User.follow(user, followed_one)
1371 {:ok, user} = User.follow(user, followed_two)
1375 |> assign(:user, user)
1376 |> get("/api/statuses/friends")
1378 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1379 result = json_response(conn, 200)
1380 assert Enum.sort(expected) == Enum.sort(result)
1383 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1384 user = insert(:user)
1385 followeds = insert_list(21, :user)
1388 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1389 User.follow(user, followed)
1394 |> assign(:user, user)
1395 |> get("/api/statuses/friends")
1397 result = json_response(res_conn, 200)
1398 assert length(result) == 20
1402 |> assign(:user, user)
1403 |> get("/api/statuses/friends", %{page: 2})
1405 result = json_response(res_conn, 200)
1406 assert length(result) == 1
1410 |> assign(:user, user)
1411 |> get("/api/statuses/friends", %{all: true})
1413 result = json_response(res_conn, 200)
1414 assert length(result) == 21
1417 test "it returns a given user's friends with user_id", %{conn: conn} do
1418 user = insert(:user)
1419 followed_one = insert(:user)
1420 followed_two = insert(:user)
1421 _not_followed = insert(:user)
1423 {:ok, user} = User.follow(user, followed_one)
1424 {:ok, user} = User.follow(user, followed_two)
1428 |> assign(:user, user)
1429 |> get("/api/statuses/friends", %{"user_id" => user.id})
1431 assert MapSet.equal?(
1432 MapSet.new(json_response(conn, 200)),
1434 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1439 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1440 user = insert(:user, %{info: %{hide_follows: true}})
1441 followed_one = insert(:user)
1442 followed_two = insert(:user)
1443 not_followed = insert(:user)
1445 {:ok, user} = User.follow(user, followed_one)
1446 {:ok, user} = User.follow(user, followed_two)
1450 |> assign(:user, not_followed)
1451 |> get("/api/statuses/friends", %{"user_id" => user.id})
1453 assert [] == json_response(conn, 200)
1456 test "it returns friends when hide_follows is set to true if the user themselves request it",
1460 user = insert(:user, %{info: %{hide_follows: true}})
1461 followed_one = insert(:user)
1462 followed_two = insert(:user)
1463 _not_followed = insert(:user)
1465 {:ok, _user} = User.follow(user, followed_one)
1466 {:ok, _user} = User.follow(user, followed_two)
1470 |> assign(:user, user)
1471 |> get("/api/statuses/friends", %{"user_id" => user.id})
1472 |> json_response(200)
1474 refute [] == response
1477 test "it returns a given user's friends with screen_name", %{conn: conn} do
1478 user = insert(:user)
1479 followed_one = insert(:user)
1480 followed_two = insert(:user)
1481 _not_followed = insert(:user)
1483 {:ok, user} = User.follow(user, followed_one)
1484 {:ok, user} = User.follow(user, followed_two)
1488 |> assign(:user, user)
1489 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1491 assert MapSet.equal?(
1492 MapSet.new(json_response(conn, 200)),
1494 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1500 describe "GET /friends/ids" do
1501 test "it returns a user's friends", %{conn: conn} do
1502 user = insert(:user)
1503 followed_one = insert(:user)
1504 followed_two = insert(:user)
1505 _not_followed = insert(:user)
1507 {:ok, user} = User.follow(user, followed_one)
1508 {:ok, user} = User.follow(user, followed_two)
1512 |> assign(:user, user)
1513 |> get("/api/friends/ids")
1515 expected = [followed_one.id, followed_two.id]
1517 assert MapSet.equal?(
1518 MapSet.new(Poison.decode!(json_response(conn, 200))),
1519 MapSet.new(expected)
1524 describe "POST /api/account/update_profile.json" do
1525 test "it updates a user's profile", %{conn: conn} do
1526 user = insert(:user)
1527 user2 = insert(:user)
1531 |> assign(:user, user)
1532 |> post("/api/account/update_profile.json", %{
1533 "name" => "new name",
1534 "description" => "hi @#{user2.nickname}"
1537 user = Repo.get!(User, user.id)
1538 assert user.name == "new name"
1541 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1543 }'>@<span>#{user2.nickname}</span></a></span>"
1545 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1548 test "it sets and un-sets hide_follows", %{conn: conn} do
1549 user = insert(:user)
1552 |> assign(:user, user)
1553 |> post("/api/account/update_profile.json", %{
1554 "hide_follows" => "true"
1557 user = Repo.get!(User, user.id)
1558 assert user.info.hide_follows == true
1562 |> assign(:user, user)
1563 |> post("/api/account/update_profile.json", %{
1564 "hide_follows" => "false"
1567 user = refresh_record(user)
1568 assert user.info.hide_follows == false
1569 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1572 test "it sets and un-sets hide_followers", %{conn: conn} do
1573 user = insert(:user)
1576 |> assign(:user, user)
1577 |> post("/api/account/update_profile.json", %{
1578 "hide_followers" => "true"
1581 user = Repo.get!(User, user.id)
1582 assert user.info.hide_followers == true
1586 |> assign(:user, user)
1587 |> post("/api/account/update_profile.json", %{
1588 "hide_followers" => "false"
1591 user = Repo.get!(User, user.id)
1592 assert user.info.hide_followers == false
1593 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1596 test "it sets and un-sets show_role", %{conn: conn} do
1597 user = insert(:user)
1600 |> assign(:user, user)
1601 |> post("/api/account/update_profile.json", %{
1602 "show_role" => "true"
1605 user = Repo.get!(User, user.id)
1606 assert user.info.show_role == true
1610 |> assign(:user, user)
1611 |> post("/api/account/update_profile.json", %{
1612 "show_role" => "false"
1615 user = Repo.get!(User, user.id)
1616 assert user.info.show_role == false
1617 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1620 test "it sets and un-sets skip_thread_containment", %{conn: conn} do
1621 user = insert(:user)
1625 |> assign(:user, user)
1626 |> post("/api/account/update_profile.json", %{"skip_thread_containment" => "true"})
1627 |> json_response(200)
1629 assert response["pleroma"]["skip_thread_containment"] == true
1630 user = refresh_record(user)
1631 assert user.info.skip_thread_containment
1635 |> assign(:user, user)
1636 |> post("/api/account/update_profile.json", %{"skip_thread_containment" => "false"})
1637 |> json_response(200)
1639 assert response["pleroma"]["skip_thread_containment"] == false
1640 refute refresh_record(user).info.skip_thread_containment
1643 test "it locks an account", %{conn: conn} do
1644 user = insert(:user)
1648 |> assign(:user, user)
1649 |> post("/api/account/update_profile.json", %{
1653 user = Repo.get!(User, user.id)
1654 assert user.info.locked == true
1656 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1659 test "it unlocks an account", %{conn: conn} do
1660 user = insert(:user)
1664 |> assign(:user, user)
1665 |> post("/api/account/update_profile.json", %{
1669 user = Repo.get!(User, user.id)
1670 assert user.info.locked == false
1672 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1675 # Broken before the change to class="emoji" and non-<img/> in the DB
1677 test "it formats emojos", %{conn: conn} do
1678 user = insert(:user)
1682 |> assign(:user, user)
1683 |> post("/api/account/update_profile.json", %{
1684 "bio" => "I love our :moominmamma:"
1687 assert response = json_response(conn, 200)
1690 "description" => "I love our :moominmamma:",
1691 "description_html" =>
1692 ~s{I love our <img class="emoji" alt="moominmamma" title="moominmamma" src="} <>
1698 |> get("/api/users/show.json?user_id=#{user.nickname}")
1700 assert response == json_response(conn, 200)
1704 defp valid_user(_context) do
1705 user = insert(:user)
1709 defp with_credentials(conn, username, password) do
1710 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1711 put_req_header(conn, "authorization", header_content)
1714 describe "GET /api/search.json" do
1715 test "it returns search results", %{conn: conn} do
1716 user = insert(:user)
1717 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1719 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1720 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1724 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1726 assert [status] = json_response(conn, 200)
1727 assert status["id"] == activity.id
1731 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1732 test "it returns the tags timeline", %{conn: conn} do
1733 user = insert(:user)
1734 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1736 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1737 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1741 |> get("/api/statusnet/tags/timeline/2hu.json")
1743 assert [status] = json_response(conn, 200)
1744 assert status["id"] == activity.id
1748 test "Convert newlines to <br> in bio", %{conn: conn} do
1749 user = insert(:user)
1753 |> assign(:user, user)
1754 |> post("/api/account/update_profile.json", %{
1755 "description" => "Hello,\r\nWorld! I\n am a test."
1758 user = Repo.get!(User, user.id)
1759 assert user.bio == "Hello,<br>World! I<br> am a test."
1762 describe "POST /api/pleroma/change_password" do
1765 test "without credentials", %{conn: conn} do
1766 conn = post(conn, "/api/pleroma/change_password")
1767 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1770 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1773 |> with_credentials(current_user.nickname, "test")
1774 |> post("/api/pleroma/change_password", %{
1776 "new_password" => "newpass",
1777 "new_password_confirmation" => "newpass"
1780 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1783 test "with credentials, valid password and new password and confirmation not matching", %{
1789 |> with_credentials(current_user.nickname, "test")
1790 |> post("/api/pleroma/change_password", %{
1791 "password" => "test",
1792 "new_password" => "newpass",
1793 "new_password_confirmation" => "notnewpass"
1796 assert json_response(conn, 200) == %{
1797 "error" => "New password does not match confirmation."
1801 test "with credentials, valid password and invalid new password", %{
1807 |> with_credentials(current_user.nickname, "test")
1808 |> post("/api/pleroma/change_password", %{
1809 "password" => "test",
1810 "new_password" => "",
1811 "new_password_confirmation" => ""
1814 assert json_response(conn, 200) == %{
1815 "error" => "New password can't be blank."
1819 test "with credentials, valid password and matching new password and confirmation", %{
1825 |> with_credentials(current_user.nickname, "test")
1826 |> post("/api/pleroma/change_password", %{
1827 "password" => "test",
1828 "new_password" => "newpass",
1829 "new_password_confirmation" => "newpass"
1832 assert json_response(conn, 200) == %{"status" => "success"}
1833 fetched_user = User.get_cached_by_id(current_user.id)
1834 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1838 describe "POST /api/pleroma/delete_account" do
1841 test "without credentials", %{conn: conn} do
1842 conn = post(conn, "/api/pleroma/delete_account")
1843 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1846 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1849 |> with_credentials(current_user.nickname, "test")
1850 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1852 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1855 test "with credentials and valid password", %{conn: conn, user: current_user} do
1858 |> with_credentials(current_user.nickname, "test")
1859 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1861 assert json_response(conn, 200) == %{"status" => "success"}
1862 # Wait a second for the started task to end
1867 describe "GET /api/pleroma/friend_requests" do
1868 test "it lists friend requests" do
1869 user = insert(:user)
1870 other_user = insert(:user)
1872 {:ok, _activity} = ActivityPub.follow(other_user, user)
1874 user = User.get_cached_by_id(user.id)
1875 other_user = User.get_cached_by_id(other_user.id)
1877 assert User.following?(other_user, user) == false
1881 |> assign(:user, user)
1882 |> get("/api/pleroma/friend_requests")
1884 assert [relationship] = json_response(conn, 200)
1885 assert other_user.id == relationship["id"]
1888 test "requires 'read' permission", %{conn: conn} do
1889 token1 = insert(:oauth_token, scopes: ["write"])
1890 token2 = insert(:oauth_token, scopes: ["read"])
1892 for token <- [token1, token2] do
1895 |> put_req_header("authorization", "Bearer #{token.token}")
1896 |> get("/api/pleroma/friend_requests")
1898 if token == token1 do
1899 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1901 assert json_response(conn, 200)
1907 describe "POST /api/pleroma/friendships/approve" do
1908 test "it approves a friend request" do
1909 user = insert(:user)
1910 other_user = insert(:user)
1912 {:ok, _activity} = ActivityPub.follow(other_user, user)
1914 user = User.get_cached_by_id(user.id)
1915 other_user = User.get_cached_by_id(other_user.id)
1917 assert User.following?(other_user, user) == false
1921 |> assign(:user, user)
1922 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1924 assert relationship = json_response(conn, 200)
1925 assert other_user.id == relationship["id"]
1926 assert relationship["follows_you"] == true
1930 describe "POST /api/pleroma/friendships/deny" do
1931 test "it denies a friend request" do
1932 user = insert(:user)
1933 other_user = insert(:user)
1935 {:ok, _activity} = ActivityPub.follow(other_user, user)
1937 user = User.get_cached_by_id(user.id)
1938 other_user = User.get_cached_by_id(other_user.id)
1940 assert User.following?(other_user, user) == false
1944 |> assign(:user, user)
1945 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1947 assert relationship = json_response(conn, 200)
1948 assert other_user.id == relationship["id"]
1949 assert relationship["follows_you"] == false
1953 describe "GET /api/pleroma/search_user" do
1954 test "it returns users, ordered by similarity", %{conn: conn} do
1955 user = insert(:user, %{name: "eal"})
1956 user_two = insert(:user, %{name: "eal me"})
1957 _user_three = insert(:user, %{name: "zzz"})
1961 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1962 |> json_response(200)
1964 assert length(resp) == 2
1965 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1969 describe "POST /api/media/upload" do
1971 Pleroma.DataCase.ensure_local_uploader(context)
1974 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1977 user = insert(:user)
1979 upload_filename = "test/fixtures/image_tmp.jpg"
1980 File.cp!("test/fixtures/image.jpg", upload_filename)
1982 file = %Plug.Upload{
1983 content_type: "image/jpg",
1984 path: Path.absname(upload_filename),
1985 filename: "image.jpg"
1990 |> assign(:user, user)
1991 |> put_req_header("content-type", "application/octet-stream")
1992 |> post("/api/media/upload", %{
1995 |> json_response(:ok)
1997 assert response["media_id"]
1998 object = Repo.get(Object, response["media_id"])
2000 assert object.data["actor"] == User.ap_id(user)
2004 describe "POST /api/media/metadata/create" do
2006 object = insert(:note)
2007 user = User.get_cached_by_ap_id(object.data["actor"])
2008 %{object: object, user: user}
2011 test "it returns :forbidden status on attempt to modify someone else's upload", %{
2015 initial_description = object.data["name"]
2016 another_user = insert(:user)
2019 |> assign(:user, another_user)
2020 |> post("/api/media/metadata/create", %{"media_id" => object.id})
2021 |> json_response(:forbidden)
2023 object = Repo.get(Object, object.id)
2024 assert object.data["name"] == initial_description
2027 test "it updates `data[name]` of referenced Object with provided value", %{
2032 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
2035 |> assign(:user, user)
2036 |> post("/api/media/metadata/create", %{
2037 "media_id" => object.id,
2038 "alt_text" => %{"text" => description}
2040 |> json_response(:no_content)
2042 object = Repo.get(Object, object.id)
2043 assert object.data["name"] == description
2047 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
2048 test "it returns a list of pinned statuses", %{conn: conn} do
2049 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2051 user = insert(:user, %{name: "egor"})
2052 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
2053 {:ok, _} = CommonAPI.pin(activity_id, user)
2057 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
2058 |> json_response(200)
2060 assert length(resp) == 1
2061 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
2065 describe "POST /api/statuses/pin/:id" do
2067 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2068 [user: insert(:user)]
2071 test "without valid credentials", %{conn: conn} do
2072 note_activity = insert(:note_activity)
2073 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
2074 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
2077 test "with credentials", %{conn: conn, user: user} do
2078 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
2080 request_path = "/api/statuses/pin/#{activity.id}.json"
2084 |> with_credentials(user.nickname, "test")
2085 |> post(request_path)
2087 user = refresh_record(user)
2089 assert json_response(response, 200) ==
2090 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2094 describe "POST /api/statuses/unpin/:id" do
2096 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2097 [user: insert(:user)]
2100 test "without valid credentials", %{conn: conn} do
2101 note_activity = insert(:note_activity)
2102 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
2103 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
2106 test "with credentials", %{conn: conn, user: user} do
2107 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
2108 {:ok, activity} = CommonAPI.pin(activity.id, user)
2110 request_path = "/api/statuses/unpin/#{activity.id}.json"
2114 |> with_credentials(user.nickname, "test")
2115 |> post(request_path)
2117 user = refresh_record(user)
2119 assert json_response(response, 200) ==
2120 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2124 describe "GET /api/oauth_tokens" do
2126 token = insert(:oauth_token) |> Repo.preload(:user)
2131 test "renders list", %{token: token} do
2134 |> assign(:user, token.user)
2135 |> get("/api/oauth_tokens")
2138 json_response(response, 200)
2142 assert keys -- ["id", "app_name", "valid_until"] == []
2145 test "revoke token", %{token: token} do
2148 |> assign(:user, token.user)
2149 |> delete("/api/oauth_tokens/#{token.id}")
2151 tokens = Token.get_user_tokens(token.user)
2154 assert response.status == 201