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"
45 describe "POST /api/qvitter/update_background_image" do
46 test "it updates the background", %{conn: conn} do
50 |> assign(:user, user)
51 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => @banner})
54 user = refresh_record(user)
55 assert user.info.background["type"] == "Image"
59 describe "POST /api/account/verify_credentials" do
62 test "without valid credentials", %{conn: conn} do
63 conn = post(conn, "/api/account/verify_credentials.json")
64 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
67 test "with credentials", %{conn: conn, user: user} do
70 |> with_credentials(user.nickname, "test")
71 |> post("/api/account/verify_credentials.json")
75 UserView.render("show.json", %{user: user, token: response["token"], for: user})
79 describe "POST /statuses/update.json" do
82 test "without valid credentials", %{conn: conn} do
83 conn = post(conn, "/api/statuses/update.json")
84 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
87 test "with credentials", %{conn: conn, user: user} do
88 conn_with_creds = conn |> with_credentials(user.nickname, "test")
89 request_path = "/api/statuses/update.json"
92 "request" => request_path,
93 "error" => "Client must provide a 'status' parameter with a value."
100 assert json_response(conn, 400) == error_response
104 |> post(request_path, %{status: ""})
106 assert json_response(conn, 400) == error_response
110 |> post(request_path, %{status: " "})
112 assert json_response(conn, 400) == error_response
114 # we post with visibility private in order to avoid triggering relay
117 |> post(request_path, %{status: "Nice meme.", visibility: "private"})
119 assert json_response(conn, 200) ==
120 ActivityView.render("activity.json", %{
121 activity: Repo.one(Activity),
128 describe "GET /statuses/public_timeline.json" do
131 test "returns statuses", %{conn: conn} do
133 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
134 ActivityBuilder.insert_list(10, %{}, %{user: user})
135 since_id = List.last(activities).id
139 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
141 response = json_response(conn, 200)
143 assert length(response) == 10
146 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
148 Application.get_env(:pleroma, :instance)
149 |> Keyword.put(:public, false)
151 Application.put_env(:pleroma, :instance, instance)
154 |> get("/api/statuses/public_timeline.json")
155 |> json_response(403)
158 Application.get_env(:pleroma, :instance)
159 |> Keyword.put(:public, true)
161 Application.put_env(:pleroma, :instance, instance)
164 test "returns 200 to authenticated request when the instance is not public",
165 %{conn: conn, user: user} do
167 Application.get_env(:pleroma, :instance)
168 |> Keyword.put(:public, false)
170 Application.put_env(:pleroma, :instance, instance)
173 |> with_credentials(user.nickname, "test")
174 |> get("/api/statuses/public_timeline.json")
175 |> json_response(200)
178 Application.get_env(:pleroma, :instance)
179 |> Keyword.put(:public, true)
181 Application.put_env(:pleroma, :instance, instance)
184 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
186 |> get("/api/statuses/public_timeline.json")
187 |> json_response(200)
190 test "returns 200 to authenticated request when the instance is public",
191 %{conn: conn, user: user} do
193 |> with_credentials(user.nickname, "test")
194 |> get("/api/statuses/public_timeline.json")
195 |> json_response(200)
198 test_with_mock "treats user as unauthenticated if `assigns[:token]` is present but lacks `read` permission",
202 token = insert(:oauth_token, scopes: ["write"])
205 |> put_req_header("authorization", "Bearer #{token.token}")
206 |> get("/api/statuses/public_timeline.json")
207 |> json_response(200)
209 assert called(Controller.public_timeline(%{assigns: %{user: nil}}, :_))
213 describe "GET /statuses/public_and_external_timeline.json" do
216 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
218 Application.get_env(:pleroma, :instance)
219 |> Keyword.put(:public, false)
221 Application.put_env(:pleroma, :instance, instance)
224 |> get("/api/statuses/public_and_external_timeline.json")
225 |> json_response(403)
228 Application.get_env(:pleroma, :instance)
229 |> Keyword.put(:public, true)
231 Application.put_env(:pleroma, :instance, instance)
234 test "returns 200 to authenticated request when the instance is not public",
235 %{conn: conn, user: user} do
237 Application.get_env(:pleroma, :instance)
238 |> Keyword.put(:public, false)
240 Application.put_env(:pleroma, :instance, instance)
243 |> with_credentials(user.nickname, "test")
244 |> get("/api/statuses/public_and_external_timeline.json")
245 |> json_response(200)
248 Application.get_env(:pleroma, :instance)
249 |> Keyword.put(:public, true)
251 Application.put_env(:pleroma, :instance, instance)
254 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
256 |> get("/api/statuses/public_and_external_timeline.json")
257 |> json_response(200)
260 test "returns 200 to authenticated request when the instance is public",
261 %{conn: conn, user: user} do
263 |> with_credentials(user.nickname, "test")
264 |> get("/api/statuses/public_and_external_timeline.json")
265 |> json_response(200)
269 describe "GET /statuses/show/:id.json" do
270 test "returns one status", %{conn: conn} do
272 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
273 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
277 |> get("/api/statuses/show/#{activity.id}.json")
279 response = json_response(conn, 200)
281 assert response == ActivityView.render("activity.json", %{activity: activity, user: actor})
285 describe "GET /users/show.json" do
286 test "gets user with screen_name", %{conn: conn} do
291 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
293 response = json_response(conn, 200)
295 assert response["id"] == user.id
298 test "gets user with user_id", %{conn: conn} do
303 |> get("/api/users/show.json", %{"user_id" => user.id})
305 response = json_response(conn, 200)
307 assert response["id"] == user.id
310 test "gets a user for a logged in user", %{conn: conn} do
312 logged_in = insert(:user)
314 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
318 |> with_credentials(logged_in.nickname, "test")
319 |> get("/api/users/show.json", %{"user_id" => user.id})
321 response = json_response(conn, 200)
323 assert response["following"] == true
327 describe "GET /statusnet/conversation/:id.json" do
328 test "returns the statuses in the conversation", %{conn: conn} do
329 {:ok, _user} = UserBuilder.insert()
330 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
331 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
332 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
336 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
338 response = json_response(conn, 200)
340 assert length(response) == 2
344 describe "GET /statuses/friends_timeline.json" do
347 test "without valid credentials", %{conn: conn} do
348 conn = get(conn, "/api/statuses/friends_timeline.json")
349 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
352 test "with credentials", %{conn: conn, user: current_user} do
356 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
358 returned_activities =
359 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
361 other_user = insert(:user)
362 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
363 since_id = List.last(activities).id
366 Changeset.change(current_user, following: [User.ap_followers(user)])
371 |> with_credentials(current_user.nickname, "test")
372 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
374 response = json_response(conn, 200)
376 assert length(response) == 10
379 Enum.map(returned_activities, fn activity ->
380 ActivityView.render("activity.json", %{
382 user: User.get_cached_by_ap_id(activity.data["actor"]),
389 describe "GET /statuses/dm_timeline.json" do
390 test "it show direct messages", %{conn: conn} do
391 user_one = insert(:user)
392 user_two = insert(:user)
394 {:ok, user_two} = User.follow(user_two, user_one)
397 CommonAPI.post(user_one, %{
398 "status" => "Hi @#{user_two.nickname}!",
399 "visibility" => "direct"
403 CommonAPI.post(user_two, %{
404 "status" => "Hi @#{user_one.nickname}!",
405 "visibility" => "direct"
408 {:ok, _follower_only} =
409 CommonAPI.post(user_one, %{
410 "status" => "Hi @#{user_two.nickname}!",
411 "visibility" => "private"
414 # Only direct should be visible here
417 |> assign(:user, user_two)
418 |> get("/api/statuses/dm_timeline.json")
420 [status, status_two] = json_response(res_conn, 200)
421 assert status["id"] == direct_two.id
422 assert status_two["id"] == direct.id
425 test "doesn't include DMs from blocked users", %{conn: conn} do
426 blocker = insert(:user)
427 blocked = insert(:user)
429 {:ok, blocker} = User.block(blocker, blocked)
431 {:ok, _blocked_direct} =
432 CommonAPI.post(blocked, %{
433 "status" => "Hi @#{blocker.nickname}!",
434 "visibility" => "direct"
438 CommonAPI.post(user, %{
439 "status" => "Hi @#{blocker.nickname}!",
440 "visibility" => "direct"
445 |> assign(:user, blocker)
446 |> get("/api/statuses/dm_timeline.json")
448 [status] = json_response(res_conn, 200)
449 assert status["id"] == direct.id
453 describe "GET /statuses/mentions.json" do
456 test "without valid credentials", %{conn: conn} do
457 conn = get(conn, "/api/statuses/mentions.json")
458 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
461 test "with credentials", %{conn: conn, user: current_user} do
463 CommonAPI.post(current_user, %{
464 "status" => "why is tenshi eating a corndog so cute?",
465 "visibility" => "public"
470 |> with_credentials(current_user.nickname, "test")
471 |> get("/api/statuses/mentions.json")
473 response = json_response(conn, 200)
475 assert length(response) == 1
477 assert Enum.at(response, 0) ==
478 ActivityView.render("activity.json", %{
485 test "does not show DMs in mentions timeline", %{conn: conn, user: current_user} do
487 CommonAPI.post(current_user, %{
488 "status" => "Have you guys ever seen how cute tenshi eating a corndog is?",
489 "visibility" => "direct"
494 |> with_credentials(current_user.nickname, "test")
495 |> get("/api/statuses/mentions.json")
497 response = json_response(conn, 200)
499 assert Enum.empty?(response)
503 describe "GET /api/qvitter/statuses/notifications.json" do
506 test "without valid credentials", %{conn: conn} do
507 conn = get(conn, "/api/qvitter/statuses/notifications.json")
508 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
511 test "with credentials", %{conn: conn, user: current_user} do
512 other_user = insert(:user)
515 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
519 |> with_credentials(current_user.nickname, "test")
520 |> get("/api/qvitter/statuses/notifications.json")
522 response = json_response(conn, 200)
524 assert length(response) == 1
527 NotificationView.render("notification.json", %{
528 notifications: Notification.for_user(current_user),
534 describe "POST /api/qvitter/statuses/notifications/read" do
537 test "without valid credentials", %{conn: conn} do
538 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
539 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
542 test "with credentials, without any params", %{conn: conn, user: current_user} do
545 |> with_credentials(current_user.nickname, "test")
546 |> post("/api/qvitter/statuses/notifications/read")
548 assert json_response(conn, 400) == %{
549 "error" => "You need to specify latest_id",
550 "request" => "/api/qvitter/statuses/notifications/read"
554 test "with credentials, with params", %{conn: conn, user: current_user} do
555 other_user = insert(:user)
558 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
562 |> with_credentials(current_user.nickname, "test")
563 |> get("/api/qvitter/statuses/notifications.json")
565 [notification] = response = json_response(response_conn, 200)
567 assert length(response) == 1
569 assert notification["is_seen"] == 0
573 |> with_credentials(current_user.nickname, "test")
574 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
576 [notification] = response = json_response(response_conn, 200)
578 assert length(response) == 1
580 assert notification["is_seen"] == 1
584 describe "GET /statuses/user_timeline.json" do
587 test "without any params", %{conn: conn} do
588 conn = get(conn, "/api/statuses/user_timeline.json")
590 assert json_response(conn, 400) == %{
591 "error" => "You need to specify screen_name or user_id",
592 "request" => "/api/statuses/user_timeline.json"
596 test "with user_id", %{conn: conn} do
598 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
600 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
601 response = json_response(conn, 200)
602 assert length(response) == 1
604 assert Enum.at(response, 0) ==
605 ActivityView.render("activity.json", %{user: user, activity: activity})
608 test "with screen_name", %{conn: conn} do
610 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
612 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
613 response = json_response(conn, 200)
614 assert length(response) == 1
616 assert Enum.at(response, 0) ==
617 ActivityView.render("activity.json", %{user: user, activity: activity})
620 test "with credentials", %{conn: conn, user: current_user} do
621 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
625 |> with_credentials(current_user.nickname, "test")
626 |> get("/api/statuses/user_timeline.json")
628 response = json_response(conn, 200)
630 assert length(response) == 1
632 assert Enum.at(response, 0) ==
633 ActivityView.render("activity.json", %{
640 test "with credentials with user_id", %{conn: conn, user: current_user} do
642 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
646 |> with_credentials(current_user.nickname, "test")
647 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
649 response = json_response(conn, 200)
651 assert length(response) == 1
653 assert Enum.at(response, 0) ==
654 ActivityView.render("activity.json", %{user: user, activity: activity})
657 test "with credentials screen_name", %{conn: conn, user: current_user} do
659 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
663 |> with_credentials(current_user.nickname, "test")
664 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
666 response = json_response(conn, 200)
668 assert length(response) == 1
670 assert Enum.at(response, 0) ==
671 ActivityView.render("activity.json", %{user: user, activity: activity})
674 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
676 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
677 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
681 |> with_credentials(current_user.nickname, "test")
682 |> get("/api/statuses/user_timeline.json", %{
683 "user_id" => user.id,
684 "include_rts" => "false"
687 response = json_response(conn, 200)
689 assert length(response) == 1
691 assert Enum.at(response, 0) ==
692 ActivityView.render("activity.json", %{user: user, activity: activity})
696 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
698 response = json_response(conn, 200)
700 assert length(response) == 1
702 assert Enum.at(response, 0) ==
703 ActivityView.render("activity.json", %{user: user, activity: activity})
707 describe "POST /friendships/create.json" do
710 test "without valid credentials", %{conn: conn} do
711 conn = post(conn, "/api/friendships/create.json")
712 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
715 test "with credentials", %{conn: conn, user: current_user} do
716 followed = insert(:user)
720 |> with_credentials(current_user.nickname, "test")
721 |> post("/api/friendships/create.json", %{user_id: followed.id})
723 current_user = User.get_by_id(current_user.id)
724 assert User.ap_followers(followed) in current_user.following
726 assert json_response(conn, 200) ==
727 UserView.render("show.json", %{user: followed, for: current_user})
730 test "for restricted account", %{conn: conn, user: current_user} do
731 followed = insert(:user, info: %User.Info{locked: true})
735 |> with_credentials(current_user.nickname, "test")
736 |> post("/api/friendships/create.json", %{user_id: followed.id})
738 current_user = User.get_by_id(current_user.id)
739 followed = User.get_by_id(followed.id)
741 refute User.ap_followers(followed) in current_user.following
743 assert json_response(conn, 200) ==
744 UserView.render("show.json", %{user: followed, for: current_user})
748 describe "POST /friendships/destroy.json" do
751 test "without valid credentials", %{conn: conn} do
752 conn = post(conn, "/api/friendships/destroy.json")
753 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
756 test "with credentials", %{conn: conn, user: current_user} do
757 followed = insert(:user)
759 {:ok, current_user} = User.follow(current_user, followed)
760 assert User.ap_followers(followed) in current_user.following
761 ActivityPub.follow(current_user, followed)
765 |> with_credentials(current_user.nickname, "test")
766 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
768 current_user = User.get_by_id(current_user.id)
769 assert current_user.following == [current_user.ap_id]
771 assert json_response(conn, 200) ==
772 UserView.render("show.json", %{user: followed, for: current_user})
776 describe "POST /blocks/create.json" do
779 test "without valid credentials", %{conn: conn} do
780 conn = post(conn, "/api/blocks/create.json")
781 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
784 test "with credentials", %{conn: conn, user: current_user} do
785 blocked = insert(:user)
789 |> with_credentials(current_user.nickname, "test")
790 |> post("/api/blocks/create.json", %{user_id: blocked.id})
792 current_user = User.get_by_id(current_user.id)
793 assert User.blocks?(current_user, blocked)
795 assert json_response(conn, 200) ==
796 UserView.render("show.json", %{user: blocked, for: current_user})
800 describe "POST /blocks/destroy.json" do
803 test "without valid credentials", %{conn: conn} do
804 conn = post(conn, "/api/blocks/destroy.json")
805 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
808 test "with credentials", %{conn: conn, user: current_user} do
809 blocked = insert(:user)
811 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
812 assert User.blocks?(current_user, blocked)
816 |> with_credentials(current_user.nickname, "test")
817 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
819 current_user = User.get_by_id(current_user.id)
820 assert current_user.info.blocks == []
822 assert json_response(conn, 200) ==
823 UserView.render("show.json", %{user: blocked, for: current_user})
827 describe "GET /help/test.json" do
828 test "returns \"ok\"", %{conn: conn} do
829 conn = get(conn, "/api/help/test.json")
830 assert json_response(conn, 200) == "ok"
834 describe "POST /api/qvitter/update_avatar.json" do
837 test "without valid credentials", %{conn: conn} do
838 conn = post(conn, "/api/qvitter/update_avatar.json")
839 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
842 test "with credentials", %{conn: conn, user: current_user} do
843 avatar_image = File.read!("test/fixtures/avatar_data_uri")
847 |> with_credentials(current_user.nickname, "test")
848 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
850 current_user = User.get_by_id(current_user.id)
851 assert is_map(current_user.avatar)
853 assert json_response(conn, 200) ==
854 UserView.render("show.json", %{user: current_user, for: current_user})
858 describe "GET /api/qvitter/mutes.json" do
861 test "unimplemented mutes without valid credentials", %{conn: conn} do
862 conn = get(conn, "/api/qvitter/mutes.json")
863 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
866 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
869 |> with_credentials(current_user.nickname, "test")
870 |> get("/api/qvitter/mutes.json")
871 |> json_response(200)
877 describe "POST /api/favorites/create/:id" do
880 test "without valid credentials", %{conn: conn} do
881 note_activity = insert(:note_activity)
882 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
883 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
886 test "with credentials", %{conn: conn, user: current_user} do
887 note_activity = insert(:note_activity)
891 |> with_credentials(current_user.nickname, "test")
892 |> post("/api/favorites/create/#{note_activity.id}.json")
894 assert json_response(conn, 200)
897 test "with credentials, invalid param", %{conn: conn, user: current_user} do
900 |> with_credentials(current_user.nickname, "test")
901 |> post("/api/favorites/create/wrong.json")
903 assert json_response(conn, 400)
906 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
909 |> with_credentials(current_user.nickname, "test")
910 |> post("/api/favorites/create/1.json")
912 assert json_response(conn, 400)
916 describe "POST /api/favorites/destroy/:id" do
919 test "without valid credentials", %{conn: conn} do
920 note_activity = insert(:note_activity)
921 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
922 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
925 test "with credentials", %{conn: conn, user: current_user} do
926 note_activity = insert(:note_activity)
927 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
928 ActivityPub.like(current_user, object)
932 |> with_credentials(current_user.nickname, "test")
933 |> post("/api/favorites/destroy/#{note_activity.id}.json")
935 assert json_response(conn, 200)
939 describe "POST /api/statuses/retweet/:id" do
942 test "without valid credentials", %{conn: conn} do
943 note_activity = insert(:note_activity)
944 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
945 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
948 test "with credentials", %{conn: conn, user: current_user} do
949 note_activity = insert(:note_activity)
951 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
955 |> with_credentials(current_user.nickname, "test")
956 |> post(request_path)
958 activity = Activity.get_by_id(note_activity.id)
959 activity_user = User.get_by_ap_id(note_activity.data["actor"])
961 assert json_response(response, 200) ==
962 ActivityView.render("activity.json", %{
970 describe "POST /api/statuses/unretweet/:id" do
973 test "without valid credentials", %{conn: conn} do
974 note_activity = insert(:note_activity)
975 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
976 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
979 test "with credentials", %{conn: conn, user: current_user} do
980 note_activity = insert(:note_activity)
982 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
986 |> with_credentials(current_user.nickname, "test")
987 |> post(request_path)
989 request_path = String.replace(request_path, "retweet", "unretweet")
993 |> with_credentials(current_user.nickname, "test")
994 |> post(request_path)
996 activity = Activity.get_by_id(note_activity.id)
997 activity_user = User.get_by_ap_id(note_activity.data["actor"])
999 assert json_response(response, 200) ==
1000 ActivityView.render("activity.json", %{
1001 user: activity_user,
1008 describe "POST /api/account/register" do
1009 test "it creates a new user", %{conn: conn} do
1011 "nickname" => "lain",
1012 "email" => "lain@wired.jp",
1013 "fullname" => "lain iwakura",
1014 "bio" => "close the world.",
1015 "password" => "bear",
1021 |> post("/api/account/register", data)
1023 user = json_response(conn, 200)
1025 fetched_user = User.get_by_nickname("lain")
1026 assert user == UserView.render("show.json", %{user: fetched_user})
1029 test "it returns errors on a problem", %{conn: conn} do
1031 "email" => "lain@wired.jp",
1032 "fullname" => "lain iwakura",
1033 "bio" => "close the world.",
1034 "password" => "bear",
1040 |> post("/api/account/register", data)
1042 errors = json_response(conn, 400)
1044 assert is_binary(errors["error"])
1048 describe "POST /api/account/password_reset, with valid parameters" do
1049 setup %{conn: conn} do
1050 user = insert(:user)
1051 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1052 %{conn: conn, user: user}
1055 test "it returns 204", %{conn: conn} do
1056 assert json_response(conn, :no_content)
1059 test "it creates a PasswordResetToken record for user", %{user: user} do
1060 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1064 test "it sends an email to user", %{user: user} do
1065 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1067 email = Pleroma.UserEmail.password_reset_email(user, token_record.token)
1068 notify_email = Pleroma.Config.get([:instance, :notify_email])
1069 instance_name = Pleroma.Config.get([:instance, :name])
1072 from: {instance_name, notify_email},
1073 to: {user.name, user.email},
1074 html_body: email.html_body
1079 describe "POST /api/account/password_reset, with invalid parameters" do
1082 test "it returns 500 when user is not found", %{conn: conn, user: user} do
1083 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1084 assert json_response(conn, :internal_server_error)
1087 test "it returns 500 when user is not local", %{conn: conn, user: user} do
1088 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1089 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1090 assert json_response(conn, :internal_server_error)
1094 describe "GET /api/account/confirm_email/:id/:token" do
1096 user = insert(:user)
1097 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1101 |> Changeset.change()
1102 |> Changeset.put_embed(:info, info_change)
1105 assert user.info.confirmation_pending
1110 test "it redirects to root url", %{conn: conn, user: user} do
1111 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1113 assert 302 == conn.status
1116 test "it confirms the user account", %{conn: conn, user: user} do
1117 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1119 user = User.get_by_id(user.id)
1121 refute user.info.confirmation_pending
1122 refute user.info.confirmation_token
1125 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1126 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1128 assert 500 == conn.status
1131 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1132 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1134 assert 500 == conn.status
1138 describe "POST /api/account/resend_confirmation_email" do
1140 setting = Pleroma.Config.get([:instance, :account_activation_required])
1143 Pleroma.Config.put([:instance, :account_activation_required], true)
1144 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1147 user = insert(:user)
1148 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1152 |> Changeset.change()
1153 |> Changeset.put_embed(:info, info_change)
1156 assert user.info.confirmation_pending
1161 test "it returns 204 No Content", %{conn: conn, user: user} do
1163 |> assign(:user, user)
1164 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1165 |> json_response(:no_content)
1168 test "it sends confirmation email", %{conn: conn, user: user} do
1170 |> assign(:user, user)
1171 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1173 email = Pleroma.UserEmail.account_confirmation_email(user)
1174 notify_email = Pleroma.Config.get([:instance, :notify_email])
1175 instance_name = Pleroma.Config.get([:instance, :name])
1178 from: {instance_name, notify_email},
1179 to: {user.name, user.email},
1180 html_body: email.html_body
1185 describe "GET /api/externalprofile/show" do
1186 test "it returns the user", %{conn: conn} do
1187 user = insert(:user)
1188 other_user = insert(:user)
1192 |> assign(:user, user)
1193 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1195 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1199 describe "GET /api/statuses/followers" do
1200 test "it returns a user's followers", %{conn: conn} do
1201 user = insert(:user)
1202 follower_one = insert(:user)
1203 follower_two = insert(:user)
1204 _not_follower = insert(:user)
1206 {:ok, follower_one} = User.follow(follower_one, user)
1207 {:ok, follower_two} = User.follow(follower_two, user)
1211 |> assign(:user, user)
1212 |> get("/api/statuses/followers")
1214 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1215 result = json_response(conn, 200)
1216 assert Enum.sort(expected) == Enum.sort(result)
1219 test "it returns 20 followers per page", %{conn: conn} do
1220 user = insert(:user)
1221 followers = insert_list(21, :user)
1223 Enum.each(followers, fn follower ->
1224 User.follow(follower, user)
1229 |> assign(:user, user)
1230 |> get("/api/statuses/followers")
1232 result = json_response(res_conn, 200)
1233 assert length(result) == 20
1237 |> assign(:user, user)
1238 |> get("/api/statuses/followers?page=2")
1240 result = json_response(res_conn, 200)
1241 assert length(result) == 1
1244 test "it returns a given user's followers with user_id", %{conn: conn} do
1245 user = insert(:user)
1246 follower_one = insert(:user)
1247 follower_two = insert(:user)
1248 not_follower = insert(:user)
1250 {:ok, follower_one} = User.follow(follower_one, user)
1251 {:ok, follower_two} = User.follow(follower_two, user)
1255 |> assign(:user, not_follower)
1256 |> get("/api/statuses/followers", %{"user_id" => user.id})
1258 assert MapSet.equal?(
1259 MapSet.new(json_response(conn, 200)),
1261 UserView.render("index.json", %{
1262 users: [follower_one, follower_two],
1269 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1270 user = insert(:user, %{info: %{hide_followers: true}})
1271 follower_one = insert(:user)
1272 follower_two = insert(:user)
1273 not_follower = insert(:user)
1275 {:ok, _follower_one} = User.follow(follower_one, user)
1276 {:ok, _follower_two} = User.follow(follower_two, user)
1280 |> assign(:user, not_follower)
1281 |> get("/api/statuses/followers", %{"user_id" => user.id})
1282 |> json_response(200)
1284 assert [] == response
1287 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1291 user = insert(:user, %{info: %{hide_followers: true}})
1292 follower_one = insert(:user)
1293 follower_two = insert(:user)
1294 _not_follower = insert(:user)
1296 {:ok, _follower_one} = User.follow(follower_one, user)
1297 {:ok, _follower_two} = User.follow(follower_two, user)
1301 |> assign(:user, user)
1302 |> get("/api/statuses/followers", %{"user_id" => user.id})
1304 refute [] == json_response(conn, 200)
1308 describe "GET /api/statuses/blocks" do
1309 test "it returns the list of users blocked by requester", %{conn: conn} do
1310 user = insert(:user)
1311 other_user = insert(:user)
1313 {:ok, user} = User.block(user, other_user)
1317 |> assign(:user, user)
1318 |> get("/api/statuses/blocks")
1320 expected = UserView.render("index.json", %{users: [other_user], for: user})
1321 result = json_response(conn, 200)
1322 assert Enum.sort(expected) == Enum.sort(result)
1326 describe "GET /api/statuses/friends" do
1327 test "it returns the logged in user's friends", %{conn: conn} do
1328 user = insert(:user)
1329 followed_one = insert(:user)
1330 followed_two = insert(:user)
1331 _not_followed = insert(:user)
1333 {:ok, user} = User.follow(user, followed_one)
1334 {:ok, user} = User.follow(user, followed_two)
1338 |> assign(:user, user)
1339 |> get("/api/statuses/friends")
1341 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1342 result = json_response(conn, 200)
1343 assert Enum.sort(expected) == Enum.sort(result)
1346 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1347 user = insert(:user)
1348 followeds = insert_list(21, :user)
1351 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1352 User.follow(user, followed)
1357 |> assign(:user, user)
1358 |> get("/api/statuses/friends")
1360 result = json_response(res_conn, 200)
1361 assert length(result) == 20
1365 |> assign(:user, user)
1366 |> get("/api/statuses/friends", %{page: 2})
1368 result = json_response(res_conn, 200)
1369 assert length(result) == 1
1373 |> assign(:user, user)
1374 |> get("/api/statuses/friends", %{all: true})
1376 result = json_response(res_conn, 200)
1377 assert length(result) == 21
1380 test "it returns a given user's friends with user_id", %{conn: conn} do
1381 user = insert(:user)
1382 followed_one = insert(:user)
1383 followed_two = insert(:user)
1384 _not_followed = insert(:user)
1386 {:ok, user} = User.follow(user, followed_one)
1387 {:ok, user} = User.follow(user, followed_two)
1391 |> assign(:user, user)
1392 |> get("/api/statuses/friends", %{"user_id" => user.id})
1394 assert MapSet.equal?(
1395 MapSet.new(json_response(conn, 200)),
1397 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1402 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1403 user = insert(:user, %{info: %{hide_follows: true}})
1404 followed_one = insert(:user)
1405 followed_two = insert(:user)
1406 not_followed = insert(:user)
1408 {:ok, user} = User.follow(user, followed_one)
1409 {:ok, user} = User.follow(user, followed_two)
1413 |> assign(:user, not_followed)
1414 |> get("/api/statuses/friends", %{"user_id" => user.id})
1416 assert [] == json_response(conn, 200)
1419 test "it returns friends when hide_follows is set to true if the user themselves request it",
1423 user = insert(:user, %{info: %{hide_follows: true}})
1424 followed_one = insert(:user)
1425 followed_two = insert(:user)
1426 _not_followed = insert(:user)
1428 {:ok, _user} = User.follow(user, followed_one)
1429 {:ok, _user} = User.follow(user, followed_two)
1433 |> assign(:user, user)
1434 |> get("/api/statuses/friends", %{"user_id" => user.id})
1435 |> json_response(200)
1437 refute [] == response
1440 test "it returns a given user's friends with screen_name", %{conn: conn} do
1441 user = insert(:user)
1442 followed_one = insert(:user)
1443 followed_two = insert(:user)
1444 _not_followed = insert(:user)
1446 {:ok, user} = User.follow(user, followed_one)
1447 {:ok, user} = User.follow(user, followed_two)
1451 |> assign(:user, user)
1452 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1454 assert MapSet.equal?(
1455 MapSet.new(json_response(conn, 200)),
1457 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1463 describe "GET /friends/ids" do
1464 test "it returns a user's friends", %{conn: conn} do
1465 user = insert(:user)
1466 followed_one = insert(:user)
1467 followed_two = insert(:user)
1468 _not_followed = insert(:user)
1470 {:ok, user} = User.follow(user, followed_one)
1471 {:ok, user} = User.follow(user, followed_two)
1475 |> assign(:user, user)
1476 |> get("/api/friends/ids")
1478 expected = [followed_one.id, followed_two.id]
1480 assert MapSet.equal?(
1481 MapSet.new(Poison.decode!(json_response(conn, 200))),
1482 MapSet.new(expected)
1487 describe "POST /api/account/update_profile.json" do
1488 test "it updates a user's profile", %{conn: conn} do
1489 user = insert(:user)
1490 user2 = insert(:user)
1494 |> assign(:user, user)
1495 |> post("/api/account/update_profile.json", %{
1496 "name" => "new name",
1497 "description" => "hi @#{user2.nickname}"
1500 user = Repo.get!(User, user.id)
1501 assert user.name == "new name"
1504 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1506 }'>@<span>#{user2.nickname}</span></a></span>"
1508 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1511 test "it sets and un-sets hide_follows", %{conn: conn} do
1512 user = insert(:user)
1515 |> assign(:user, user)
1516 |> post("/api/account/update_profile.json", %{
1517 "hide_follows" => "true"
1520 user = Repo.get!(User, user.id)
1521 assert user.info.hide_follows == true
1525 |> assign(:user, user)
1526 |> post("/api/account/update_profile.json", %{
1527 "hide_follows" => "false"
1530 user = Repo.get!(User, user.id)
1531 assert user.info.hide_follows == false
1532 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1535 test "it sets and un-sets hide_followers", %{conn: conn} do
1536 user = insert(:user)
1539 |> assign(:user, user)
1540 |> post("/api/account/update_profile.json", %{
1541 "hide_followers" => "true"
1544 user = Repo.get!(User, user.id)
1545 assert user.info.hide_followers == true
1549 |> assign(:user, user)
1550 |> post("/api/account/update_profile.json", %{
1551 "hide_followers" => "false"
1554 user = Repo.get!(User, user.id)
1555 assert user.info.hide_followers == false
1556 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1559 test "it sets and un-sets show_role", %{conn: conn} do
1560 user = insert(:user)
1563 |> assign(:user, user)
1564 |> post("/api/account/update_profile.json", %{
1565 "show_role" => "true"
1568 user = Repo.get!(User, user.id)
1569 assert user.info.show_role == true
1573 |> assign(:user, user)
1574 |> post("/api/account/update_profile.json", %{
1575 "show_role" => "false"
1578 user = Repo.get!(User, user.id)
1579 assert user.info.show_role == false
1580 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1583 test "it locks an account", %{conn: conn} do
1584 user = insert(:user)
1588 |> assign(:user, user)
1589 |> post("/api/account/update_profile.json", %{
1593 user = Repo.get!(User, user.id)
1594 assert user.info.locked == true
1596 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1599 test "it unlocks an account", %{conn: conn} do
1600 user = insert(:user)
1604 |> assign(:user, user)
1605 |> post("/api/account/update_profile.json", %{
1609 user = Repo.get!(User, user.id)
1610 assert user.info.locked == false
1612 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1616 defp valid_user(_context) do
1617 user = insert(:user)
1621 defp with_credentials(conn, username, password) do
1622 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1623 put_req_header(conn, "authorization", header_content)
1626 describe "GET /api/search.json" do
1627 test "it returns search results", %{conn: conn} do
1628 user = insert(:user)
1629 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1631 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1632 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1636 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1638 assert [status] = json_response(conn, 200)
1639 assert status["id"] == activity.id
1643 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1644 test "it returns the tags timeline", %{conn: conn} do
1645 user = insert(:user)
1646 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1648 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1649 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1653 |> get("/api/statusnet/tags/timeline/2hu.json")
1655 assert [status] = json_response(conn, 200)
1656 assert status["id"] == activity.id
1660 test "Convert newlines to <br> in bio", %{conn: conn} do
1661 user = insert(:user)
1665 |> assign(:user, user)
1666 |> post("/api/account/update_profile.json", %{
1667 "description" => "Hello,\r\nWorld! I\n am a test."
1670 user = Repo.get!(User, user.id)
1671 assert user.bio == "Hello,<br>World! I<br> am a test."
1674 describe "POST /api/pleroma/change_password" do
1677 test "without credentials", %{conn: conn} do
1678 conn = post(conn, "/api/pleroma/change_password")
1679 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1682 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1685 |> with_credentials(current_user.nickname, "test")
1686 |> post("/api/pleroma/change_password", %{
1688 "new_password" => "newpass",
1689 "new_password_confirmation" => "newpass"
1692 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1695 test "with credentials, valid password and new password and confirmation not matching", %{
1701 |> with_credentials(current_user.nickname, "test")
1702 |> post("/api/pleroma/change_password", %{
1703 "password" => "test",
1704 "new_password" => "newpass",
1705 "new_password_confirmation" => "notnewpass"
1708 assert json_response(conn, 200) == %{
1709 "error" => "New password does not match confirmation."
1713 test "with credentials, valid password and invalid new password", %{
1719 |> with_credentials(current_user.nickname, "test")
1720 |> post("/api/pleroma/change_password", %{
1721 "password" => "test",
1722 "new_password" => "",
1723 "new_password_confirmation" => ""
1726 assert json_response(conn, 200) == %{
1727 "error" => "New password can't be blank."
1731 test "with credentials, valid password and matching new password and confirmation", %{
1737 |> with_credentials(current_user.nickname, "test")
1738 |> post("/api/pleroma/change_password", %{
1739 "password" => "test",
1740 "new_password" => "newpass",
1741 "new_password_confirmation" => "newpass"
1744 assert json_response(conn, 200) == %{"status" => "success"}
1745 fetched_user = User.get_by_id(current_user.id)
1746 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1750 describe "POST /api/pleroma/delete_account" do
1753 test "without credentials", %{conn: conn} do
1754 conn = post(conn, "/api/pleroma/delete_account")
1755 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1758 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1761 |> with_credentials(current_user.nickname, "test")
1762 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1764 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1767 test "with credentials and valid password", %{conn: conn, user: current_user} do
1770 |> with_credentials(current_user.nickname, "test")
1771 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1773 assert json_response(conn, 200) == %{"status" => "success"}
1774 # Wait a second for the started task to end
1779 describe "GET /api/pleroma/friend_requests" do
1780 test "it lists friend requests" do
1781 user = insert(:user)
1782 other_user = insert(:user)
1784 {:ok, _activity} = ActivityPub.follow(other_user, user)
1786 user = User.get_by_id(user.id)
1787 other_user = User.get_by_id(other_user.id)
1789 assert User.following?(other_user, user) == false
1793 |> assign(:user, user)
1794 |> get("/api/pleroma/friend_requests")
1796 assert [relationship] = json_response(conn, 200)
1797 assert other_user.id == relationship["id"]
1800 test "requires 'read' permission", %{conn: conn} do
1801 token1 = insert(:oauth_token, scopes: ["write"])
1802 token2 = insert(:oauth_token, scopes: ["read"])
1804 for token <- [token1, token2] do
1807 |> put_req_header("authorization", "Bearer #{token.token}")
1808 |> get("/api/pleroma/friend_requests")
1810 if token == token1 do
1811 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1813 assert json_response(conn, 200)
1819 describe "POST /api/pleroma/friendships/approve" do
1820 test "it approves a friend request" do
1821 user = insert(:user)
1822 other_user = insert(:user)
1824 {:ok, _activity} = ActivityPub.follow(other_user, user)
1826 user = User.get_by_id(user.id)
1827 other_user = User.get_by_id(other_user.id)
1829 assert User.following?(other_user, user) == false
1833 |> assign(:user, user)
1834 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1836 assert relationship = json_response(conn, 200)
1837 assert other_user.id == relationship["id"]
1838 assert relationship["follows_you"] == true
1842 describe "POST /api/pleroma/friendships/deny" do
1843 test "it denies a friend request" do
1844 user = insert(:user)
1845 other_user = insert(:user)
1847 {:ok, _activity} = ActivityPub.follow(other_user, user)
1849 user = User.get_by_id(user.id)
1850 other_user = User.get_by_id(other_user.id)
1852 assert User.following?(other_user, user) == false
1856 |> assign(:user, user)
1857 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1859 assert relationship = json_response(conn, 200)
1860 assert other_user.id == relationship["id"]
1861 assert relationship["follows_you"] == false
1865 describe "GET /api/pleroma/search_user" do
1866 test "it returns users, ordered by similarity", %{conn: conn} do
1867 user = insert(:user, %{name: "eal"})
1868 user_two = insert(:user, %{name: "eal me"})
1869 _user_three = insert(:user, %{name: "zzz"})
1873 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1874 |> json_response(200)
1876 assert length(resp) == 2
1877 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1881 describe "POST /api/media/upload" do
1883 Pleroma.DataCase.ensure_local_uploader(context)
1886 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1889 user = insert(:user)
1891 upload_filename = "test/fixtures/image_tmp.jpg"
1892 File.cp!("test/fixtures/image.jpg", upload_filename)
1894 file = %Plug.Upload{
1895 content_type: "image/jpg",
1896 path: Path.absname(upload_filename),
1897 filename: "image.jpg"
1902 |> assign(:user, user)
1903 |> put_req_header("content-type", "application/octet-stream")
1904 |> post("/api/media/upload", %{
1907 |> json_response(:ok)
1909 assert response["media_id"]
1910 object = Repo.get(Object, response["media_id"])
1912 assert object.data["actor"] == User.ap_id(user)
1916 describe "POST /api/media/metadata/create" do
1918 object = insert(:note)
1919 user = User.get_by_ap_id(object.data["actor"])
1920 %{object: object, user: user}
1923 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1927 initial_description = object.data["name"]
1928 another_user = insert(:user)
1931 |> assign(:user, another_user)
1932 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1933 |> json_response(:forbidden)
1935 object = Repo.get(Object, object.id)
1936 assert object.data["name"] == initial_description
1939 test "it updates `data[name]` of referenced Object with provided value", %{
1944 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1947 |> assign(:user, user)
1948 |> post("/api/media/metadata/create", %{
1949 "media_id" => object.id,
1950 "alt_text" => %{"text" => description}
1952 |> json_response(:no_content)
1954 object = Repo.get(Object, object.id)
1955 assert object.data["name"] == description
1959 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1960 test "it returns a list of pinned statuses", %{conn: conn} do
1961 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1963 user = insert(:user, %{name: "egor"})
1964 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1965 {:ok, _} = CommonAPI.pin(activity_id, user)
1969 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1970 |> json_response(200)
1972 assert length(resp) == 1
1973 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1977 describe "POST /api/statuses/pin/:id" do
1979 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1980 [user: insert(:user)]
1983 test "without valid credentials", %{conn: conn} do
1984 note_activity = insert(:note_activity)
1985 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1986 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1989 test "with credentials", %{conn: conn, user: user} do
1990 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1992 request_path = "/api/statuses/pin/#{activity.id}.json"
1996 |> with_credentials(user.nickname, "test")
1997 |> post(request_path)
1999 user = refresh_record(user)
2001 assert json_response(response, 200) ==
2002 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2006 describe "POST /api/statuses/unpin/:id" do
2008 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2009 [user: insert(:user)]
2012 test "without valid credentials", %{conn: conn} do
2013 note_activity = insert(:note_activity)
2014 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
2015 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
2018 test "with credentials", %{conn: conn, user: user} do
2019 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
2020 {:ok, activity} = CommonAPI.pin(activity.id, user)
2022 request_path = "/api/statuses/unpin/#{activity.id}.json"
2026 |> with_credentials(user.nickname, "test")
2027 |> post(request_path)
2029 user = refresh_record(user)
2031 assert json_response(response, 200) ==
2032 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2036 describe "GET /api/oauth_tokens" do
2038 token = insert(:oauth_token) |> Repo.preload(:user)
2043 test "renders list", %{token: token} do
2046 |> assign(:user, token.user)
2047 |> get("/api/oauth_tokens")
2050 json_response(response, 200)
2054 assert keys -- ["id", "app_name", "valid_until"] == []
2057 test "revoke token", %{token: token} do
2060 |> assign(:user, token.user)
2061 |> delete("/api/oauth_tokens/#{token.id}")
2063 tokens = Token.get_user_tokens(token.user)
2066 assert response.status == 201