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
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 length(response) == 0
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