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.Representers.ActivityRepresenter
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 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
419 test "doesn't include DMs from blocked users", %{conn: conn} do
420 blocker = insert(:user)
421 blocked = insert(:user)
423 {:ok, blocker} = User.block(blocker, blocked)
425 {:ok, _blocked_direct} =
426 CommonAPI.post(blocked, %{
427 "status" => "Hi @#{blocker.nickname}!",
428 "visibility" => "direct"
432 CommonAPI.post(user, %{
433 "status" => "Hi @#{blocker.nickname}!",
434 "visibility" => "direct"
439 |> assign(:user, blocker)
440 |> get("/api/statuses/dm_timeline.json")
442 [status] = json_response(res_conn, 200)
443 assert status["id"] == direct.id
447 describe "GET /statuses/mentions.json" do
450 test "without valid credentials", %{conn: conn} do
451 conn = get(conn, "/api/statuses/mentions.json")
452 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
455 test "with credentials", %{conn: conn, user: current_user} do
457 CommonAPI.post(current_user, %{
458 "status" => "why is tenshi eating a corndog so cute?",
459 "visibility" => "public"
464 |> with_credentials(current_user.nickname, "test")
465 |> get("/api/statuses/mentions.json")
467 response = json_response(conn, 200)
469 assert length(response) == 1
471 assert Enum.at(response, 0) ==
472 ActivityRepresenter.to_map(activity, %{
475 mentioned: [current_user]
479 test "does not show DMs in mentions timeline", %{conn: conn, user: current_user} do
481 CommonAPI.post(current_user, %{
482 "status" => "Have you guys ever seen how cute tenshi eating a corndog is?",
483 "visibility" => "direct"
488 |> with_credentials(current_user.nickname, "test")
489 |> get("/api/statuses/mentions.json")
491 response = json_response(conn, 200)
493 assert Enum.empty?(response)
497 describe "GET /api/qvitter/statuses/notifications.json" do
500 test "without valid credentials", %{conn: conn} do
501 conn = get(conn, "/api/qvitter/statuses/notifications.json")
502 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
505 test "with credentials", %{conn: conn, user: current_user} do
506 other_user = insert(:user)
509 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
513 |> with_credentials(current_user.nickname, "test")
514 |> get("/api/qvitter/statuses/notifications.json")
516 response = json_response(conn, 200)
518 assert length(response) == 1
521 NotificationView.render("notification.json", %{
522 notifications: Notification.for_user(current_user),
528 describe "POST /api/qvitter/statuses/notifications/read" do
531 test "without valid credentials", %{conn: conn} do
532 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
533 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
536 test "with credentials, without any params", %{conn: conn, user: current_user} do
539 |> with_credentials(current_user.nickname, "test")
540 |> post("/api/qvitter/statuses/notifications/read")
542 assert json_response(conn, 400) == %{
543 "error" => "You need to specify latest_id",
544 "request" => "/api/qvitter/statuses/notifications/read"
548 test "with credentials, with params", %{conn: conn, user: current_user} do
549 other_user = insert(:user)
552 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
556 |> with_credentials(current_user.nickname, "test")
557 |> get("/api/qvitter/statuses/notifications.json")
559 [notification] = response = json_response(response_conn, 200)
561 assert length(response) == 1
563 assert notification["is_seen"] == 0
567 |> with_credentials(current_user.nickname, "test")
568 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
570 [notification] = response = json_response(response_conn, 200)
572 assert length(response) == 1
574 assert notification["is_seen"] == 1
578 describe "GET /statuses/user_timeline.json" do
581 test "without any params", %{conn: conn} do
582 conn = get(conn, "/api/statuses/user_timeline.json")
584 assert json_response(conn, 400) == %{
585 "error" => "You need to specify screen_name or user_id",
586 "request" => "/api/statuses/user_timeline.json"
590 test "with user_id", %{conn: conn} do
592 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
594 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
595 response = json_response(conn, 200)
596 assert length(response) == 1
597 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
600 test "with screen_name", %{conn: conn} do
602 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
604 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
605 response = json_response(conn, 200)
606 assert length(response) == 1
607 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
610 test "with credentials", %{conn: conn, user: current_user} do
611 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
615 |> with_credentials(current_user.nickname, "test")
616 |> get("/api/statuses/user_timeline.json")
618 response = json_response(conn, 200)
620 assert length(response) == 1
622 assert Enum.at(response, 0) ==
623 ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
626 test "with credentials with user_id", %{conn: conn, user: current_user} do
628 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
632 |> with_credentials(current_user.nickname, "test")
633 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
635 response = json_response(conn, 200)
637 assert length(response) == 1
638 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
641 test "with credentials screen_name", %{conn: conn, user: current_user} do
643 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
647 |> with_credentials(current_user.nickname, "test")
648 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
650 response = json_response(conn, 200)
652 assert length(response) == 1
653 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
656 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
658 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
659 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
663 |> with_credentials(current_user.nickname, "test")
664 |> get("/api/statuses/user_timeline.json", %{
665 "user_id" => user.id,
666 "include_rts" => "false"
669 response = json_response(conn, 200)
671 assert length(response) == 1
672 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
676 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
678 response = json_response(conn, 200)
680 assert length(response) == 1
681 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
685 describe "POST /friendships/create.json" do
688 test "without valid credentials", %{conn: conn} do
689 conn = post(conn, "/api/friendships/create.json")
690 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
693 test "with credentials", %{conn: conn, user: current_user} do
694 followed = insert(:user)
698 |> with_credentials(current_user.nickname, "test")
699 |> post("/api/friendships/create.json", %{user_id: followed.id})
701 current_user = Repo.get(User, current_user.id)
702 assert User.ap_followers(followed) in current_user.following
704 assert json_response(conn, 200) ==
705 UserView.render("show.json", %{user: followed, for: current_user})
708 test "for restricted account", %{conn: conn, user: current_user} do
709 followed = insert(:user, info: %User.Info{locked: true})
713 |> with_credentials(current_user.nickname, "test")
714 |> post("/api/friendships/create.json", %{user_id: followed.id})
716 current_user = Repo.get(User, current_user.id)
717 followed = Repo.get(User, followed.id)
719 refute User.ap_followers(followed) in current_user.following
721 assert json_response(conn, 200) ==
722 UserView.render("show.json", %{user: followed, for: current_user})
726 describe "POST /friendships/destroy.json" do
729 test "without valid credentials", %{conn: conn} do
730 conn = post(conn, "/api/friendships/destroy.json")
731 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
734 test "with credentials", %{conn: conn, user: current_user} do
735 followed = insert(:user)
737 {:ok, current_user} = User.follow(current_user, followed)
738 assert User.ap_followers(followed) in current_user.following
739 ActivityPub.follow(current_user, followed)
743 |> with_credentials(current_user.nickname, "test")
744 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
746 current_user = Repo.get(User, current_user.id)
747 assert current_user.following == [current_user.ap_id]
749 assert json_response(conn, 200) ==
750 UserView.render("show.json", %{user: followed, for: current_user})
754 describe "POST /blocks/create.json" do
757 test "without valid credentials", %{conn: conn} do
758 conn = post(conn, "/api/blocks/create.json")
759 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
762 test "with credentials", %{conn: conn, user: current_user} do
763 blocked = insert(:user)
767 |> with_credentials(current_user.nickname, "test")
768 |> post("/api/blocks/create.json", %{user_id: blocked.id})
770 current_user = Repo.get(User, current_user.id)
771 assert User.blocks?(current_user, blocked)
773 assert json_response(conn, 200) ==
774 UserView.render("show.json", %{user: blocked, for: current_user})
778 describe "POST /blocks/destroy.json" do
781 test "without valid credentials", %{conn: conn} do
782 conn = post(conn, "/api/blocks/destroy.json")
783 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
786 test "with credentials", %{conn: conn, user: current_user} do
787 blocked = insert(:user)
789 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
790 assert User.blocks?(current_user, blocked)
794 |> with_credentials(current_user.nickname, "test")
795 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
797 current_user = Repo.get(User, current_user.id)
798 assert current_user.info.blocks == []
800 assert json_response(conn, 200) ==
801 UserView.render("show.json", %{user: blocked, for: current_user})
805 describe "GET /help/test.json" do
806 test "returns \"ok\"", %{conn: conn} do
807 conn = get(conn, "/api/help/test.json")
808 assert json_response(conn, 200) == "ok"
812 describe "POST /api/qvitter/update_avatar.json" do
815 test "without valid credentials", %{conn: conn} do
816 conn = post(conn, "/api/qvitter/update_avatar.json")
817 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
820 test "with credentials", %{conn: conn, user: current_user} do
821 avatar_image = File.read!("test/fixtures/avatar_data_uri")
825 |> with_credentials(current_user.nickname, "test")
826 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
828 current_user = Repo.get(User, current_user.id)
829 assert is_map(current_user.avatar)
831 assert json_response(conn, 200) ==
832 UserView.render("show.json", %{user: current_user, for: current_user})
836 describe "GET /api/qvitter/mutes.json" do
839 test "unimplemented mutes without valid credentials", %{conn: conn} do
840 conn = get(conn, "/api/qvitter/mutes.json")
841 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
844 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
847 |> with_credentials(current_user.nickname, "test")
848 |> get("/api/qvitter/mutes.json")
849 |> json_response(200)
855 describe "POST /api/favorites/create/:id" do
858 test "without valid credentials", %{conn: conn} do
859 note_activity = insert(:note_activity)
860 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
861 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
864 test "with credentials", %{conn: conn, user: current_user} do
865 note_activity = insert(:note_activity)
869 |> with_credentials(current_user.nickname, "test")
870 |> post("/api/favorites/create/#{note_activity.id}.json")
872 assert json_response(conn, 200)
875 test "with credentials, invalid param", %{conn: conn, user: current_user} do
878 |> with_credentials(current_user.nickname, "test")
879 |> post("/api/favorites/create/wrong.json")
881 assert json_response(conn, 400)
884 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
887 |> with_credentials(current_user.nickname, "test")
888 |> post("/api/favorites/create/1.json")
890 assert json_response(conn, 400)
894 describe "POST /api/favorites/destroy/:id" do
897 test "without valid credentials", %{conn: conn} do
898 note_activity = insert(:note_activity)
899 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
900 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
903 test "with credentials", %{conn: conn, user: current_user} do
904 note_activity = insert(:note_activity)
905 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
906 ActivityPub.like(current_user, object)
910 |> with_credentials(current_user.nickname, "test")
911 |> post("/api/favorites/destroy/#{note_activity.id}.json")
913 assert json_response(conn, 200)
917 describe "POST /api/statuses/retweet/:id" do
920 test "without valid credentials", %{conn: conn} do
921 note_activity = insert(:note_activity)
922 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
923 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
926 test "with credentials", %{conn: conn, user: current_user} do
927 note_activity = insert(:note_activity)
929 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
933 |> with_credentials(current_user.nickname, "test")
934 |> post(request_path)
936 activity = Repo.get(Activity, note_activity.id)
937 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
939 assert json_response(response, 200) ==
940 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
944 describe "POST /api/statuses/unretweet/:id" do
947 test "without valid credentials", %{conn: conn} do
948 note_activity = insert(:note_activity)
949 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
950 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
953 test "with credentials", %{conn: conn, user: current_user} do
954 note_activity = insert(:note_activity)
956 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
960 |> with_credentials(current_user.nickname, "test")
961 |> post(request_path)
963 request_path = String.replace(request_path, "retweet", "unretweet")
967 |> with_credentials(current_user.nickname, "test")
968 |> post(request_path)
970 activity = Repo.get(Activity, note_activity.id)
971 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
973 assert json_response(response, 200) ==
974 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
978 describe "POST /api/account/register" do
979 test "it creates a new user", %{conn: conn} do
981 "nickname" => "lain",
982 "email" => "lain@wired.jp",
983 "fullname" => "lain iwakura",
984 "bio" => "close the world.",
985 "password" => "bear",
991 |> post("/api/account/register", data)
993 user = json_response(conn, 200)
995 fetched_user = Repo.get_by(User, nickname: "lain")
996 assert user == UserView.render("show.json", %{user: fetched_user})
999 test "it returns errors on a problem", %{conn: conn} do
1001 "email" => "lain@wired.jp",
1002 "fullname" => "lain iwakura",
1003 "bio" => "close the world.",
1004 "password" => "bear",
1010 |> post("/api/account/register", data)
1012 errors = json_response(conn, 400)
1014 assert is_binary(errors["error"])
1018 describe "POST /api/account/password_reset, with valid parameters" do
1019 setup %{conn: conn} do
1020 user = insert(:user)
1021 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1022 %{conn: conn, user: user}
1025 test "it returns 204", %{conn: conn} do
1026 assert json_response(conn, :no_content)
1029 test "it creates a PasswordResetToken record for user", %{user: user} do
1030 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1034 test "it sends an email to user", %{user: user} do
1035 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
1037 Swoosh.TestAssertions.assert_email_sent(
1038 Pleroma.UserEmail.password_reset_email(user, token_record.token)
1043 describe "POST /api/account/password_reset, with invalid parameters" do
1046 test "it returns 500 when user is not found", %{conn: conn, user: user} do
1047 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1048 assert json_response(conn, :internal_server_error)
1051 test "it returns 500 when user is not local", %{conn: conn, user: user} do
1052 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1053 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1054 assert json_response(conn, :internal_server_error)
1058 describe "GET /api/account/confirm_email/:id/:token" do
1060 user = insert(:user)
1061 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1065 |> Changeset.change()
1066 |> Changeset.put_embed(:info, info_change)
1069 assert user.info.confirmation_pending
1074 test "it redirects to root url", %{conn: conn, user: user} do
1075 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1077 assert 302 == conn.status
1080 test "it confirms the user account", %{conn: conn, user: user} do
1081 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1083 user = Repo.get(User, user.id)
1085 refute user.info.confirmation_pending
1086 refute user.info.confirmation_token
1089 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1090 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1092 assert 500 == conn.status
1095 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1096 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1098 assert 500 == conn.status
1102 describe "POST /api/account/resend_confirmation_email" do
1104 setting = Pleroma.Config.get([:instance, :account_activation_required])
1107 Pleroma.Config.put([:instance, :account_activation_required], true)
1108 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1111 user = insert(:user)
1112 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1116 |> Changeset.change()
1117 |> Changeset.put_embed(:info, info_change)
1120 assert user.info.confirmation_pending
1125 test "it returns 204 No Content", %{conn: conn, user: user} do
1127 |> assign(:user, user)
1128 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1129 |> json_response(:no_content)
1132 test "it sends confirmation email", %{conn: conn, user: user} do
1134 |> assign(:user, user)
1135 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1137 Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
1141 describe "GET /api/externalprofile/show" do
1142 test "it returns the user", %{conn: conn} do
1143 user = insert(:user)
1144 other_user = insert(:user)
1148 |> assign(:user, user)
1149 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1151 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1155 describe "GET /api/statuses/followers" do
1156 test "it returns a user's followers", %{conn: conn} do
1157 user = insert(:user)
1158 follower_one = insert(:user)
1159 follower_two = insert(:user)
1160 _not_follower = insert(:user)
1162 {:ok, follower_one} = User.follow(follower_one, user)
1163 {:ok, follower_two} = User.follow(follower_two, user)
1167 |> assign(:user, user)
1168 |> get("/api/statuses/followers")
1170 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1171 result = json_response(conn, 200)
1172 assert Enum.sort(expected) == Enum.sort(result)
1175 test "it returns 20 followers per page", %{conn: conn} do
1176 user = insert(:user)
1177 followers = insert_list(21, :user)
1179 Enum.each(followers, fn follower ->
1180 User.follow(follower, user)
1185 |> assign(:user, user)
1186 |> get("/api/statuses/followers")
1188 result = json_response(res_conn, 200)
1189 assert length(result) == 20
1193 |> assign(:user, user)
1194 |> get("/api/statuses/followers?page=2")
1196 result = json_response(res_conn, 200)
1197 assert length(result) == 1
1200 test "it returns a given user's followers with user_id", %{conn: conn} do
1201 user = insert(:user)
1202 follower_one = insert(:user)
1203 follower_two = insert(:user)
1204 not_follower = insert(:user)
1206 {:ok, follower_one} = User.follow(follower_one, user)
1207 {:ok, follower_two} = User.follow(follower_two, user)
1211 |> assign(:user, not_follower)
1212 |> get("/api/statuses/followers", %{"user_id" => user.id})
1214 assert MapSet.equal?(
1215 MapSet.new(json_response(conn, 200)),
1217 UserView.render("index.json", %{
1218 users: [follower_one, follower_two],
1225 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1226 user = insert(:user, %{info: %{hide_followers: true}})
1227 follower_one = insert(:user)
1228 follower_two = insert(:user)
1229 not_follower = insert(:user)
1231 {:ok, _follower_one} = User.follow(follower_one, user)
1232 {:ok, _follower_two} = User.follow(follower_two, user)
1236 |> assign(:user, not_follower)
1237 |> get("/api/statuses/followers", %{"user_id" => user.id})
1238 |> json_response(200)
1240 assert [] == response
1243 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
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, user)
1258 |> get("/api/statuses/followers", %{"user_id" => user.id})
1260 refute [] == json_response(conn, 200)
1264 describe "GET /api/statuses/blocks" do
1265 test "it returns the list of users blocked by requester", %{conn: conn} do
1266 user = insert(:user)
1267 other_user = insert(:user)
1269 {:ok, user} = User.block(user, other_user)
1273 |> assign(:user, user)
1274 |> get("/api/statuses/blocks")
1276 expected = UserView.render("index.json", %{users: [other_user], for: user})
1277 result = json_response(conn, 200)
1278 assert Enum.sort(expected) == Enum.sort(result)
1282 describe "GET /api/statuses/friends" do
1283 test "it returns the logged in user's friends", %{conn: conn} do
1284 user = insert(:user)
1285 followed_one = insert(:user)
1286 followed_two = insert(:user)
1287 _not_followed = insert(:user)
1289 {:ok, user} = User.follow(user, followed_one)
1290 {:ok, user} = User.follow(user, followed_two)
1294 |> assign(:user, user)
1295 |> get("/api/statuses/friends")
1297 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1298 result = json_response(conn, 200)
1299 assert Enum.sort(expected) == Enum.sort(result)
1302 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1303 user = insert(:user)
1304 followeds = insert_list(21, :user)
1307 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1308 User.follow(user, followed)
1313 |> assign(:user, user)
1314 |> get("/api/statuses/friends")
1316 result = json_response(res_conn, 200)
1317 assert length(result) == 20
1321 |> assign(:user, user)
1322 |> get("/api/statuses/friends", %{page: 2})
1324 result = json_response(res_conn, 200)
1325 assert length(result) == 1
1329 |> assign(:user, user)
1330 |> get("/api/statuses/friends", %{all: true})
1332 result = json_response(res_conn, 200)
1333 assert length(result) == 21
1336 test "it returns a given user's friends with user_id", %{conn: conn} do
1337 user = insert(:user)
1338 followed_one = insert(:user)
1339 followed_two = insert(:user)
1340 _not_followed = insert(:user)
1342 {:ok, user} = User.follow(user, followed_one)
1343 {:ok, user} = User.follow(user, followed_two)
1347 |> assign(:user, user)
1348 |> get("/api/statuses/friends", %{"user_id" => user.id})
1350 assert MapSet.equal?(
1351 MapSet.new(json_response(conn, 200)),
1353 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1358 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1359 user = insert(:user, %{info: %{hide_follows: true}})
1360 followed_one = insert(:user)
1361 followed_two = insert(:user)
1362 not_followed = insert(:user)
1364 {:ok, user} = User.follow(user, followed_one)
1365 {:ok, user} = User.follow(user, followed_two)
1369 |> assign(:user, not_followed)
1370 |> get("/api/statuses/friends", %{"user_id" => user.id})
1372 assert [] == json_response(conn, 200)
1375 test "it returns friends when hide_follows is set to true if the user themselves request it",
1379 user = insert(:user, %{info: %{hide_follows: true}})
1380 followed_one = insert(:user)
1381 followed_two = insert(:user)
1382 _not_followed = insert(:user)
1384 {:ok, _user} = User.follow(user, followed_one)
1385 {:ok, _user} = User.follow(user, followed_two)
1389 |> assign(:user, user)
1390 |> get("/api/statuses/friends", %{"user_id" => user.id})
1391 |> json_response(200)
1393 refute [] == response
1396 test "it returns a given user's friends with screen_name", %{conn: conn} do
1397 user = insert(:user)
1398 followed_one = insert(:user)
1399 followed_two = insert(:user)
1400 _not_followed = insert(:user)
1402 {:ok, user} = User.follow(user, followed_one)
1403 {:ok, user} = User.follow(user, followed_two)
1407 |> assign(:user, user)
1408 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1410 assert MapSet.equal?(
1411 MapSet.new(json_response(conn, 200)),
1413 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1419 describe "GET /friends/ids" do
1420 test "it returns a user's friends", %{conn: conn} do
1421 user = insert(:user)
1422 followed_one = insert(:user)
1423 followed_two = insert(:user)
1424 _not_followed = insert(:user)
1426 {:ok, user} = User.follow(user, followed_one)
1427 {:ok, user} = User.follow(user, followed_two)
1431 |> assign(:user, user)
1432 |> get("/api/friends/ids")
1434 expected = [followed_one.id, followed_two.id]
1436 assert MapSet.equal?(
1437 MapSet.new(Poison.decode!(json_response(conn, 200))),
1438 MapSet.new(expected)
1443 describe "POST /api/account/update_profile.json" do
1444 test "it updates a user's profile", %{conn: conn} do
1445 user = insert(:user)
1446 user2 = insert(:user)
1450 |> assign(:user, user)
1451 |> post("/api/account/update_profile.json", %{
1452 "name" => "new name",
1453 "description" => "hi @#{user2.nickname}"
1456 user = Repo.get!(User, user.id)
1457 assert user.name == "new name"
1460 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1462 }'>@<span>#{user2.nickname}</span></a></span>"
1464 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1467 test "it sets and un-sets hide_follows", %{conn: conn} do
1468 user = insert(:user)
1471 |> assign(:user, user)
1472 |> post("/api/account/update_profile.json", %{
1473 "hide_follows" => "true"
1476 user = Repo.get!(User, user.id)
1477 assert user.info.hide_follows == true
1481 |> assign(:user, user)
1482 |> post("/api/account/update_profile.json", %{
1483 "hide_follows" => "false"
1486 user = Repo.get!(User, user.id)
1487 assert user.info.hide_follows == false
1488 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1491 test "it sets and un-sets hide_followers", %{conn: conn} do
1492 user = insert(:user)
1495 |> assign(:user, user)
1496 |> post("/api/account/update_profile.json", %{
1497 "hide_followers" => "true"
1500 user = Repo.get!(User, user.id)
1501 assert user.info.hide_followers == true
1505 |> assign(:user, user)
1506 |> post("/api/account/update_profile.json", %{
1507 "hide_followers" => "false"
1510 user = Repo.get!(User, user.id)
1511 assert user.info.hide_followers == false
1512 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1515 test "it sets and un-sets show_role", %{conn: conn} do
1516 user = insert(:user)
1519 |> assign(:user, user)
1520 |> post("/api/account/update_profile.json", %{
1521 "show_role" => "true"
1524 user = Repo.get!(User, user.id)
1525 assert user.info.show_role == true
1529 |> assign(:user, user)
1530 |> post("/api/account/update_profile.json", %{
1531 "show_role" => "false"
1534 user = Repo.get!(User, user.id)
1535 assert user.info.show_role == false
1536 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1539 test "it locks an account", %{conn: conn} do
1540 user = insert(:user)
1544 |> assign(:user, user)
1545 |> post("/api/account/update_profile.json", %{
1549 user = Repo.get!(User, user.id)
1550 assert user.info.locked == true
1552 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1555 test "it unlocks an account", %{conn: conn} do
1556 user = insert(:user)
1560 |> assign(:user, user)
1561 |> post("/api/account/update_profile.json", %{
1565 user = Repo.get!(User, user.id)
1566 assert user.info.locked == false
1568 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1572 defp valid_user(_context) do
1573 user = insert(:user)
1577 defp with_credentials(conn, username, password) do
1578 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1579 put_req_header(conn, "authorization", header_content)
1582 describe "GET /api/search.json" do
1583 test "it returns search results", %{conn: conn} do
1584 user = insert(:user)
1585 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1587 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1588 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1592 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1594 assert [status] = json_response(conn, 200)
1595 assert status["id"] == activity.id
1599 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1600 test "it returns the tags timeline", %{conn: conn} do
1601 user = insert(:user)
1602 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1604 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1605 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1609 |> get("/api/statusnet/tags/timeline/2hu.json")
1611 assert [status] = json_response(conn, 200)
1612 assert status["id"] == activity.id
1616 test "Convert newlines to <br> in bio", %{conn: conn} do
1617 user = insert(:user)
1621 |> assign(:user, user)
1622 |> post("/api/account/update_profile.json", %{
1623 "description" => "Hello,\r\nWorld! I\n am a test."
1626 user = Repo.get!(User, user.id)
1627 assert user.bio == "Hello,<br>World! I<br> am a test."
1630 describe "POST /api/pleroma/change_password" do
1633 test "without credentials", %{conn: conn} do
1634 conn = post(conn, "/api/pleroma/change_password")
1635 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1638 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1641 |> with_credentials(current_user.nickname, "test")
1642 |> post("/api/pleroma/change_password", %{
1644 "new_password" => "newpass",
1645 "new_password_confirmation" => "newpass"
1648 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1651 test "with credentials, valid password and new password and confirmation not matching", %{
1657 |> with_credentials(current_user.nickname, "test")
1658 |> post("/api/pleroma/change_password", %{
1659 "password" => "test",
1660 "new_password" => "newpass",
1661 "new_password_confirmation" => "notnewpass"
1664 assert json_response(conn, 200) == %{
1665 "error" => "New password does not match confirmation."
1669 test "with credentials, valid password and invalid new password", %{
1675 |> with_credentials(current_user.nickname, "test")
1676 |> post("/api/pleroma/change_password", %{
1677 "password" => "test",
1678 "new_password" => "",
1679 "new_password_confirmation" => ""
1682 assert json_response(conn, 200) == %{
1683 "error" => "New password can't be blank."
1687 test "with credentials, valid password and matching new password and confirmation", %{
1693 |> with_credentials(current_user.nickname, "test")
1694 |> post("/api/pleroma/change_password", %{
1695 "password" => "test",
1696 "new_password" => "newpass",
1697 "new_password_confirmation" => "newpass"
1700 assert json_response(conn, 200) == %{"status" => "success"}
1701 fetched_user = Repo.get(User, current_user.id)
1702 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1706 describe "POST /api/pleroma/delete_account" do
1709 test "without credentials", %{conn: conn} do
1710 conn = post(conn, "/api/pleroma/delete_account")
1711 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1714 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1717 |> with_credentials(current_user.nickname, "test")
1718 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1720 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1723 test "with credentials and valid password", %{conn: conn, user: current_user} do
1726 |> with_credentials(current_user.nickname, "test")
1727 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1729 assert json_response(conn, 200) == %{"status" => "success"}
1730 # Wait a second for the started task to end
1735 describe "GET /api/pleroma/friend_requests" do
1736 test "it lists friend requests" do
1737 user = insert(:user)
1738 other_user = insert(:user)
1740 {:ok, _activity} = ActivityPub.follow(other_user, user)
1742 user = Repo.get(User, user.id)
1743 other_user = Repo.get(User, other_user.id)
1745 assert User.following?(other_user, user) == false
1749 |> assign(:user, user)
1750 |> get("/api/pleroma/friend_requests")
1752 assert [relationship] = json_response(conn, 200)
1753 assert other_user.id == relationship["id"]
1756 test "requires 'read' permission", %{conn: conn} do
1757 token1 = insert(:oauth_token, scopes: ["write"])
1758 token2 = insert(:oauth_token, scopes: ["read"])
1760 for token <- [token1, token2] do
1763 |> put_req_header("authorization", "Bearer #{token.token}")
1764 |> get("/api/pleroma/friend_requests")
1766 if token == token1 do
1767 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1769 assert json_response(conn, 200)
1775 describe "POST /api/pleroma/friendships/approve" do
1776 test "it approves a friend request" do
1777 user = insert(:user)
1778 other_user = insert(:user)
1780 {:ok, _activity} = ActivityPub.follow(other_user, user)
1782 user = Repo.get(User, user.id)
1783 other_user = Repo.get(User, other_user.id)
1785 assert User.following?(other_user, user) == false
1789 |> assign(:user, user)
1790 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1792 assert relationship = json_response(conn, 200)
1793 assert other_user.id == relationship["id"]
1794 assert relationship["follows_you"] == true
1798 describe "POST /api/pleroma/friendships/deny" do
1799 test "it denies a friend request" do
1800 user = insert(:user)
1801 other_user = insert(:user)
1803 {:ok, _activity} = ActivityPub.follow(other_user, user)
1805 user = Repo.get(User, user.id)
1806 other_user = Repo.get(User, other_user.id)
1808 assert User.following?(other_user, user) == false
1812 |> assign(:user, user)
1813 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1815 assert relationship = json_response(conn, 200)
1816 assert other_user.id == relationship["id"]
1817 assert relationship["follows_you"] == false
1821 describe "GET /api/pleroma/search_user" do
1822 test "it returns users, ordered by similarity", %{conn: conn} do
1823 user = insert(:user, %{name: "eal"})
1824 user_two = insert(:user, %{name: "eal me"})
1825 _user_three = insert(:user, %{name: "zzz"})
1829 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1830 |> json_response(200)
1832 assert length(resp) == 2
1833 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1837 describe "POST /api/media/upload" do
1839 Pleroma.DataCase.ensure_local_uploader(context)
1842 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1845 user = insert(:user)
1847 upload_filename = "test/fixtures/image_tmp.jpg"
1848 File.cp!("test/fixtures/image.jpg", upload_filename)
1850 file = %Plug.Upload{
1851 content_type: "image/jpg",
1852 path: Path.absname(upload_filename),
1853 filename: "image.jpg"
1858 |> assign(:user, user)
1859 |> put_req_header("content-type", "application/octet-stream")
1860 |> post("/api/media/upload", %{
1863 |> json_response(:ok)
1865 assert response["media_id"]
1866 object = Repo.get(Object, response["media_id"])
1868 assert object.data["actor"] == User.ap_id(user)
1872 describe "POST /api/media/metadata/create" do
1874 object = insert(:note)
1875 user = User.get_by_ap_id(object.data["actor"])
1876 %{object: object, user: user}
1879 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1883 initial_description = object.data["name"]
1884 another_user = insert(:user)
1887 |> assign(:user, another_user)
1888 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1889 |> json_response(:forbidden)
1891 object = Repo.get(Object, object.id)
1892 assert object.data["name"] == initial_description
1895 test "it updates `data[name]` of referenced Object with provided value", %{
1900 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1903 |> assign(:user, user)
1904 |> post("/api/media/metadata/create", %{
1905 "media_id" => object.id,
1906 "alt_text" => %{"text" => description}
1908 |> json_response(:no_content)
1910 object = Repo.get(Object, object.id)
1911 assert object.data["name"] == description
1915 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1916 test "it returns a list of pinned statuses", %{conn: conn} do
1917 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1919 user = insert(:user, %{name: "egor"})
1920 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1921 {:ok, _} = CommonAPI.pin(activity_id, user)
1925 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1926 |> json_response(200)
1928 assert length(resp) == 1
1929 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1933 describe "POST /api/statuses/pin/:id" do
1935 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1936 [user: insert(:user)]
1939 test "without valid credentials", %{conn: conn} do
1940 note_activity = insert(:note_activity)
1941 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1942 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1945 test "with credentials", %{conn: conn, user: user} do
1946 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1948 request_path = "/api/statuses/pin/#{activity.id}.json"
1952 |> with_credentials(user.nickname, "test")
1953 |> post(request_path)
1955 user = refresh_record(user)
1957 assert json_response(response, 200) ==
1958 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1962 describe "POST /api/statuses/unpin/:id" do
1964 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1965 [user: insert(:user)]
1968 test "without valid credentials", %{conn: conn} do
1969 note_activity = insert(:note_activity)
1970 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1971 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1974 test "with credentials", %{conn: conn, user: user} do
1975 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1976 {:ok, activity} = CommonAPI.pin(activity.id, user)
1978 request_path = "/api/statuses/unpin/#{activity.id}.json"
1982 |> with_credentials(user.nickname, "test")
1983 |> post(request_path)
1985 user = refresh_record(user)
1987 assert json_response(response, 200) ==
1988 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1992 describe "GET /api/oauth_tokens" do
1994 token = insert(:oauth_token) |> Repo.preload(:user)
1999 test "renders list", %{token: token} do
2002 |> assign(:user, token.user)
2003 |> get("/api/oauth_tokens")
2006 json_response(response, 200)
2010 assert keys -- ["id", "app_name", "valid_until"] == []
2013 test "revoke token", %{token: token} do
2016 |> assign(:user, token.user)
2017 |> delete("/api/oauth_tokens/#{token.id}")
2019 tokens = Token.get_user_tokens(token.user)
2022 assert response.status == 201