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.Controller
20 alias Pleroma.Web.TwitterAPI.NotificationView
21 alias Pleroma.Web.TwitterAPI.ActivityView
22 alias Pleroma.Web.TwitterAPI.TwitterAPI
23 alias Pleroma.Web.TwitterAPI.UserView
25 import Pleroma.Factory
28 @banner "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
30 describe "POST /api/account/update_profile_banner" do
31 test "it updates the banner", %{conn: conn} do
35 |> assign(:user, user)
36 |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => @banner})
39 user = refresh_record(user)
40 assert user.info.banner["type"] == "Image"
44 describe "POST /api/qvitter/update_background_image" do
45 test "it updates the background", %{conn: conn} do
49 |> assign(:user, user)
50 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => @banner})
53 user = refresh_record(user)
54 assert user.info.background["type"] == "Image"
58 describe "POST /api/account/verify_credentials" do
61 test "without valid credentials", %{conn: conn} do
62 conn = post(conn, "/api/account/verify_credentials.json")
63 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
66 test "with credentials", %{conn: conn, user: user} do
69 |> with_credentials(user.nickname, "test")
70 |> post("/api/account/verify_credentials.json")
74 UserView.render("show.json", %{user: user, token: response["token"], for: user})
78 describe "POST /statuses/update.json" do
81 test "without valid credentials", %{conn: conn} do
82 conn = post(conn, "/api/statuses/update.json")
83 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
86 test "with credentials", %{conn: conn, user: user} do
87 conn_with_creds = conn |> with_credentials(user.nickname, "test")
88 request_path = "/api/statuses/update.json"
91 "request" => request_path,
92 "error" => "Client must provide a 'status' parameter with a value."
99 assert json_response(conn, 400) == error_response
103 |> post(request_path, %{status: ""})
105 assert json_response(conn, 400) == error_response
109 |> post(request_path, %{status: " "})
111 assert json_response(conn, 400) == error_response
113 # we post with visibility private in order to avoid triggering relay
116 |> post(request_path, %{status: "Nice meme.", visibility: "private"})
118 assert json_response(conn, 200) ==
119 ActivityView.render("activity.json", %{
120 activity: Repo.one(Activity),
127 describe "GET /statuses/public_timeline.json" do
130 test "returns statuses", %{conn: conn} do
132 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
133 ActivityBuilder.insert_list(10, %{}, %{user: user})
134 since_id = List.last(activities).id
138 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
140 response = json_response(conn, 200)
142 assert length(response) == 10
145 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
147 Application.get_env(:pleroma, :instance)
148 |> Keyword.put(:public, false)
150 Application.put_env(:pleroma, :instance, instance)
153 |> get("/api/statuses/public_timeline.json")
154 |> json_response(403)
157 Application.get_env(:pleroma, :instance)
158 |> Keyword.put(:public, true)
160 Application.put_env(:pleroma, :instance, instance)
163 test "returns 200 to authenticated request when the instance is not public",
164 %{conn: conn, user: user} do
166 Application.get_env(:pleroma, :instance)
167 |> Keyword.put(:public, false)
169 Application.put_env(:pleroma, :instance, instance)
172 |> with_credentials(user.nickname, "test")
173 |> get("/api/statuses/public_timeline.json")
174 |> json_response(200)
177 Application.get_env(:pleroma, :instance)
178 |> Keyword.put(:public, true)
180 Application.put_env(:pleroma, :instance, instance)
183 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
185 |> get("/api/statuses/public_timeline.json")
186 |> json_response(200)
189 test "returns 200 to authenticated request when the instance is public",
190 %{conn: conn, user: user} do
192 |> with_credentials(user.nickname, "test")
193 |> get("/api/statuses/public_timeline.json")
194 |> json_response(200)
197 test_with_mock "treats user as unauthenticated if `assigns[:token]` is present but lacks `read` permission",
201 token = insert(:oauth_token, scopes: ["write"])
204 |> put_req_header("authorization", "Bearer #{token.token}")
205 |> get("/api/statuses/public_timeline.json")
206 |> json_response(200)
208 assert called(Controller.public_timeline(%{assigns: %{user: nil}}, :_))
212 describe "GET /statuses/public_and_external_timeline.json" do
215 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
217 Application.get_env(:pleroma, :instance)
218 |> Keyword.put(:public, false)
220 Application.put_env(:pleroma, :instance, instance)
223 |> get("/api/statuses/public_and_external_timeline.json")
224 |> json_response(403)
227 Application.get_env(:pleroma, :instance)
228 |> Keyword.put(:public, true)
230 Application.put_env(:pleroma, :instance, instance)
233 test "returns 200 to authenticated request when the instance is not public",
234 %{conn: conn, user: user} do
236 Application.get_env(:pleroma, :instance)
237 |> Keyword.put(:public, false)
239 Application.put_env(:pleroma, :instance, instance)
242 |> with_credentials(user.nickname, "test")
243 |> get("/api/statuses/public_and_external_timeline.json")
244 |> json_response(200)
247 Application.get_env(:pleroma, :instance)
248 |> Keyword.put(:public, true)
250 Application.put_env(:pleroma, :instance, instance)
253 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
255 |> get("/api/statuses/public_and_external_timeline.json")
256 |> json_response(200)
259 test "returns 200 to authenticated request when the instance is public",
260 %{conn: conn, user: user} do
262 |> with_credentials(user.nickname, "test")
263 |> get("/api/statuses/public_and_external_timeline.json")
264 |> json_response(200)
268 describe "GET /statuses/show/:id.json" do
269 test "returns one status", %{conn: conn} do
271 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
272 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
276 |> get("/api/statuses/show/#{activity.id}.json")
278 response = json_response(conn, 200)
280 assert response == ActivityView.render("activity.json", %{activity: activity, user: actor})
284 describe "GET /users/show.json" do
285 test "gets user with screen_name", %{conn: conn} do
290 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
292 response = json_response(conn, 200)
294 assert response["id"] == user.id
297 test "gets user with user_id", %{conn: conn} do
302 |> get("/api/users/show.json", %{"user_id" => user.id})
304 response = json_response(conn, 200)
306 assert response["id"] == user.id
309 test "gets a user for a logged in user", %{conn: conn} do
311 logged_in = insert(:user)
313 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
317 |> with_credentials(logged_in.nickname, "test")
318 |> get("/api/users/show.json", %{"user_id" => user.id})
320 response = json_response(conn, 200)
322 assert response["following"] == true
326 describe "GET /statusnet/conversation/:id.json" do
327 test "returns the statuses in the conversation", %{conn: conn} do
328 {:ok, _user} = UserBuilder.insert()
329 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
330 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
331 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
335 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
337 response = json_response(conn, 200)
339 assert length(response) == 2
343 describe "GET /statuses/friends_timeline.json" do
346 test "without valid credentials", %{conn: conn} do
347 conn = get(conn, "/api/statuses/friends_timeline.json")
348 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
351 test "with credentials", %{conn: conn, user: current_user} do
355 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
357 returned_activities =
358 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
360 other_user = insert(:user)
361 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
362 since_id = List.last(activities).id
365 Changeset.change(current_user, following: [User.ap_followers(user)])
370 |> with_credentials(current_user.nickname, "test")
371 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
373 response = json_response(conn, 200)
375 assert length(response) == 10
378 Enum.map(returned_activities, fn activity ->
379 ActivityView.render("activity.json", %{
381 user: User.get_cached_by_ap_id(activity.data["actor"]),
388 describe "GET /statuses/dm_timeline.json" do
389 test "it show direct messages", %{conn: conn} do
390 user_one = insert(:user)
391 user_two = insert(:user)
393 {:ok, user_two} = User.follow(user_two, user_one)
396 CommonAPI.post(user_one, %{
397 "status" => "Hi @#{user_two.nickname}!",
398 "visibility" => "direct"
402 CommonAPI.post(user_two, %{
403 "status" => "Hi @#{user_one.nickname}!",
404 "visibility" => "direct"
407 {:ok, _follower_only} =
408 CommonAPI.post(user_one, %{
409 "status" => "Hi @#{user_two.nickname}!",
410 "visibility" => "private"
413 # Only direct should be visible here
416 |> assign(:user, user_two)
417 |> get("/api/statuses/dm_timeline.json")
419 [status, status_two] = json_response(res_conn, 200)
420 assert status["id"] == direct_two.id
421 assert status_two["id"] == direct.id
424 test "doesn't include DMs from blocked users", %{conn: conn} do
425 blocker = insert(:user)
426 blocked = insert(:user)
428 {:ok, blocker} = User.block(blocker, blocked)
430 {:ok, _blocked_direct} =
431 CommonAPI.post(blocked, %{
432 "status" => "Hi @#{blocker.nickname}!",
433 "visibility" => "direct"
437 CommonAPI.post(user, %{
438 "status" => "Hi @#{blocker.nickname}!",
439 "visibility" => "direct"
444 |> assign(:user, blocker)
445 |> get("/api/statuses/dm_timeline.json")
447 [status] = json_response(res_conn, 200)
448 assert status["id"] == direct.id
452 describe "GET /statuses/mentions.json" do
455 test "without valid credentials", %{conn: conn} do
456 conn = get(conn, "/api/statuses/mentions.json")
457 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
460 test "with credentials", %{conn: conn, user: current_user} do
462 CommonAPI.post(current_user, %{
463 "status" => "why is tenshi eating a corndog so cute?",
464 "visibility" => "public"
469 |> with_credentials(current_user.nickname, "test")
470 |> get("/api/statuses/mentions.json")
472 response = json_response(conn, 200)
474 assert length(response) == 1
476 assert Enum.at(response, 0) ==
477 ActivityView.render("activity.json", %{
484 test "does not show DMs in mentions timeline", %{conn: conn, user: current_user} do
486 CommonAPI.post(current_user, %{
487 "status" => "Have you guys ever seen how cute tenshi eating a corndog is?",
488 "visibility" => "direct"
493 |> with_credentials(current_user.nickname, "test")
494 |> get("/api/statuses/mentions.json")
496 response = json_response(conn, 200)
498 assert Enum.empty?(response)
502 describe "GET /api/qvitter/statuses/notifications.json" do
505 test "without valid credentials", %{conn: conn} do
506 conn = get(conn, "/api/qvitter/statuses/notifications.json")
507 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
510 test "with credentials", %{conn: conn, user: current_user} do
511 other_user = insert(:user)
514 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
518 |> with_credentials(current_user.nickname, "test")
519 |> get("/api/qvitter/statuses/notifications.json")
521 response = json_response(conn, 200)
523 assert length(response) == 1
526 NotificationView.render("notification.json", %{
527 notifications: Notification.for_user(current_user),
533 describe "POST /api/qvitter/statuses/notifications/read" do
536 test "without valid credentials", %{conn: conn} do
537 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
538 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
541 test "with credentials, without any params", %{conn: conn, user: current_user} do
544 |> with_credentials(current_user.nickname, "test")
545 |> post("/api/qvitter/statuses/notifications/read")
547 assert json_response(conn, 400) == %{
548 "error" => "You need to specify latest_id",
549 "request" => "/api/qvitter/statuses/notifications/read"
553 test "with credentials, with params", %{conn: conn, user: current_user} do
554 other_user = insert(:user)
557 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
561 |> with_credentials(current_user.nickname, "test")
562 |> get("/api/qvitter/statuses/notifications.json")
564 [notification] = response = json_response(response_conn, 200)
566 assert length(response) == 1
568 assert notification["is_seen"] == 0
572 |> with_credentials(current_user.nickname, "test")
573 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
575 [notification] = response = json_response(response_conn, 200)
577 assert length(response) == 1
579 assert notification["is_seen"] == 1
583 describe "GET /statuses/user_timeline.json" do
586 test "without any params", %{conn: conn} do
587 conn = get(conn, "/api/statuses/user_timeline.json")
589 assert json_response(conn, 400) == %{
590 "error" => "You need to specify screen_name or user_id",
591 "request" => "/api/statuses/user_timeline.json"
595 test "with user_id", %{conn: conn} do
597 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
599 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
600 response = json_response(conn, 200)
601 assert length(response) == 1
603 assert Enum.at(response, 0) ==
604 ActivityView.render("activity.json", %{user: user, activity: activity})
607 test "with screen_name", %{conn: conn} do
609 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
611 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
612 response = json_response(conn, 200)
613 assert length(response) == 1
615 assert Enum.at(response, 0) ==
616 ActivityView.render("activity.json", %{user: user, activity: activity})
619 test "with credentials", %{conn: conn, user: current_user} do
620 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
624 |> with_credentials(current_user.nickname, "test")
625 |> get("/api/statuses/user_timeline.json")
627 response = json_response(conn, 200)
629 assert length(response) == 1
631 assert Enum.at(response, 0) ==
632 ActivityView.render("activity.json", %{
639 test "with credentials with user_id", %{conn: conn, user: current_user} do
641 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
645 |> with_credentials(current_user.nickname, "test")
646 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
648 response = json_response(conn, 200)
650 assert length(response) == 1
652 assert Enum.at(response, 0) ==
653 ActivityView.render("activity.json", %{user: user, activity: activity})
656 test "with credentials screen_name", %{conn: conn, user: current_user} do
658 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
662 |> with_credentials(current_user.nickname, "test")
663 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
665 response = json_response(conn, 200)
667 assert length(response) == 1
669 assert Enum.at(response, 0) ==
670 ActivityView.render("activity.json", %{user: user, activity: activity})
673 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
675 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
676 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
680 |> with_credentials(current_user.nickname, "test")
681 |> get("/api/statuses/user_timeline.json", %{
682 "user_id" => user.id,
683 "include_rts" => "false"
686 response = json_response(conn, 200)
688 assert length(response) == 1
690 assert Enum.at(response, 0) ==
691 ActivityView.render("activity.json", %{user: user, activity: activity})
695 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
697 response = json_response(conn, 200)
699 assert length(response) == 1
701 assert Enum.at(response, 0) ==
702 ActivityView.render("activity.json", %{user: user, activity: activity})
706 describe "POST /friendships/create.json" do
709 test "without valid credentials", %{conn: conn} do
710 conn = post(conn, "/api/friendships/create.json")
711 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
714 test "with credentials", %{conn: conn, user: current_user} do
715 followed = insert(:user)
719 |> with_credentials(current_user.nickname, "test")
720 |> post("/api/friendships/create.json", %{user_id: followed.id})
722 current_user = Repo.get(User, current_user.id)
723 assert User.ap_followers(followed) in current_user.following
725 assert json_response(conn, 200) ==
726 UserView.render("show.json", %{user: followed, for: current_user})
729 test "for restricted account", %{conn: conn, user: current_user} do
730 followed = insert(:user, info: %User.Info{locked: true})
734 |> with_credentials(current_user.nickname, "test")
735 |> post("/api/friendships/create.json", %{user_id: followed.id})
737 current_user = Repo.get(User, current_user.id)
738 followed = Repo.get(User, followed.id)
740 refute User.ap_followers(followed) in current_user.following
742 assert json_response(conn, 200) ==
743 UserView.render("show.json", %{user: followed, for: current_user})
747 describe "POST /friendships/destroy.json" do
750 test "without valid credentials", %{conn: conn} do
751 conn = post(conn, "/api/friendships/destroy.json")
752 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
755 test "with credentials", %{conn: conn, user: current_user} do
756 followed = insert(:user)
758 {:ok, current_user} = User.follow(current_user, followed)
759 assert User.ap_followers(followed) in current_user.following
760 ActivityPub.follow(current_user, followed)
764 |> with_credentials(current_user.nickname, "test")
765 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
767 current_user = Repo.get(User, current_user.id)
768 assert current_user.following == [current_user.ap_id]
770 assert json_response(conn, 200) ==
771 UserView.render("show.json", %{user: followed, for: current_user})
775 describe "POST /blocks/create.json" do
778 test "without valid credentials", %{conn: conn} do
779 conn = post(conn, "/api/blocks/create.json")
780 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
783 test "with credentials", %{conn: conn, user: current_user} do
784 blocked = insert(:user)
788 |> with_credentials(current_user.nickname, "test")
789 |> post("/api/blocks/create.json", %{user_id: blocked.id})
791 current_user = Repo.get(User, current_user.id)
792 assert User.blocks?(current_user, blocked)
794 assert json_response(conn, 200) ==
795 UserView.render("show.json", %{user: blocked, for: current_user})
799 describe "POST /blocks/destroy.json" do
802 test "without valid credentials", %{conn: conn} do
803 conn = post(conn, "/api/blocks/destroy.json")
804 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
807 test "with credentials", %{conn: conn, user: current_user} do
808 blocked = insert(:user)
810 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
811 assert User.blocks?(current_user, blocked)
815 |> with_credentials(current_user.nickname, "test")
816 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
818 current_user = Repo.get(User, current_user.id)
819 assert current_user.info.blocks == []
821 assert json_response(conn, 200) ==
822 UserView.render("show.json", %{user: blocked, for: current_user})
826 describe "GET /help/test.json" do
827 test "returns \"ok\"", %{conn: conn} do
828 conn = get(conn, "/api/help/test.json")
829 assert json_response(conn, 200) == "ok"
833 describe "POST /api/qvitter/update_avatar.json" do
836 test "without valid credentials", %{conn: conn} do
837 conn = post(conn, "/api/qvitter/update_avatar.json")
838 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
841 test "with credentials", %{conn: conn, user: current_user} do
842 avatar_image = File.read!("test/fixtures/avatar_data_uri")
846 |> with_credentials(current_user.nickname, "test")
847 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
849 current_user = Repo.get(User, current_user.id)
850 assert is_map(current_user.avatar)
852 assert json_response(conn, 200) ==
853 UserView.render("show.json", %{user: current_user, for: current_user})
857 describe "GET /api/qvitter/mutes.json" do
860 test "unimplemented mutes without valid credentials", %{conn: conn} do
861 conn = get(conn, "/api/qvitter/mutes.json")
862 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
865 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
868 |> with_credentials(current_user.nickname, "test")
869 |> get("/api/qvitter/mutes.json")
870 |> json_response(200)
876 describe "POST /api/favorites/create/:id" do
879 test "without valid credentials", %{conn: conn} do
880 note_activity = insert(:note_activity)
881 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
882 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
885 test "with credentials", %{conn: conn, user: current_user} do
886 note_activity = insert(:note_activity)
890 |> with_credentials(current_user.nickname, "test")
891 |> post("/api/favorites/create/#{note_activity.id}.json")
893 assert json_response(conn, 200)
896 test "with credentials, invalid param", %{conn: conn, user: current_user} do
899 |> with_credentials(current_user.nickname, "test")
900 |> post("/api/favorites/create/wrong.json")
902 assert json_response(conn, 400)
905 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
908 |> with_credentials(current_user.nickname, "test")
909 |> post("/api/favorites/create/1.json")
911 assert json_response(conn, 400)
915 describe "POST /api/favorites/destroy/:id" do
918 test "without valid credentials", %{conn: conn} do
919 note_activity = insert(:note_activity)
920 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
921 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
924 test "with credentials", %{conn: conn, user: current_user} do
925 note_activity = insert(:note_activity)
926 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
927 ActivityPub.like(current_user, object)
931 |> with_credentials(current_user.nickname, "test")
932 |> post("/api/favorites/destroy/#{note_activity.id}.json")
934 assert json_response(conn, 200)
938 describe "POST /api/statuses/retweet/:id" do
941 test "without valid credentials", %{conn: conn} do
942 note_activity = insert(:note_activity)
943 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
944 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
947 test "with credentials", %{conn: conn, user: current_user} do
948 note_activity = insert(:note_activity)
950 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
954 |> with_credentials(current_user.nickname, "test")
955 |> post(request_path)
957 activity = Repo.get(Activity, note_activity.id)
958 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
960 assert json_response(response, 200) ==
961 ActivityView.render("activity.json", %{user: activity_user, for: current_user, activity: activity})
965 describe "POST /api/statuses/unretweet/:id" do
968 test "without valid credentials", %{conn: conn} do
969 note_activity = insert(:note_activity)
970 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
971 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
974 test "with credentials", %{conn: conn, user: current_user} do
975 note_activity = insert(:note_activity)
977 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
981 |> with_credentials(current_user.nickname, "test")
982 |> post(request_path)
984 request_path = String.replace(request_path, "retweet", "unretweet")
988 |> with_credentials(current_user.nickname, "test")
989 |> post(request_path)
991 activity = Repo.get(Activity, note_activity.id)
992 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
994 assert json_response(response, 200) ==
995 ActivityView.render("activity.json", %{user: activity_user, for: current_user, activity: activity})
999 describe "POST /api/account/register" do
1000 test "it creates a new user", %{conn: conn} do
1002 "nickname" => "lain",
1003 "email" => "lain@wired.jp",
1004 "fullname" => "lain iwakura",
1005 "bio" => "close the world.",
1006 "password" => "bear",
1012 |> post("/api/account/register", data)
1014 user = json_response(conn, 200)
1016 fetched_user = Repo.get_by(User, nickname: "lain")
1017 assert user == UserView.render("show.json", %{user: fetched_user})
1020 test "it returns errors on a problem", %{conn: conn} do
1022 "email" => "lain@wired.jp",
1023 "fullname" => "lain iwakura",
1024 "bio" => "close the world.",
1025 "password" => "bear",
1031 |> post("/api/account/register", data)
1033 errors = json_response(conn, 400)
1035 assert is_binary(errors["error"])
1039 describe "POST /api/account/password_reset, with valid parameters" do
1040 setup %{conn: conn} do
1041 user = insert(:user)
1042 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1043 %{conn: conn, user: user}
1046 test "it returns 204", %{conn: conn} do
1047 assert json_response(conn, :no_content)
1050 test "it creates a PasswordResetToken record for user", %{user: user} do
1051 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1055 test "it sends an email to user", %{user: user} do
1056 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1058 Swoosh.TestAssertions.assert_email_sent(
1059 Pleroma.UserEmail.password_reset_email(user, token_record.token)
1064 describe "POST /api/account/password_reset, with invalid parameters" do
1067 test "it returns 500 when user is not found", %{conn: conn, user: user} do
1068 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1069 assert json_response(conn, :internal_server_error)
1072 test "it returns 500 when user is not local", %{conn: conn, user: user} do
1073 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1074 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1075 assert json_response(conn, :internal_server_error)
1079 describe "GET /api/account/confirm_email/:id/:token" do
1081 user = insert(:user)
1082 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1086 |> Changeset.change()
1087 |> Changeset.put_embed(:info, info_change)
1090 assert user.info.confirmation_pending
1095 test "it redirects to root url", %{conn: conn, user: user} do
1096 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1098 assert 302 == conn.status
1101 test "it confirms the user account", %{conn: conn, user: user} do
1102 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1104 user = Repo.get(User, user.id)
1106 refute user.info.confirmation_pending
1107 refute user.info.confirmation_token
1110 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1111 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1113 assert 500 == conn.status
1116 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1117 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1119 assert 500 == conn.status
1123 describe "POST /api/account/resend_confirmation_email" do
1125 setting = Pleroma.Config.get([:instance, :account_activation_required])
1128 Pleroma.Config.put([:instance, :account_activation_required], true)
1129 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1132 user = insert(:user)
1133 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1137 |> Changeset.change()
1138 |> Changeset.put_embed(:info, info_change)
1141 assert user.info.confirmation_pending
1146 test "it returns 204 No Content", %{conn: conn, user: user} do
1148 |> assign(:user, user)
1149 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1150 |> json_response(:no_content)
1153 test "it sends confirmation email", %{conn: conn, user: user} do
1155 |> assign(:user, user)
1156 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1158 Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
1162 describe "GET /api/externalprofile/show" do
1163 test "it returns the user", %{conn: conn} do
1164 user = insert(:user)
1165 other_user = insert(:user)
1169 |> assign(:user, user)
1170 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1172 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1176 describe "GET /api/statuses/followers" do
1177 test "it returns a user's followers", %{conn: conn} do
1178 user = insert(:user)
1179 follower_one = insert(:user)
1180 follower_two = insert(:user)
1181 _not_follower = insert(:user)
1183 {:ok, follower_one} = User.follow(follower_one, user)
1184 {:ok, follower_two} = User.follow(follower_two, user)
1188 |> assign(:user, user)
1189 |> get("/api/statuses/followers")
1191 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1192 result = json_response(conn, 200)
1193 assert Enum.sort(expected) == Enum.sort(result)
1196 test "it returns 20 followers per page", %{conn: conn} do
1197 user = insert(:user)
1198 followers = insert_list(21, :user)
1200 Enum.each(followers, fn follower ->
1201 User.follow(follower, user)
1206 |> assign(:user, user)
1207 |> get("/api/statuses/followers")
1209 result = json_response(res_conn, 200)
1210 assert length(result) == 20
1214 |> assign(:user, user)
1215 |> get("/api/statuses/followers?page=2")
1217 result = json_response(res_conn, 200)
1218 assert length(result) == 1
1221 test "it returns a given user's followers with user_id", %{conn: conn} do
1222 user = insert(:user)
1223 follower_one = insert(:user)
1224 follower_two = insert(:user)
1225 not_follower = insert(:user)
1227 {:ok, follower_one} = User.follow(follower_one, user)
1228 {:ok, follower_two} = User.follow(follower_two, user)
1232 |> assign(:user, not_follower)
1233 |> get("/api/statuses/followers", %{"user_id" => user.id})
1235 assert MapSet.equal?(
1236 MapSet.new(json_response(conn, 200)),
1238 UserView.render("index.json", %{
1239 users: [follower_one, follower_two],
1246 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1247 user = insert(:user, %{info: %{hide_followers: true}})
1248 follower_one = insert(:user)
1249 follower_two = insert(:user)
1250 not_follower = insert(:user)
1252 {:ok, _follower_one} = User.follow(follower_one, user)
1253 {:ok, _follower_two} = User.follow(follower_two, user)
1257 |> assign(:user, not_follower)
1258 |> get("/api/statuses/followers", %{"user_id" => user.id})
1259 |> json_response(200)
1261 assert [] == response
1264 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1268 user = insert(:user, %{info: %{hide_followers: true}})
1269 follower_one = insert(:user)
1270 follower_two = insert(:user)
1271 _not_follower = insert(:user)
1273 {:ok, _follower_one} = User.follow(follower_one, user)
1274 {:ok, _follower_two} = User.follow(follower_two, user)
1278 |> assign(:user, user)
1279 |> get("/api/statuses/followers", %{"user_id" => user.id})
1281 refute [] == json_response(conn, 200)
1285 describe "GET /api/statuses/blocks" do
1286 test "it returns the list of users blocked by requester", %{conn: conn} do
1287 user = insert(:user)
1288 other_user = insert(:user)
1290 {:ok, user} = User.block(user, other_user)
1294 |> assign(:user, user)
1295 |> get("/api/statuses/blocks")
1297 expected = UserView.render("index.json", %{users: [other_user], for: user})
1298 result = json_response(conn, 200)
1299 assert Enum.sort(expected) == Enum.sort(result)
1303 describe "GET /api/statuses/friends" do
1304 test "it returns the logged in user's friends", %{conn: conn} do
1305 user = insert(:user)
1306 followed_one = insert(:user)
1307 followed_two = insert(:user)
1308 _not_followed = insert(:user)
1310 {:ok, user} = User.follow(user, followed_one)
1311 {:ok, user} = User.follow(user, followed_two)
1315 |> assign(:user, user)
1316 |> get("/api/statuses/friends")
1318 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1319 result = json_response(conn, 200)
1320 assert Enum.sort(expected) == Enum.sort(result)
1323 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1324 user = insert(:user)
1325 followeds = insert_list(21, :user)
1328 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1329 User.follow(user, followed)
1334 |> assign(:user, user)
1335 |> get("/api/statuses/friends")
1337 result = json_response(res_conn, 200)
1338 assert length(result) == 20
1342 |> assign(:user, user)
1343 |> get("/api/statuses/friends", %{page: 2})
1345 result = json_response(res_conn, 200)
1346 assert length(result) == 1
1350 |> assign(:user, user)
1351 |> get("/api/statuses/friends", %{all: true})
1353 result = json_response(res_conn, 200)
1354 assert length(result) == 21
1357 test "it returns a given user's friends with user_id", %{conn: conn} do
1358 user = insert(:user)
1359 followed_one = insert(:user)
1360 followed_two = insert(:user)
1361 _not_followed = insert(:user)
1363 {:ok, user} = User.follow(user, followed_one)
1364 {:ok, user} = User.follow(user, followed_two)
1368 |> assign(:user, user)
1369 |> get("/api/statuses/friends", %{"user_id" => user.id})
1371 assert MapSet.equal?(
1372 MapSet.new(json_response(conn, 200)),
1374 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1379 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1380 user = insert(:user, %{info: %{hide_follows: true}})
1381 followed_one = insert(:user)
1382 followed_two = insert(:user)
1383 not_followed = insert(:user)
1385 {:ok, user} = User.follow(user, followed_one)
1386 {:ok, user} = User.follow(user, followed_two)
1390 |> assign(:user, not_followed)
1391 |> get("/api/statuses/friends", %{"user_id" => user.id})
1393 assert [] == json_response(conn, 200)
1396 test "it returns friends when hide_follows is set to true if the user themselves request it",
1400 user = insert(:user, %{info: %{hide_follows: true}})
1401 followed_one = insert(:user)
1402 followed_two = insert(:user)
1403 _not_followed = insert(:user)
1405 {:ok, _user} = User.follow(user, followed_one)
1406 {:ok, _user} = User.follow(user, followed_two)
1410 |> assign(:user, user)
1411 |> get("/api/statuses/friends", %{"user_id" => user.id})
1412 |> json_response(200)
1414 refute [] == response
1417 test "it returns a given user's friends with screen_name", %{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", %{"screen_name" => user.nickname})
1431 assert MapSet.equal?(
1432 MapSet.new(json_response(conn, 200)),
1434 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1440 describe "GET /friends/ids" do
1441 test "it returns a user's friends", %{conn: conn} do
1442 user = insert(:user)
1443 followed_one = insert(:user)
1444 followed_two = insert(:user)
1445 _not_followed = insert(:user)
1447 {:ok, user} = User.follow(user, followed_one)
1448 {:ok, user} = User.follow(user, followed_two)
1452 |> assign(:user, user)
1453 |> get("/api/friends/ids")
1455 expected = [followed_one.id, followed_two.id]
1457 assert MapSet.equal?(
1458 MapSet.new(Poison.decode!(json_response(conn, 200))),
1459 MapSet.new(expected)
1464 describe "POST /api/account/update_profile.json" do
1465 test "it updates a user's profile", %{conn: conn} do
1466 user = insert(:user)
1467 user2 = insert(:user)
1471 |> assign(:user, user)
1472 |> post("/api/account/update_profile.json", %{
1473 "name" => "new name",
1474 "description" => "hi @#{user2.nickname}"
1477 user = Repo.get!(User, user.id)
1478 assert user.name == "new name"
1481 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1483 }'>@<span>#{user2.nickname}</span></a></span>"
1485 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1488 test "it sets and un-sets hide_follows", %{conn: conn} do
1489 user = insert(:user)
1492 |> assign(:user, user)
1493 |> post("/api/account/update_profile.json", %{
1494 "hide_follows" => "true"
1497 user = Repo.get!(User, user.id)
1498 assert user.info.hide_follows == true
1502 |> assign(:user, user)
1503 |> post("/api/account/update_profile.json", %{
1504 "hide_follows" => "false"
1507 user = Repo.get!(User, user.id)
1508 assert user.info.hide_follows == false
1509 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1512 test "it sets and un-sets hide_followers", %{conn: conn} do
1513 user = insert(:user)
1516 |> assign(:user, user)
1517 |> post("/api/account/update_profile.json", %{
1518 "hide_followers" => "true"
1521 user = Repo.get!(User, user.id)
1522 assert user.info.hide_followers == true
1526 |> assign(:user, user)
1527 |> post("/api/account/update_profile.json", %{
1528 "hide_followers" => "false"
1531 user = Repo.get!(User, user.id)
1532 assert user.info.hide_followers == false
1533 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1536 test "it sets and un-sets show_role", %{conn: conn} do
1537 user = insert(:user)
1540 |> assign(:user, user)
1541 |> post("/api/account/update_profile.json", %{
1542 "show_role" => "true"
1545 user = Repo.get!(User, user.id)
1546 assert user.info.show_role == true
1550 |> assign(:user, user)
1551 |> post("/api/account/update_profile.json", %{
1552 "show_role" => "false"
1555 user = Repo.get!(User, user.id)
1556 assert user.info.show_role == false
1557 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1560 test "it locks an account", %{conn: conn} do
1561 user = insert(:user)
1565 |> assign(:user, user)
1566 |> post("/api/account/update_profile.json", %{
1570 user = Repo.get!(User, user.id)
1571 assert user.info.locked == true
1573 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1576 test "it unlocks an account", %{conn: conn} do
1577 user = insert(:user)
1581 |> assign(:user, user)
1582 |> post("/api/account/update_profile.json", %{
1586 user = Repo.get!(User, user.id)
1587 assert user.info.locked == false
1589 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1593 defp valid_user(_context) do
1594 user = insert(:user)
1598 defp with_credentials(conn, username, password) do
1599 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1600 put_req_header(conn, "authorization", header_content)
1603 describe "GET /api/search.json" do
1604 test "it returns search results", %{conn: conn} do
1605 user = insert(:user)
1606 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1608 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1609 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1613 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1615 assert [status] = json_response(conn, 200)
1616 assert status["id"] == activity.id
1620 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1621 test "it returns the tags timeline", %{conn: conn} do
1622 user = insert(:user)
1623 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1625 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1626 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1630 |> get("/api/statusnet/tags/timeline/2hu.json")
1632 assert [status] = json_response(conn, 200)
1633 assert status["id"] == activity.id
1637 test "Convert newlines to <br> in bio", %{conn: conn} do
1638 user = insert(:user)
1642 |> assign(:user, user)
1643 |> post("/api/account/update_profile.json", %{
1644 "description" => "Hello,\r\nWorld! I\n am a test."
1647 user = Repo.get!(User, user.id)
1648 assert user.bio == "Hello,<br>World! I<br> am a test."
1651 describe "POST /api/pleroma/change_password" do
1654 test "without credentials", %{conn: conn} do
1655 conn = post(conn, "/api/pleroma/change_password")
1656 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1659 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1662 |> with_credentials(current_user.nickname, "test")
1663 |> post("/api/pleroma/change_password", %{
1665 "new_password" => "newpass",
1666 "new_password_confirmation" => "newpass"
1669 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1672 test "with credentials, valid password and new password and confirmation not matching", %{
1678 |> with_credentials(current_user.nickname, "test")
1679 |> post("/api/pleroma/change_password", %{
1680 "password" => "test",
1681 "new_password" => "newpass",
1682 "new_password_confirmation" => "notnewpass"
1685 assert json_response(conn, 200) == %{
1686 "error" => "New password does not match confirmation."
1690 test "with credentials, valid password and invalid new password", %{
1696 |> with_credentials(current_user.nickname, "test")
1697 |> post("/api/pleroma/change_password", %{
1698 "password" => "test",
1699 "new_password" => "",
1700 "new_password_confirmation" => ""
1703 assert json_response(conn, 200) == %{
1704 "error" => "New password can't be blank."
1708 test "with credentials, valid password and matching new password and confirmation", %{
1714 |> with_credentials(current_user.nickname, "test")
1715 |> post("/api/pleroma/change_password", %{
1716 "password" => "test",
1717 "new_password" => "newpass",
1718 "new_password_confirmation" => "newpass"
1721 assert json_response(conn, 200) == %{"status" => "success"}
1722 fetched_user = Repo.get(User, current_user.id)
1723 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1727 describe "POST /api/pleroma/delete_account" do
1730 test "without credentials", %{conn: conn} do
1731 conn = post(conn, "/api/pleroma/delete_account")
1732 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1735 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1738 |> with_credentials(current_user.nickname, "test")
1739 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1741 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1744 test "with credentials and valid password", %{conn: conn, user: current_user} do
1747 |> with_credentials(current_user.nickname, "test")
1748 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1750 assert json_response(conn, 200) == %{"status" => "success"}
1751 # Wait a second for the started task to end
1756 describe "GET /api/pleroma/friend_requests" do
1757 test "it lists friend requests" do
1758 user = insert(:user)
1759 other_user = insert(:user)
1761 {:ok, _activity} = ActivityPub.follow(other_user, user)
1763 user = Repo.get(User, user.id)
1764 other_user = Repo.get(User, other_user.id)
1766 assert User.following?(other_user, user) == false
1770 |> assign(:user, user)
1771 |> get("/api/pleroma/friend_requests")
1773 assert [relationship] = json_response(conn, 200)
1774 assert other_user.id == relationship["id"]
1777 test "requires 'read' permission", %{conn: conn} do
1778 token1 = insert(:oauth_token, scopes: ["write"])
1779 token2 = insert(:oauth_token, scopes: ["read"])
1781 for token <- [token1, token2] do
1784 |> put_req_header("authorization", "Bearer #{token.token}")
1785 |> get("/api/pleroma/friend_requests")
1787 if token == token1 do
1788 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1790 assert json_response(conn, 200)
1796 describe "POST /api/pleroma/friendships/approve" do
1797 test "it approves a friend request" do
1798 user = insert(:user)
1799 other_user = insert(:user)
1801 {:ok, _activity} = ActivityPub.follow(other_user, user)
1803 user = Repo.get(User, user.id)
1804 other_user = Repo.get(User, other_user.id)
1806 assert User.following?(other_user, user) == false
1810 |> assign(:user, user)
1811 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1813 assert relationship = json_response(conn, 200)
1814 assert other_user.id == relationship["id"]
1815 assert relationship["follows_you"] == true
1819 describe "POST /api/pleroma/friendships/deny" do
1820 test "it denies a friend request" do
1821 user = insert(:user)
1822 other_user = insert(:user)
1824 {:ok, _activity} = ActivityPub.follow(other_user, user)
1826 user = Repo.get(User, user.id)
1827 other_user = Repo.get(User, other_user.id)
1829 assert User.following?(other_user, user) == false
1833 |> assign(:user, user)
1834 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1836 assert relationship = json_response(conn, 200)
1837 assert other_user.id == relationship["id"]
1838 assert relationship["follows_you"] == false
1842 describe "GET /api/pleroma/search_user" do
1843 test "it returns users, ordered by similarity", %{conn: conn} do
1844 user = insert(:user, %{name: "eal"})
1845 user_two = insert(:user, %{name: "eal me"})
1846 _user_three = insert(:user, %{name: "zzz"})
1850 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1851 |> json_response(200)
1853 assert length(resp) == 2
1854 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1858 describe "POST /api/media/upload" do
1860 Pleroma.DataCase.ensure_local_uploader(context)
1863 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1866 user = insert(:user)
1868 upload_filename = "test/fixtures/image_tmp.jpg"
1869 File.cp!("test/fixtures/image.jpg", upload_filename)
1871 file = %Plug.Upload{
1872 content_type: "image/jpg",
1873 path: Path.absname(upload_filename),
1874 filename: "image.jpg"
1879 |> assign(:user, user)
1880 |> put_req_header("content-type", "application/octet-stream")
1881 |> post("/api/media/upload", %{
1884 |> json_response(:ok)
1886 assert response["media_id"]
1887 object = Repo.get(Object, response["media_id"])
1889 assert object.data["actor"] == User.ap_id(user)
1893 describe "POST /api/media/metadata/create" do
1895 object = insert(:note)
1896 user = User.get_by_ap_id(object.data["actor"])
1897 %{object: object, user: user}
1900 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1904 initial_description = object.data["name"]
1905 another_user = insert(:user)
1908 |> assign(:user, another_user)
1909 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1910 |> json_response(:forbidden)
1912 object = Repo.get(Object, object.id)
1913 assert object.data["name"] == initial_description
1916 test "it updates `data[name]` of referenced Object with provided value", %{
1921 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1924 |> assign(:user, user)
1925 |> post("/api/media/metadata/create", %{
1926 "media_id" => object.id,
1927 "alt_text" => %{"text" => description}
1929 |> json_response(:no_content)
1931 object = Repo.get(Object, object.id)
1932 assert object.data["name"] == description
1936 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1937 test "it returns a list of pinned statuses", %{conn: conn} do
1938 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1940 user = insert(:user, %{name: "egor"})
1941 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1942 {:ok, _} = CommonAPI.pin(activity_id, user)
1946 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1947 |> json_response(200)
1949 assert length(resp) == 1
1950 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1954 describe "POST /api/statuses/pin/:id" do
1956 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1957 [user: insert(:user)]
1960 test "without valid credentials", %{conn: conn} do
1961 note_activity = insert(:note_activity)
1962 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1963 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1966 test "with credentials", %{conn: conn, user: user} do
1967 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1969 request_path = "/api/statuses/pin/#{activity.id}.json"
1973 |> with_credentials(user.nickname, "test")
1974 |> post(request_path)
1976 user = refresh_record(user)
1978 assert json_response(response, 200) ==
1979 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
1983 describe "POST /api/statuses/unpin/:id" do
1985 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1986 [user: insert(:user)]
1989 test "without valid credentials", %{conn: conn} do
1990 note_activity = insert(:note_activity)
1991 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1992 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1995 test "with credentials", %{conn: conn, user: user} do
1996 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1997 {:ok, activity} = CommonAPI.pin(activity.id, user)
1999 request_path = "/api/statuses/unpin/#{activity.id}.json"
2003 |> with_credentials(user.nickname, "test")
2004 |> post(request_path)
2006 user = refresh_record(user)
2008 assert json_response(response, 200) ==
2009 ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
2013 describe "GET /api/oauth_tokens" do
2015 token = insert(:oauth_token) |> Repo.preload(:user)
2020 test "renders list", %{token: token} do
2023 |> assign(:user, token.user)
2024 |> get("/api/oauth_tokens")
2027 json_response(response, 200)
2031 assert keys -- ["id", "app_name", "valid_until"] == []
2034 test "revoke token", %{token: token} do
2037 |> assign(:user, token.user)
2038 |> delete("/api/oauth_tokens/#{token.id}")
2040 tokens = Token.get_user_tokens(token.user)
2043 assert response.status == 201