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
7 alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
8 alias Pleroma.Builders.ActivityBuilder
9 alias Pleroma.Builders.UserBuilder
11 alias Pleroma.Activity
14 alias Pleroma.Notification
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.OAuth.Token
17 alias Pleroma.Web.TwitterAPI.Controller
18 alias Pleroma.Web.TwitterAPI.UserView
19 alias Pleroma.Web.TwitterAPI.NotificationView
20 alias Pleroma.Web.CommonAPI
21 alias Pleroma.Web.TwitterAPI.TwitterAPI
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 ActivityRepresenter.to_map(Repo.one(Activity), %{user: user, for: user})
123 describe "GET /statuses/public_timeline.json" do
126 test "returns statuses", %{conn: conn} do
128 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
129 ActivityBuilder.insert_list(10, %{}, %{user: user})
130 since_id = List.last(activities).id
134 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
136 response = json_response(conn, 200)
138 assert length(response) == 10
141 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
143 Application.get_env(:pleroma, :instance)
144 |> Keyword.put(:public, false)
146 Application.put_env(:pleroma, :instance, instance)
149 |> get("/api/statuses/public_timeline.json")
150 |> json_response(403)
153 Application.get_env(:pleroma, :instance)
154 |> Keyword.put(:public, true)
156 Application.put_env(:pleroma, :instance, instance)
159 test "returns 200 to authenticated request when the instance is not public",
160 %{conn: conn, user: user} do
162 Application.get_env(:pleroma, :instance)
163 |> Keyword.put(:public, false)
165 Application.put_env(:pleroma, :instance, instance)
168 |> with_credentials(user.nickname, "test")
169 |> get("/api/statuses/public_timeline.json")
170 |> json_response(200)
173 Application.get_env(:pleroma, :instance)
174 |> Keyword.put(:public, true)
176 Application.put_env(:pleroma, :instance, instance)
179 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
181 |> get("/api/statuses/public_timeline.json")
182 |> json_response(200)
185 test "returns 200 to authenticated request when the instance is public",
186 %{conn: conn, user: user} do
188 |> with_credentials(user.nickname, "test")
189 |> get("/api/statuses/public_timeline.json")
190 |> json_response(200)
193 test_with_mock "treats user as unauthenticated if `assigns[:token]` is present but lacks `read` permission",
197 token = insert(:oauth_token, scopes: ["write"])
200 |> put_req_header("authorization", "Bearer #{token.token}")
201 |> get("/api/statuses/public_timeline.json")
202 |> json_response(200)
204 assert called(Controller.public_timeline(%{assigns: %{user: nil}}, :_))
208 describe "GET /statuses/public_and_external_timeline.json" do
211 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
213 Application.get_env(:pleroma, :instance)
214 |> Keyword.put(:public, false)
216 Application.put_env(:pleroma, :instance, instance)
219 |> get("/api/statuses/public_and_external_timeline.json")
220 |> json_response(403)
223 Application.get_env(:pleroma, :instance)
224 |> Keyword.put(:public, true)
226 Application.put_env(:pleroma, :instance, instance)
229 test "returns 200 to authenticated request when the instance is not public",
230 %{conn: conn, user: user} do
232 Application.get_env(:pleroma, :instance)
233 |> Keyword.put(:public, false)
235 Application.put_env(:pleroma, :instance, instance)
238 |> with_credentials(user.nickname, "test")
239 |> get("/api/statuses/public_and_external_timeline.json")
240 |> json_response(200)
243 Application.get_env(:pleroma, :instance)
244 |> Keyword.put(:public, true)
246 Application.put_env(:pleroma, :instance, instance)
249 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
251 |> get("/api/statuses/public_and_external_timeline.json")
252 |> json_response(200)
255 test "returns 200 to authenticated request when the instance is public",
256 %{conn: conn, user: user} do
258 |> with_credentials(user.nickname, "test")
259 |> get("/api/statuses/public_and_external_timeline.json")
260 |> json_response(200)
264 describe "GET /statuses/show/:id.json" do
265 test "returns one status", %{conn: conn} do
267 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
268 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
272 |> get("/api/statuses/show/#{activity.id}.json")
274 response = json_response(conn, 200)
276 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
280 describe "GET /users/show.json" do
281 test "gets user with screen_name", %{conn: conn} do
286 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
288 response = json_response(conn, 200)
290 assert response["id"] == user.id
293 test "gets user with user_id", %{conn: conn} do
298 |> get("/api/users/show.json", %{"user_id" => user.id})
300 response = json_response(conn, 200)
302 assert response["id"] == user.id
305 test "gets a user for a logged in user", %{conn: conn} do
307 logged_in = insert(:user)
309 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
313 |> with_credentials(logged_in.nickname, "test")
314 |> get("/api/users/show.json", %{"user_id" => user.id})
316 response = json_response(conn, 200)
318 assert response["following"] == true
322 describe "GET /statusnet/conversation/:id.json" do
323 test "returns the statuses in the conversation", %{conn: conn} do
324 {:ok, _user} = UserBuilder.insert()
325 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
326 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
327 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
331 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
333 response = json_response(conn, 200)
335 assert length(response) == 2
339 describe "GET /statuses/friends_timeline.json" do
342 test "without valid credentials", %{conn: conn} do
343 conn = get(conn, "/api/statuses/friends_timeline.json")
344 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
347 test "with credentials", %{conn: conn, user: current_user} do
351 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
353 returned_activities =
354 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
356 other_user = insert(:user)
357 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
358 since_id = List.last(activities).id
361 Changeset.change(current_user, following: [User.ap_followers(user)])
366 |> with_credentials(current_user.nickname, "test")
367 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
369 response = json_response(conn, 200)
371 assert length(response) == 10
374 Enum.map(returned_activities, fn activity ->
375 ActivityRepresenter.to_map(activity, %{
376 user: User.get_cached_by_ap_id(activity.data["actor"]),
383 describe "GET /statuses/dm_timeline.json" do
384 test "it show direct messages", %{conn: conn} do
385 user_one = insert(:user)
386 user_two = insert(:user)
388 {:ok, user_two} = User.follow(user_two, user_one)
391 CommonAPI.post(user_one, %{
392 "status" => "Hi @#{user_two.nickname}!",
393 "visibility" => "direct"
397 CommonAPI.post(user_two, %{
398 "status" => "Hi @#{user_one.nickname}!",
399 "visibility" => "direct"
402 {:ok, _follower_only} =
403 CommonAPI.post(user_one, %{
404 "status" => "Hi @#{user_two.nickname}!",
405 "visibility" => "private"
408 # Only direct should be visible here
411 |> assign(:user, user_two)
412 |> get("/api/statuses/dm_timeline.json")
414 [status, status_two] = json_response(res_conn, 200)
415 assert status["id"] == direct_two.id
416 assert status_two["id"] == direct.id
420 describe "GET /statuses/mentions.json" do
423 test "without valid credentials", %{conn: conn} do
424 conn = get(conn, "/api/statuses/mentions.json")
425 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
428 test "with credentials", %{conn: conn, user: current_user} do
430 CommonAPI.post(current_user, %{
431 "status" => "why is tenshi eating a corndog so cute?",
432 "visibility" => "public"
437 |> with_credentials(current_user.nickname, "test")
438 |> get("/api/statuses/mentions.json")
440 response = json_response(conn, 200)
442 assert length(response) == 1
444 assert Enum.at(response, 0) ==
445 ActivityRepresenter.to_map(activity, %{
448 mentioned: [current_user]
452 test "does not show DMs in mentions timeline", %{conn: conn, user: current_user} do
454 CommonAPI.post(current_user, %{
455 "status" => "Have you guys ever seen how cute tenshi eating a corndog is?",
456 "visibility" => "direct"
461 |> with_credentials(current_user.nickname, "test")
462 |> get("/api/statuses/mentions.json")
464 response = json_response(conn, 200)
466 assert length(response) == 0
470 describe "GET /api/qvitter/statuses/notifications.json" do
473 test "without valid credentials", %{conn: conn} do
474 conn = get(conn, "/api/qvitter/statuses/notifications.json")
475 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
478 test "with credentials", %{conn: conn, user: current_user} do
479 other_user = insert(:user)
482 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
486 |> with_credentials(current_user.nickname, "test")
487 |> get("/api/qvitter/statuses/notifications.json")
489 response = json_response(conn, 200)
491 assert length(response) == 1
494 NotificationView.render("notification.json", %{
495 notifications: Notification.for_user(current_user),
501 describe "POST /api/qvitter/statuses/notifications/read" do
504 test "without valid credentials", %{conn: conn} do
505 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
506 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
509 test "with credentials, without any params", %{conn: conn, user: current_user} do
512 |> with_credentials(current_user.nickname, "test")
513 |> post("/api/qvitter/statuses/notifications/read")
515 assert json_response(conn, 400) == %{
516 "error" => "You need to specify latest_id",
517 "request" => "/api/qvitter/statuses/notifications/read"
521 test "with credentials, with params", %{conn: conn, user: current_user} do
522 other_user = insert(:user)
525 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
529 |> with_credentials(current_user.nickname, "test")
530 |> get("/api/qvitter/statuses/notifications.json")
532 [notification] = response = json_response(response_conn, 200)
534 assert length(response) == 1
536 assert notification["is_seen"] == 0
540 |> with_credentials(current_user.nickname, "test")
541 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
543 [notification] = response = json_response(response_conn, 200)
545 assert length(response) == 1
547 assert notification["is_seen"] == 1
551 describe "GET /statuses/user_timeline.json" do
554 test "without any params", %{conn: conn} do
555 conn = get(conn, "/api/statuses/user_timeline.json")
557 assert json_response(conn, 400) == %{
558 "error" => "You need to specify screen_name or user_id",
559 "request" => "/api/statuses/user_timeline.json"
563 test "with user_id", %{conn: conn} do
565 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
567 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
568 response = json_response(conn, 200)
569 assert length(response) == 1
570 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
573 test "with screen_name", %{conn: conn} do
575 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
577 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
578 response = json_response(conn, 200)
579 assert length(response) == 1
580 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
583 test "with credentials", %{conn: conn, user: current_user} do
584 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
588 |> with_credentials(current_user.nickname, "test")
589 |> get("/api/statuses/user_timeline.json")
591 response = json_response(conn, 200)
593 assert length(response) == 1
595 assert Enum.at(response, 0) ==
596 ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
599 test "with credentials with user_id", %{conn: conn, user: current_user} do
601 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
605 |> with_credentials(current_user.nickname, "test")
606 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
608 response = json_response(conn, 200)
610 assert length(response) == 1
611 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
614 test "with credentials screen_name", %{conn: conn, user: current_user} do
616 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
620 |> with_credentials(current_user.nickname, "test")
621 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
623 response = json_response(conn, 200)
625 assert length(response) == 1
626 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
629 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
631 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
632 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
636 |> with_credentials(current_user.nickname, "test")
637 |> get("/api/statuses/user_timeline.json", %{
638 "user_id" => user.id,
639 "include_rts" => "false"
642 response = json_response(conn, 200)
644 assert length(response) == 1
645 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
649 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
651 response = json_response(conn, 200)
653 assert length(response) == 1
654 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
658 describe "POST /friendships/create.json" do
661 test "without valid credentials", %{conn: conn} do
662 conn = post(conn, "/api/friendships/create.json")
663 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
666 test "with credentials", %{conn: conn, user: current_user} do
667 followed = insert(:user)
671 |> with_credentials(current_user.nickname, "test")
672 |> post("/api/friendships/create.json", %{user_id: followed.id})
674 current_user = Repo.get(User, current_user.id)
675 assert User.ap_followers(followed) in current_user.following
677 assert json_response(conn, 200) ==
678 UserView.render("show.json", %{user: followed, for: current_user})
681 test "for restricted account", %{conn: conn, user: current_user} do
682 followed = insert(:user, info: %User.Info{locked: true})
686 |> with_credentials(current_user.nickname, "test")
687 |> post("/api/friendships/create.json", %{user_id: followed.id})
689 current_user = Repo.get(User, current_user.id)
690 followed = Repo.get(User, followed.id)
692 refute User.ap_followers(followed) in current_user.following
693 assert followed.info.follow_request_count == 1
695 assert json_response(conn, 200) ==
696 UserView.render("show.json", %{user: followed, for: current_user})
700 describe "POST /friendships/destroy.json" do
703 test "without valid credentials", %{conn: conn} do
704 conn = post(conn, "/api/friendships/destroy.json")
705 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
708 test "with credentials", %{conn: conn, user: current_user} do
709 followed = insert(:user)
711 {:ok, current_user} = User.follow(current_user, followed)
712 assert User.ap_followers(followed) in current_user.following
713 ActivityPub.follow(current_user, followed)
717 |> with_credentials(current_user.nickname, "test")
718 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
720 current_user = Repo.get(User, current_user.id)
721 assert current_user.following == [current_user.ap_id]
723 assert json_response(conn, 200) ==
724 UserView.render("show.json", %{user: followed, for: current_user})
728 describe "POST /blocks/create.json" do
731 test "without valid credentials", %{conn: conn} do
732 conn = post(conn, "/api/blocks/create.json")
733 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
736 test "with credentials", %{conn: conn, user: current_user} do
737 blocked = insert(:user)
741 |> with_credentials(current_user.nickname, "test")
742 |> post("/api/blocks/create.json", %{user_id: blocked.id})
744 current_user = Repo.get(User, current_user.id)
745 assert User.blocks?(current_user, blocked)
747 assert json_response(conn, 200) ==
748 UserView.render("show.json", %{user: blocked, for: current_user})
752 describe "POST /blocks/destroy.json" do
755 test "without valid credentials", %{conn: conn} do
756 conn = post(conn, "/api/blocks/destroy.json")
757 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
760 test "with credentials", %{conn: conn, user: current_user} do
761 blocked = insert(:user)
763 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
764 assert User.blocks?(current_user, blocked)
768 |> with_credentials(current_user.nickname, "test")
769 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
771 current_user = Repo.get(User, current_user.id)
772 assert current_user.info.blocks == []
774 assert json_response(conn, 200) ==
775 UserView.render("show.json", %{user: blocked, for: current_user})
779 describe "GET /help/test.json" do
780 test "returns \"ok\"", %{conn: conn} do
781 conn = get(conn, "/api/help/test.json")
782 assert json_response(conn, 200) == "ok"
786 describe "POST /api/qvitter/update_avatar.json" do
789 test "without valid credentials", %{conn: conn} do
790 conn = post(conn, "/api/qvitter/update_avatar.json")
791 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
794 test "with credentials", %{conn: conn, user: current_user} do
795 avatar_image = File.read!("test/fixtures/avatar_data_uri")
799 |> with_credentials(current_user.nickname, "test")
800 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
802 current_user = Repo.get(User, current_user.id)
803 assert is_map(current_user.avatar)
805 assert json_response(conn, 200) ==
806 UserView.render("show.json", %{user: current_user, for: current_user})
810 describe "GET /api/qvitter/mutes.json" do
813 test "unimplemented mutes without valid credentials", %{conn: conn} do
814 conn = get(conn, "/api/qvitter/mutes.json")
815 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
818 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
821 |> with_credentials(current_user.nickname, "test")
822 |> get("/api/qvitter/mutes.json")
823 |> json_response(200)
829 describe "POST /api/favorites/create/:id" do
832 test "without valid credentials", %{conn: conn} do
833 note_activity = insert(:note_activity)
834 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
835 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
838 test "with credentials", %{conn: conn, user: current_user} do
839 note_activity = insert(:note_activity)
843 |> with_credentials(current_user.nickname, "test")
844 |> post("/api/favorites/create/#{note_activity.id}.json")
846 assert json_response(conn, 200)
849 test "with credentials, invalid param", %{conn: conn, user: current_user} do
852 |> with_credentials(current_user.nickname, "test")
853 |> post("/api/favorites/create/wrong.json")
855 assert json_response(conn, 400)
858 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
861 |> with_credentials(current_user.nickname, "test")
862 |> post("/api/favorites/create/1.json")
864 assert json_response(conn, 400)
868 describe "POST /api/favorites/destroy/:id" do
871 test "without valid credentials", %{conn: conn} do
872 note_activity = insert(:note_activity)
873 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
874 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
877 test "with credentials", %{conn: conn, user: current_user} do
878 note_activity = insert(:note_activity)
879 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
880 ActivityPub.like(current_user, object)
884 |> with_credentials(current_user.nickname, "test")
885 |> post("/api/favorites/destroy/#{note_activity.id}.json")
887 assert json_response(conn, 200)
891 describe "POST /api/statuses/retweet/:id" do
894 test "without valid credentials", %{conn: conn} do
895 note_activity = insert(:note_activity)
896 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
897 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
900 test "with credentials", %{conn: conn, user: current_user} do
901 note_activity = insert(:note_activity)
903 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
907 |> with_credentials(current_user.nickname, "test")
908 |> post(request_path)
910 activity = Repo.get(Activity, note_activity.id)
911 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
913 assert json_response(response, 200) ==
914 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
918 describe "POST /api/statuses/unretweet/:id" do
921 test "without valid credentials", %{conn: conn} do
922 note_activity = insert(:note_activity)
923 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
924 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
927 test "with credentials", %{conn: conn, user: current_user} do
928 note_activity = insert(:note_activity)
930 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
934 |> with_credentials(current_user.nickname, "test")
935 |> post(request_path)
937 request_path = String.replace(request_path, "retweet", "unretweet")
941 |> with_credentials(current_user.nickname, "test")
942 |> post(request_path)
944 activity = Repo.get(Activity, note_activity.id)
945 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
947 assert json_response(response, 200) ==
948 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
952 describe "POST /api/account/register" do
953 test "it creates a new user", %{conn: conn} do
955 "nickname" => "lain",
956 "email" => "lain@wired.jp",
957 "fullname" => "lain iwakura",
958 "bio" => "close the world.",
959 "password" => "bear",
965 |> post("/api/account/register", data)
967 user = json_response(conn, 200)
969 fetched_user = Repo.get_by(User, nickname: "lain")
970 assert user == UserView.render("show.json", %{user: fetched_user})
973 test "it returns errors on a problem", %{conn: conn} do
975 "email" => "lain@wired.jp",
976 "fullname" => "lain iwakura",
977 "bio" => "close the world.",
978 "password" => "bear",
984 |> post("/api/account/register", data)
986 errors = json_response(conn, 400)
988 assert is_binary(errors["error"])
992 describe "POST /api/account/password_reset, with valid parameters" do
993 setup %{conn: conn} do
995 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
996 %{conn: conn, user: user}
999 test "it returns 204", %{conn: conn} do
1000 assert json_response(conn, :no_content)
1003 test "it creates a PasswordResetToken record for user", %{user: user} do
1004 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1008 test "it sends an email to user", %{user: user} do
1009 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1011 Swoosh.TestAssertions.assert_email_sent(
1012 Pleroma.UserEmail.password_reset_email(user, token_record.token)
1017 describe "POST /api/account/password_reset, with invalid parameters" do
1020 test "it returns 500 when user is not found", %{conn: conn, user: user} do
1021 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1022 assert json_response(conn, :internal_server_error)
1025 test "it returns 500 when user is not local", %{conn: conn, user: user} do
1026 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1027 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1028 assert json_response(conn, :internal_server_error)
1032 describe "GET /api/account/confirm_email/:id/:token" do
1034 user = insert(:user)
1035 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1039 |> Changeset.change()
1040 |> Changeset.put_embed(:info, info_change)
1043 assert user.info.confirmation_pending
1048 test "it redirects to root url", %{conn: conn, user: user} do
1049 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1051 assert 302 == conn.status
1054 test "it confirms the user account", %{conn: conn, user: user} do
1055 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1057 user = Repo.get(User, user.id)
1059 refute user.info.confirmation_pending
1060 refute user.info.confirmation_token
1063 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1064 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1066 assert 500 == conn.status
1069 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1070 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1072 assert 500 == conn.status
1076 describe "POST /api/account/resend_confirmation_email" do
1078 setting = Pleroma.Config.get([:instance, :account_activation_required])
1081 Pleroma.Config.put([:instance, :account_activation_required], true)
1082 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1085 user = insert(:user)
1086 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1090 |> Changeset.change()
1091 |> Changeset.put_embed(:info, info_change)
1094 assert user.info.confirmation_pending
1099 test "it returns 204 No Content", %{conn: conn, user: user} do
1101 |> assign(:user, user)
1102 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1103 |> json_response(:no_content)
1106 test "it sends confirmation email", %{conn: conn, user: user} do
1108 |> assign(:user, user)
1109 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1111 Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
1115 describe "GET /api/externalprofile/show" do
1116 test "it returns the user", %{conn: conn} do
1117 user = insert(:user)
1118 other_user = insert(:user)
1122 |> assign(:user, user)
1123 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1125 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1129 describe "GET /api/statuses/followers" do
1130 test "it returns a user's followers", %{conn: conn} do
1131 user = insert(:user)
1132 follower_one = insert(:user)
1133 follower_two = insert(:user)
1134 _not_follower = insert(:user)
1136 {:ok, follower_one} = User.follow(follower_one, user)
1137 {:ok, follower_two} = User.follow(follower_two, user)
1141 |> assign(:user, user)
1142 |> get("/api/statuses/followers")
1144 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1145 result = json_response(conn, 200)
1146 assert Enum.sort(expected) == Enum.sort(result)
1149 test "it returns 20 followers per page", %{conn: conn} do
1150 user = insert(:user)
1151 followers = insert_list(21, :user)
1153 Enum.each(followers, fn follower ->
1154 User.follow(follower, user)
1159 |> assign(:user, user)
1160 |> get("/api/statuses/followers")
1162 result = json_response(res_conn, 200)
1163 assert length(result) == 20
1167 |> assign(:user, user)
1168 |> get("/api/statuses/followers?page=2")
1170 result = json_response(res_conn, 200)
1171 assert length(result) == 1
1174 test "it returns a given user's followers with user_id", %{conn: conn} do
1175 user = insert(:user)
1176 follower_one = insert(:user)
1177 follower_two = insert(:user)
1178 not_follower = insert(:user)
1180 {:ok, follower_one} = User.follow(follower_one, user)
1181 {:ok, follower_two} = User.follow(follower_two, user)
1185 |> assign(:user, not_follower)
1186 |> get("/api/statuses/followers", %{"user_id" => user.id})
1188 assert MapSet.equal?(
1189 MapSet.new(json_response(conn, 200)),
1191 UserView.render("index.json", %{
1192 users: [follower_one, follower_two],
1199 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1200 user = insert(:user, %{info: %{hide_followers: true}})
1201 follower_one = insert(:user)
1202 follower_two = insert(:user)
1203 not_follower = insert(:user)
1205 {:ok, _follower_one} = User.follow(follower_one, user)
1206 {:ok, _follower_two} = User.follow(follower_two, user)
1210 |> assign(:user, not_follower)
1211 |> get("/api/statuses/followers", %{"user_id" => user.id})
1212 |> json_response(200)
1214 assert [] == response
1217 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1221 user = insert(:user, %{info: %{hide_followers: true}})
1222 follower_one = insert(:user)
1223 follower_two = insert(:user)
1224 _not_follower = insert(:user)
1226 {:ok, _follower_one} = User.follow(follower_one, user)
1227 {:ok, _follower_two} = User.follow(follower_two, user)
1231 |> assign(:user, user)
1232 |> get("/api/statuses/followers", %{"user_id" => user.id})
1234 refute [] == json_response(conn, 200)
1238 describe "GET /api/statuses/blocks" do
1239 test "it returns the list of users blocked by requester", %{conn: conn} do
1240 user = insert(:user)
1241 other_user = insert(:user)
1243 {:ok, user} = User.block(user, other_user)
1247 |> assign(:user, user)
1248 |> get("/api/statuses/blocks")
1250 expected = UserView.render("index.json", %{users: [other_user], for: user})
1251 result = json_response(conn, 200)
1252 assert Enum.sort(expected) == Enum.sort(result)
1256 describe "GET /api/statuses/friends" do
1257 test "it returns the logged in user's friends", %{conn: conn} do
1258 user = insert(:user)
1259 followed_one = insert(:user)
1260 followed_two = insert(:user)
1261 _not_followed = insert(:user)
1263 {:ok, user} = User.follow(user, followed_one)
1264 {:ok, user} = User.follow(user, followed_two)
1268 |> assign(:user, user)
1269 |> get("/api/statuses/friends")
1271 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1272 result = json_response(conn, 200)
1273 assert Enum.sort(expected) == Enum.sort(result)
1276 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1277 user = insert(:user)
1278 followeds = insert_list(21, :user)
1281 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1282 User.follow(user, followed)
1287 |> assign(:user, user)
1288 |> get("/api/statuses/friends")
1290 result = json_response(res_conn, 200)
1291 assert length(result) == 20
1295 |> assign(:user, user)
1296 |> get("/api/statuses/friends", %{page: 2})
1298 result = json_response(res_conn, 200)
1299 assert length(result) == 1
1303 |> assign(:user, user)
1304 |> get("/api/statuses/friends", %{all: true})
1306 result = json_response(res_conn, 200)
1307 assert length(result) == 21
1310 test "it returns a given user's friends with user_id", %{conn: conn} do
1311 user = insert(:user)
1312 followed_one = insert(:user)
1313 followed_two = insert(:user)
1314 _not_followed = insert(:user)
1316 {:ok, user} = User.follow(user, followed_one)
1317 {:ok, user} = User.follow(user, followed_two)
1321 |> assign(:user, user)
1322 |> get("/api/statuses/friends", %{"user_id" => user.id})
1324 assert MapSet.equal?(
1325 MapSet.new(json_response(conn, 200)),
1327 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1332 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1333 user = insert(:user, %{info: %{hide_follows: true}})
1334 followed_one = insert(:user)
1335 followed_two = insert(:user)
1336 not_followed = insert(:user)
1338 {:ok, user} = User.follow(user, followed_one)
1339 {:ok, user} = User.follow(user, followed_two)
1343 |> assign(:user, not_followed)
1344 |> get("/api/statuses/friends", %{"user_id" => user.id})
1346 assert [] == json_response(conn, 200)
1349 test "it returns friends when hide_follows is set to true if the user themselves request it",
1353 user = insert(:user, %{info: %{hide_follows: true}})
1354 followed_one = insert(:user)
1355 followed_two = insert(:user)
1356 _not_followed = insert(:user)
1358 {:ok, _user} = User.follow(user, followed_one)
1359 {:ok, _user} = User.follow(user, followed_two)
1363 |> assign(:user, user)
1364 |> get("/api/statuses/friends", %{"user_id" => user.id})
1365 |> json_response(200)
1367 refute [] == response
1370 test "it returns a given user's friends with screen_name", %{conn: conn} do
1371 user = insert(:user)
1372 followed_one = insert(:user)
1373 followed_two = insert(:user)
1374 _not_followed = insert(:user)
1376 {:ok, user} = User.follow(user, followed_one)
1377 {:ok, user} = User.follow(user, followed_two)
1381 |> assign(:user, user)
1382 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1384 assert MapSet.equal?(
1385 MapSet.new(json_response(conn, 200)),
1387 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1393 describe "GET /friends/ids" do
1394 test "it returns a user's friends", %{conn: conn} do
1395 user = insert(:user)
1396 followed_one = insert(:user)
1397 followed_two = insert(:user)
1398 _not_followed = insert(:user)
1400 {:ok, user} = User.follow(user, followed_one)
1401 {:ok, user} = User.follow(user, followed_two)
1405 |> assign(:user, user)
1406 |> get("/api/friends/ids")
1408 expected = [followed_one.id, followed_two.id]
1410 assert MapSet.equal?(
1411 MapSet.new(Poison.decode!(json_response(conn, 200))),
1412 MapSet.new(expected)
1417 describe "POST /api/account/update_profile.json" do
1418 test "it updates a user's profile", %{conn: conn} do
1419 user = insert(:user)
1420 user2 = insert(:user)
1424 |> assign(:user, user)
1425 |> post("/api/account/update_profile.json", %{
1426 "name" => "new name",
1427 "description" => "hi @#{user2.nickname}"
1430 user = Repo.get!(User, user.id)
1431 assert user.name == "new name"
1434 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1436 }'>@<span>#{user2.nickname}</span></a></span>"
1438 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1441 test "it sets and un-sets hide_follows", %{conn: conn} do
1442 user = insert(:user)
1445 |> assign(:user, user)
1446 |> post("/api/account/update_profile.json", %{
1447 "hide_follows" => "true"
1450 user = Repo.get!(User, user.id)
1451 assert user.info.hide_follows == true
1455 |> assign(:user, user)
1456 |> post("/api/account/update_profile.json", %{
1457 "hide_follows" => "false"
1460 user = Repo.get!(User, user.id)
1461 assert user.info.hide_follows == false
1462 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1465 test "it sets and un-sets hide_followers", %{conn: conn} do
1466 user = insert(:user)
1469 |> assign(:user, user)
1470 |> post("/api/account/update_profile.json", %{
1471 "hide_followers" => "true"
1474 user = Repo.get!(User, user.id)
1475 assert user.info.hide_followers == true
1479 |> assign(:user, user)
1480 |> post("/api/account/update_profile.json", %{
1481 "hide_followers" => "false"
1484 user = Repo.get!(User, user.id)
1485 assert user.info.hide_followers == false
1486 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1489 test "it sets and un-sets show_role", %{conn: conn} do
1490 user = insert(:user)
1493 |> assign(:user, user)
1494 |> post("/api/account/update_profile.json", %{
1495 "show_role" => "true"
1498 user = Repo.get!(User, user.id)
1499 assert user.info.show_role == true
1503 |> assign(:user, user)
1504 |> post("/api/account/update_profile.json", %{
1505 "show_role" => "false"
1508 user = Repo.get!(User, user.id)
1509 assert user.info.show_role == false
1510 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1513 test "it locks an account", %{conn: conn} do
1514 user = insert(:user)
1518 |> assign(:user, user)
1519 |> post("/api/account/update_profile.json", %{
1523 user = Repo.get!(User, user.id)
1524 assert user.info.locked == true
1526 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1529 test "it unlocks an account", %{conn: conn} do
1530 user = insert(:user)
1534 |> assign(:user, user)
1535 |> post("/api/account/update_profile.json", %{
1539 user = Repo.get!(User, user.id)
1540 assert user.info.locked == false
1542 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1546 defp valid_user(_context) do
1547 user = insert(:user)
1551 defp with_credentials(conn, username, password) do
1552 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1553 put_req_header(conn, "authorization", header_content)
1556 describe "GET /api/search.json" do
1557 test "it returns search results", %{conn: conn} do
1558 user = insert(:user)
1559 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1561 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1562 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1566 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1568 assert [status] = json_response(conn, 200)
1569 assert status["id"] == activity.id
1573 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1574 test "it returns the tags timeline", %{conn: conn} do
1575 user = insert(:user)
1576 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1578 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1579 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1583 |> get("/api/statusnet/tags/timeline/2hu.json")
1585 assert [status] = json_response(conn, 200)
1586 assert status["id"] == activity.id
1590 test "Convert newlines to <br> in bio", %{conn: conn} do
1591 user = insert(:user)
1595 |> assign(:user, user)
1596 |> post("/api/account/update_profile.json", %{
1597 "description" => "Hello,\r\nWorld! I\n am a test."
1600 user = Repo.get!(User, user.id)
1601 assert user.bio == "Hello,<br>World! I<br> am a test."
1604 describe "POST /api/pleroma/change_password" do
1607 test "without credentials", %{conn: conn} do
1608 conn = post(conn, "/api/pleroma/change_password")
1609 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1612 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1615 |> with_credentials(current_user.nickname, "test")
1616 |> post("/api/pleroma/change_password", %{
1618 "new_password" => "newpass",
1619 "new_password_confirmation" => "newpass"
1622 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1625 test "with credentials, valid password and new password and confirmation not matching", %{
1631 |> with_credentials(current_user.nickname, "test")
1632 |> post("/api/pleroma/change_password", %{
1633 "password" => "test",
1634 "new_password" => "newpass",
1635 "new_password_confirmation" => "notnewpass"
1638 assert json_response(conn, 200) == %{
1639 "error" => "New password does not match confirmation."
1643 test "with credentials, valid password and invalid new password", %{
1649 |> with_credentials(current_user.nickname, "test")
1650 |> post("/api/pleroma/change_password", %{
1651 "password" => "test",
1652 "new_password" => "",
1653 "new_password_confirmation" => ""
1656 assert json_response(conn, 200) == %{
1657 "error" => "New password can't be blank."
1661 test "with credentials, valid password and matching new password and confirmation", %{
1667 |> with_credentials(current_user.nickname, "test")
1668 |> post("/api/pleroma/change_password", %{
1669 "password" => "test",
1670 "new_password" => "newpass",
1671 "new_password_confirmation" => "newpass"
1674 assert json_response(conn, 200) == %{"status" => "success"}
1675 fetched_user = Repo.get(User, current_user.id)
1676 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1680 describe "POST /api/pleroma/delete_account" do
1683 test "without credentials", %{conn: conn} do
1684 conn = post(conn, "/api/pleroma/delete_account")
1685 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1688 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1691 |> with_credentials(current_user.nickname, "test")
1692 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1694 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1697 test "with credentials and valid password", %{conn: conn, user: current_user} do
1700 |> with_credentials(current_user.nickname, "test")
1701 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1703 assert json_response(conn, 200) == %{"status" => "success"}
1704 # Wait a second for the started task to end
1709 describe "GET /api/pleroma/friend_requests" do
1710 test "it lists friend requests" do
1711 user = insert(:user)
1712 other_user = insert(:user)
1714 {:ok, _activity} = ActivityPub.follow(other_user, user)
1716 user = Repo.get(User, user.id)
1717 other_user = Repo.get(User, other_user.id)
1719 assert User.following?(other_user, user) == false
1723 |> assign(:user, user)
1724 |> get("/api/pleroma/friend_requests")
1726 assert [relationship] = json_response(conn, 200)
1727 assert other_user.id == relationship["id"]
1730 test "requires 'read' permission", %{conn: conn} do
1731 token1 = insert(:oauth_token, scopes: ["write"])
1732 token2 = insert(:oauth_token, scopes: ["read"])
1734 for token <- [token1, token2] do
1737 |> put_req_header("authorization", "Bearer #{token.token}")
1738 |> get("/api/pleroma/friend_requests")
1740 if token == token1 do
1741 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1743 assert json_response(conn, 200)
1749 describe "POST /api/pleroma/friendships/approve" do
1750 test "it approves a friend request" do
1751 user = insert(:user)
1752 other_user = insert(:user)
1754 {:ok, _activity} = ActivityPub.follow(other_user, user)
1756 user = Repo.get(User, user.id)
1757 other_user = Repo.get(User, other_user.id)
1759 assert User.following?(other_user, user) == false
1760 assert user.info.follow_request_count == 1
1764 |> assign(:user, user)
1765 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1767 user = Repo.get(User, user.id)
1769 assert relationship = json_response(conn, 200)
1770 assert other_user.id == relationship["id"]
1771 assert relationship["follows_you"] == true
1772 assert user.info.follow_request_count == 0
1776 describe "POST /api/pleroma/friendships/deny" do
1777 test "it denies a friend request" do
1778 user = insert(:user)
1779 other_user = insert(:user)
1781 {:ok, _activity} = ActivityPub.follow(other_user, user)
1783 user = Repo.get(User, user.id)
1784 other_user = Repo.get(User, other_user.id)
1786 assert User.following?(other_user, user) == false
1787 assert user.info.follow_request_count == 1
1791 |> assign(:user, user)
1792 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1794 user = Repo.get(User, user.id)
1796 assert relationship = json_response(conn, 200)
1797 assert other_user.id == relationship["id"]
1798 assert relationship["follows_you"] == false
1799 assert user.info.follow_request_count == 0
1803 describe "GET /api/pleroma/search_user" do
1804 test "it returns users, ordered by similarity", %{conn: conn} do
1805 user = insert(:user, %{name: "eal"})
1806 user_two = insert(:user, %{name: "eal me"})
1807 _user_three = insert(:user, %{name: "zzz"})
1811 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1812 |> json_response(200)
1814 assert length(resp) == 2
1815 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1819 describe "POST /api/media/upload" do
1821 Pleroma.DataCase.ensure_local_uploader(context)
1824 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1827 user = insert(:user)
1829 upload_filename = "test/fixtures/image_tmp.jpg"
1830 File.cp!("test/fixtures/image.jpg", upload_filename)
1832 file = %Plug.Upload{
1833 content_type: "image/jpg",
1834 path: Path.absname(upload_filename),
1835 filename: "image.jpg"
1840 |> assign(:user, user)
1841 |> put_req_header("content-type", "application/octet-stream")
1842 |> post("/api/media/upload", %{
1845 |> json_response(:ok)
1847 assert response["media_id"]
1848 object = Repo.get(Object, response["media_id"])
1850 assert object.data["actor"] == User.ap_id(user)
1854 describe "POST /api/media/metadata/create" do
1856 object = insert(:note)
1857 user = User.get_by_ap_id(object.data["actor"])
1858 %{object: object, user: user}
1861 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1865 initial_description = object.data["name"]
1866 another_user = insert(:user)
1869 |> assign(:user, another_user)
1870 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1871 |> json_response(:forbidden)
1873 object = Repo.get(Object, object.id)
1874 assert object.data["name"] == initial_description
1877 test "it updates `data[name]` of referenced Object with provided value", %{
1882 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1885 |> assign(:user, user)
1886 |> post("/api/media/metadata/create", %{
1887 "media_id" => object.id,
1888 "alt_text" => %{"text" => description}
1890 |> json_response(:no_content)
1892 object = Repo.get(Object, object.id)
1893 assert object.data["name"] == description
1897 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1898 test "it returns a list of pinned statuses", %{conn: conn} do
1899 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1901 user = insert(:user, %{name: "egor"})
1902 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1903 {:ok, _} = CommonAPI.pin(activity_id, user)
1907 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1908 |> json_response(200)
1910 assert length(resp) == 1
1911 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1915 describe "POST /api/statuses/pin/:id" do
1917 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1918 [user: insert(:user)]
1921 test "without valid credentials", %{conn: conn} do
1922 note_activity = insert(:note_activity)
1923 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1924 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1927 test "with credentials", %{conn: conn, user: user} do
1928 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1930 request_path = "/api/statuses/pin/#{activity.id}.json"
1934 |> with_credentials(user.nickname, "test")
1935 |> post(request_path)
1937 user = refresh_record(user)
1939 assert json_response(response, 200) ==
1940 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1944 describe "POST /api/statuses/unpin/:id" do
1946 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1947 [user: insert(:user)]
1950 test "without valid credentials", %{conn: conn} do
1951 note_activity = insert(:note_activity)
1952 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1953 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1956 test "with credentials", %{conn: conn, user: user} do
1957 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1958 {:ok, activity} = CommonAPI.pin(activity.id, user)
1960 request_path = "/api/statuses/unpin/#{activity.id}.json"
1964 |> with_credentials(user.nickname, "test")
1965 |> post(request_path)
1967 user = refresh_record(user)
1969 assert json_response(response, 200) ==
1970 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1974 describe "GET /api/oauth_tokens" do
1976 token = insert(:oauth_token) |> Repo.preload(:user)
1981 test "renders list", %{token: token} do
1984 |> assign(:user, token.user)
1985 |> get("/api/oauth_tokens")
1988 json_response(response, 200)
1992 assert keys -- ["id", "app_name", "valid_until"] == []
1995 test "revoke token", %{token: token} do
1998 |> assign(:user, token.user)
1999 |> delete("/api/oauth_tokens/#{token.id}")
2001 tokens = Token.get_user_tokens(token.user)
2004 assert response.status == 201