1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.TwitterAPI.ControllerTest do
6 use Pleroma.Web.ConnCase
7 alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
8 alias Pleroma.Builders.ActivityBuilder
9 alias Pleroma.Builders.UserBuilder
11 alias Pleroma.Activity
14 alias Pleroma.Notification
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.OAuth.Token
17 alias Pleroma.Web.TwitterAPI.Controller
18 alias Pleroma.Web.TwitterAPI.UserView
19 alias Pleroma.Web.TwitterAPI.NotificationView
20 alias Pleroma.Web.CommonAPI
21 alias Pleroma.Web.TwitterAPI.TwitterAPI
25 import Pleroma.Factory
28 @banner "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
30 describe "POST /api/account/update_profile_banner" do
31 test "it updates the banner", %{conn: conn} do
35 |> assign(:user, user)
36 |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => @banner})
39 user = refresh_record(user)
40 assert user.info.banner["type"] == "Image"
44 describe "POST /api/qvitter/update_background_image" do
45 test "it updates the background", %{conn: conn} do
49 |> assign(:user, user)
50 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => @banner})
53 user = refresh_record(user)
54 assert user.info.background["type"] == "Image"
58 describe "POST /api/account/verify_credentials" do
61 test "without valid credentials", %{conn: conn} do
62 conn = post(conn, "/api/account/verify_credentials.json")
63 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
66 test "with credentials", %{conn: conn, user: user} do
69 |> with_credentials(user.nickname, "test")
70 |> post("/api/account/verify_credentials.json")
74 UserView.render("show.json", %{user: user, token: response["token"], for: user})
78 describe "POST /statuses/update.json" do
81 test "without valid credentials", %{conn: conn} do
82 conn = post(conn, "/api/statuses/update.json")
83 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
86 test "with credentials", %{conn: conn, user: user} do
87 conn_with_creds = conn |> with_credentials(user.nickname, "test")
88 request_path = "/api/statuses/update.json"
91 "request" => request_path,
92 "error" => "Client must provide a 'status' parameter with a value."
99 assert json_response(conn, 400) == error_response
103 |> post(request_path, %{status: ""})
105 assert json_response(conn, 400) == error_response
109 |> post(request_path, %{status: " "})
111 assert json_response(conn, 400) == error_response
113 # we post with visibility private in order to avoid triggering relay
116 |> post(request_path, %{status: "Nice meme.", visibility: "private"})
118 assert json_response(conn, 200) ==
119 ActivityRepresenter.to_map(Repo.one(Activity), %{user: user, for: user})
123 describe "GET /statuses/public_timeline.json" do
126 test "returns statuses", %{conn: conn} do
128 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
129 ActivityBuilder.insert_list(10, %{}, %{user: user})
130 since_id = List.last(activities).id
134 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
136 response = json_response(conn, 200)
138 assert length(response) == 10
141 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
143 Application.get_env(:pleroma, :instance)
144 |> Keyword.put(:public, false)
146 Application.put_env(:pleroma, :instance, instance)
149 |> get("/api/statuses/public_timeline.json")
150 |> json_response(403)
153 Application.get_env(:pleroma, :instance)
154 |> Keyword.put(:public, true)
156 Application.put_env(:pleroma, :instance, instance)
159 test "returns 200 to authenticated request when the instance is not public",
160 %{conn: conn, user: user} do
162 Application.get_env(:pleroma, :instance)
163 |> Keyword.put(:public, false)
165 Application.put_env(:pleroma, :instance, instance)
168 |> with_credentials(user.nickname, "test")
169 |> get("/api/statuses/public_timeline.json")
170 |> json_response(200)
173 Application.get_env(:pleroma, :instance)
174 |> Keyword.put(:public, true)
176 Application.put_env(:pleroma, :instance, instance)
179 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
181 |> get("/api/statuses/public_timeline.json")
182 |> json_response(200)
185 test "returns 200 to authenticated request when the instance is public",
186 %{conn: conn, user: user} do
188 |> with_credentials(user.nickname, "test")
189 |> get("/api/statuses/public_timeline.json")
190 |> json_response(200)
193 test_with_mock "treats user as unauthenticated if `assigns[:token]` is present but lacks `read` permission",
197 token = insert(:oauth_token, scopes: ["write"])
200 |> put_req_header("authorization", "Bearer #{token.token}")
201 |> get("/api/statuses/public_timeline.json")
202 |> json_response(200)
204 assert called(Controller.public_timeline(%{assigns: %{user: nil}}, :_))
208 describe "GET /statuses/public_and_external_timeline.json" do
211 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
213 Application.get_env(:pleroma, :instance)
214 |> Keyword.put(:public, false)
216 Application.put_env(:pleroma, :instance, instance)
219 |> get("/api/statuses/public_and_external_timeline.json")
220 |> json_response(403)
223 Application.get_env(:pleroma, :instance)
224 |> Keyword.put(:public, true)
226 Application.put_env(:pleroma, :instance, instance)
229 test "returns 200 to authenticated request when the instance is not public",
230 %{conn: conn, user: user} do
232 Application.get_env(:pleroma, :instance)
233 |> Keyword.put(:public, false)
235 Application.put_env(:pleroma, :instance, instance)
238 |> with_credentials(user.nickname, "test")
239 |> get("/api/statuses/public_and_external_timeline.json")
240 |> json_response(200)
243 Application.get_env(:pleroma, :instance)
244 |> Keyword.put(:public, true)
246 Application.put_env(:pleroma, :instance, instance)
249 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
251 |> get("/api/statuses/public_and_external_timeline.json")
252 |> json_response(200)
255 test "returns 200 to authenticated request when the instance is public",
256 %{conn: conn, user: user} do
258 |> with_credentials(user.nickname, "test")
259 |> get("/api/statuses/public_and_external_timeline.json")
260 |> json_response(200)
264 describe "GET /statuses/show/:id.json" do
265 test "returns one status", %{conn: conn} do
267 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
268 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
272 |> get("/api/statuses/show/#{activity.id}.json")
274 response = json_response(conn, 200)
276 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
280 describe "GET /users/show.json" do
281 test "gets user with screen_name", %{conn: conn} do
286 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
288 response = json_response(conn, 200)
290 assert response["id"] == user.id
293 test "gets user with user_id", %{conn: conn} do
298 |> get("/api/users/show.json", %{"user_id" => user.id})
300 response = json_response(conn, 200)
302 assert response["id"] == user.id
305 test "gets a user for a logged in user", %{conn: conn} do
307 logged_in = insert(:user)
309 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
313 |> with_credentials(logged_in.nickname, "test")
314 |> get("/api/users/show.json", %{"user_id" => user.id})
316 response = json_response(conn, 200)
318 assert response["following"] == true
322 describe "GET /statusnet/conversation/:id.json" do
323 test "returns the statuses in the conversation", %{conn: conn} do
324 {:ok, _user} = UserBuilder.insert()
325 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
326 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
327 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
331 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
333 response = json_response(conn, 200)
335 assert length(response) == 2
339 describe "GET /statuses/friends_timeline.json" do
342 test "without valid credentials", %{conn: conn} do
343 conn = get(conn, "/api/statuses/friends_timeline.json")
344 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
347 test "with credentials", %{conn: conn, user: current_user} do
351 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
353 returned_activities =
354 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
356 other_user = insert(:user)
357 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
358 since_id = List.last(activities).id
361 Changeset.change(current_user, following: [User.ap_followers(user)])
366 |> with_credentials(current_user.nickname, "test")
367 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
369 response = json_response(conn, 200)
371 assert length(response) == 10
374 Enum.map(returned_activities, fn activity ->
375 ActivityRepresenter.to_map(activity, %{
376 user: User.get_cached_by_ap_id(activity.data["actor"]),
383 describe "GET /statuses/dm_timeline.json" do
384 test "it show direct messages", %{conn: conn} do
385 user_one = insert(:user)
386 user_two = insert(:user)
388 {:ok, user_two} = User.follow(user_two, user_one)
391 CommonAPI.post(user_one, %{
392 "status" => "Hi @#{user_two.nickname}!",
393 "visibility" => "direct"
397 CommonAPI.post(user_two, %{
398 "status" => "Hi @#{user_one.nickname}!",
399 "visibility" => "direct"
402 {:ok, _follower_only} =
403 CommonAPI.post(user_one, %{
404 "status" => "Hi @#{user_two.nickname}!",
405 "visibility" => "private"
408 # Only direct should be visible here
411 |> assign(:user, user_two)
412 |> get("/api/statuses/dm_timeline.json")
414 [status, status_two] = json_response(res_conn, 200)
415 assert status["id"] == direct_two.id
416 assert status_two["id"] == direct.id
420 describe "GET /statuses/mentions.json" do
423 test "without valid credentials", %{conn: conn} do
424 conn = get(conn, "/api/statuses/mentions.json")
425 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
428 test "with credentials", %{conn: conn, user: current_user} do
430 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
434 |> with_credentials(current_user.nickname, "test")
435 |> get("/api/statuses/mentions.json")
437 response = json_response(conn, 200)
439 assert length(response) == 1
441 assert Enum.at(response, 0) ==
442 ActivityRepresenter.to_map(activity, %{
445 mentioned: [current_user]
450 describe "GET /api/qvitter/statuses/notifications.json" do
453 test "without valid credentials", %{conn: conn} do
454 conn = get(conn, "/api/qvitter/statuses/notifications.json")
455 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
458 test "with credentials", %{conn: conn, user: current_user} do
459 other_user = insert(:user)
462 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
466 |> with_credentials(current_user.nickname, "test")
467 |> get("/api/qvitter/statuses/notifications.json")
469 response = json_response(conn, 200)
471 assert length(response) == 1
474 NotificationView.render("notification.json", %{
475 notifications: Notification.for_user(current_user),
481 describe "POST /api/qvitter/statuses/notifications/read" do
484 test "without valid credentials", %{conn: conn} do
485 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
486 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
489 test "with credentials, without any params", %{conn: conn, user: current_user} do
492 |> with_credentials(current_user.nickname, "test")
493 |> post("/api/qvitter/statuses/notifications/read")
495 assert json_response(conn, 400) == %{
496 "error" => "You need to specify latest_id",
497 "request" => "/api/qvitter/statuses/notifications/read"
501 test "with credentials, with params", %{conn: conn, user: current_user} do
502 other_user = insert(:user)
505 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
509 |> with_credentials(current_user.nickname, "test")
510 |> get("/api/qvitter/statuses/notifications.json")
512 [notification] = response = json_response(response_conn, 200)
514 assert length(response) == 1
516 assert notification["is_seen"] == 0
520 |> with_credentials(current_user.nickname, "test")
521 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
523 [notification] = response = json_response(response_conn, 200)
525 assert length(response) == 1
527 assert notification["is_seen"] == 1
531 describe "GET /statuses/user_timeline.json" do
534 test "without any params", %{conn: conn} do
535 conn = get(conn, "/api/statuses/user_timeline.json")
537 assert json_response(conn, 400) == %{
538 "error" => "You need to specify screen_name or user_id",
539 "request" => "/api/statuses/user_timeline.json"
543 test "with user_id", %{conn: conn} do
545 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
547 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
548 response = json_response(conn, 200)
549 assert length(response) == 1
550 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
553 test "with screen_name", %{conn: conn} do
555 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
557 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
558 response = json_response(conn, 200)
559 assert length(response) == 1
560 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
563 test "with credentials", %{conn: conn, user: current_user} do
564 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
568 |> with_credentials(current_user.nickname, "test")
569 |> get("/api/statuses/user_timeline.json")
571 response = json_response(conn, 200)
573 assert length(response) == 1
575 assert Enum.at(response, 0) ==
576 ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
579 test "with credentials with user_id", %{conn: conn, user: current_user} do
581 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
585 |> with_credentials(current_user.nickname, "test")
586 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
588 response = json_response(conn, 200)
590 assert length(response) == 1
591 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
594 test "with credentials screen_name", %{conn: conn, user: current_user} do
596 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
600 |> with_credentials(current_user.nickname, "test")
601 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
603 response = json_response(conn, 200)
605 assert length(response) == 1
606 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
609 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
611 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
612 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
616 |> with_credentials(current_user.nickname, "test")
617 |> get("/api/statuses/user_timeline.json", %{
618 "user_id" => user.id,
619 "include_rts" => "false"
622 response = json_response(conn, 200)
624 assert length(response) == 1
625 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
629 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
631 response = json_response(conn, 200)
633 assert length(response) == 1
634 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
638 describe "POST /friendships/create.json" do
641 test "without valid credentials", %{conn: conn} do
642 conn = post(conn, "/api/friendships/create.json")
643 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
646 test "with credentials", %{conn: conn, user: current_user} do
647 followed = insert(:user)
651 |> with_credentials(current_user.nickname, "test")
652 |> post("/api/friendships/create.json", %{user_id: followed.id})
654 current_user = Repo.get(User, current_user.id)
655 assert User.ap_followers(followed) in current_user.following
657 assert json_response(conn, 200) ==
658 UserView.render("show.json", %{user: followed, for: current_user})
661 test "for restricted account", %{conn: conn, user: current_user} do
662 followed = insert(:user, info: %User.Info{locked: true})
666 |> with_credentials(current_user.nickname, "test")
667 |> post("/api/friendships/create.json", %{user_id: followed.id})
669 current_user = Repo.get(User, current_user.id)
670 followed = Repo.get(User, followed.id)
672 refute User.ap_followers(followed) in current_user.following
673 assert followed.info.follow_request_count == 1
675 assert json_response(conn, 200) ==
676 UserView.render("show.json", %{user: followed, for: current_user})
680 describe "POST /friendships/destroy.json" do
683 test "without valid credentials", %{conn: conn} do
684 conn = post(conn, "/api/friendships/destroy.json")
685 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
688 test "with credentials", %{conn: conn, user: current_user} do
689 followed = insert(:user)
691 {:ok, current_user} = User.follow(current_user, followed)
692 assert User.ap_followers(followed) in current_user.following
693 ActivityPub.follow(current_user, followed)
697 |> with_credentials(current_user.nickname, "test")
698 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
700 current_user = Repo.get(User, current_user.id)
701 assert current_user.following == [current_user.ap_id]
703 assert json_response(conn, 200) ==
704 UserView.render("show.json", %{user: followed, for: current_user})
708 describe "POST /blocks/create.json" do
711 test "without valid credentials", %{conn: conn} do
712 conn = post(conn, "/api/blocks/create.json")
713 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
716 test "with credentials", %{conn: conn, user: current_user} do
717 blocked = insert(:user)
721 |> with_credentials(current_user.nickname, "test")
722 |> post("/api/blocks/create.json", %{user_id: blocked.id})
724 current_user = Repo.get(User, current_user.id)
725 assert User.blocks?(current_user, blocked)
727 assert json_response(conn, 200) ==
728 UserView.render("show.json", %{user: blocked, for: current_user})
732 describe "POST /blocks/destroy.json" do
735 test "without valid credentials", %{conn: conn} do
736 conn = post(conn, "/api/blocks/destroy.json")
737 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
740 test "with credentials", %{conn: conn, user: current_user} do
741 blocked = insert(:user)
743 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
744 assert User.blocks?(current_user, blocked)
748 |> with_credentials(current_user.nickname, "test")
749 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
751 current_user = Repo.get(User, current_user.id)
752 assert current_user.info.blocks == []
754 assert json_response(conn, 200) ==
755 UserView.render("show.json", %{user: blocked, for: current_user})
759 describe "GET /help/test.json" do
760 test "returns \"ok\"", %{conn: conn} do
761 conn = get(conn, "/api/help/test.json")
762 assert json_response(conn, 200) == "ok"
766 describe "POST /api/qvitter/update_avatar.json" do
769 test "without valid credentials", %{conn: conn} do
770 conn = post(conn, "/api/qvitter/update_avatar.json")
771 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
774 test "with credentials", %{conn: conn, user: current_user} do
775 avatar_image = File.read!("test/fixtures/avatar_data_uri")
779 |> with_credentials(current_user.nickname, "test")
780 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
782 current_user = Repo.get(User, current_user.id)
783 assert is_map(current_user.avatar)
785 assert json_response(conn, 200) ==
786 UserView.render("show.json", %{user: current_user, for: current_user})
790 describe "GET /api/qvitter/mutes.json" do
793 test "unimplemented mutes without valid credentials", %{conn: conn} do
794 conn = get(conn, "/api/qvitter/mutes.json")
795 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
798 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
801 |> with_credentials(current_user.nickname, "test")
802 |> get("/api/qvitter/mutes.json")
803 |> json_response(200)
809 describe "POST /api/favorites/create/:id" do
812 test "without valid credentials", %{conn: conn} do
813 note_activity = insert(:note_activity)
814 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
815 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
818 test "with credentials", %{conn: conn, user: current_user} do
819 note_activity = insert(:note_activity)
823 |> with_credentials(current_user.nickname, "test")
824 |> post("/api/favorites/create/#{note_activity.id}.json")
826 assert json_response(conn, 200)
829 test "with credentials, invalid param", %{conn: conn, user: current_user} do
832 |> with_credentials(current_user.nickname, "test")
833 |> post("/api/favorites/create/wrong.json")
835 assert json_response(conn, 400)
838 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
841 |> with_credentials(current_user.nickname, "test")
842 |> post("/api/favorites/create/1.json")
844 assert json_response(conn, 400)
848 describe "POST /api/favorites/destroy/:id" do
851 test "without valid credentials", %{conn: conn} do
852 note_activity = insert(:note_activity)
853 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
854 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
857 test "with credentials", %{conn: conn, user: current_user} do
858 note_activity = insert(:note_activity)
859 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
860 ActivityPub.like(current_user, object)
864 |> with_credentials(current_user.nickname, "test")
865 |> post("/api/favorites/destroy/#{note_activity.id}.json")
867 assert json_response(conn, 200)
871 describe "POST /api/statuses/retweet/:id" do
874 test "without valid credentials", %{conn: conn} do
875 note_activity = insert(:note_activity)
876 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
877 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
880 test "with credentials", %{conn: conn, user: current_user} do
881 note_activity = insert(:note_activity)
883 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
887 |> with_credentials(current_user.nickname, "test")
888 |> post(request_path)
890 activity = Repo.get(Activity, note_activity.id)
891 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
893 assert json_response(response, 200) ==
894 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
898 describe "POST /api/statuses/unretweet/:id" do
901 test "without valid credentials", %{conn: conn} do
902 note_activity = insert(:note_activity)
903 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
904 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
907 test "with credentials", %{conn: conn, user: current_user} do
908 note_activity = insert(:note_activity)
910 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
914 |> with_credentials(current_user.nickname, "test")
915 |> post(request_path)
917 request_path = String.replace(request_path, "retweet", "unretweet")
921 |> with_credentials(current_user.nickname, "test")
922 |> post(request_path)
924 activity = Repo.get(Activity, note_activity.id)
925 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
927 assert json_response(response, 200) ==
928 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
932 describe "POST /api/account/register" do
933 test "it creates a new user", %{conn: conn} do
935 "nickname" => "lain",
936 "email" => "lain@wired.jp",
937 "fullname" => "lain iwakura",
938 "bio" => "close the world.",
939 "password" => "bear",
945 |> post("/api/account/register", data)
947 user = json_response(conn, 200)
949 fetched_user = Repo.get_by(User, nickname: "lain")
950 assert user == UserView.render("show.json", %{user: fetched_user})
953 test "it returns errors on a problem", %{conn: conn} do
955 "email" => "lain@wired.jp",
956 "fullname" => "lain iwakura",
957 "bio" => "close the world.",
958 "password" => "bear",
964 |> post("/api/account/register", data)
966 errors = json_response(conn, 400)
968 assert is_binary(errors["error"])
972 describe "POST /api/account/password_reset, with valid parameters" do
973 setup %{conn: conn} do
975 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
976 %{conn: conn, user: user}
979 test "it returns 204", %{conn: conn} do
980 assert json_response(conn, :no_content)
983 test "it creates a PasswordResetToken record for user", %{user: user} do
984 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
988 test "it sends an email to user", %{user: user} do
989 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
991 Swoosh.TestAssertions.assert_email_sent(
992 Pleroma.UserEmail.password_reset_email(user, token_record.token)
997 describe "POST /api/account/password_reset, with invalid parameters" do
1000 test "it returns 500 when user is not found", %{conn: conn, user: user} do
1001 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
1002 assert json_response(conn, :internal_server_error)
1005 test "it returns 500 when user is not local", %{conn: conn, user: user} do
1006 {:ok, user} = Repo.update(Changeset.change(user, local: false))
1007 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
1008 assert json_response(conn, :internal_server_error)
1012 describe "GET /api/account/confirm_email/:id/:token" do
1014 user = insert(:user)
1015 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1019 |> Changeset.change()
1020 |> Changeset.put_embed(:info, info_change)
1023 assert user.info.confirmation_pending
1028 test "it redirects to root url", %{conn: conn, user: user} do
1029 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1031 assert 302 == conn.status
1034 test "it confirms the user account", %{conn: conn, user: user} do
1035 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1037 user = Repo.get(User, user.id)
1039 refute user.info.confirmation_pending
1040 refute user.info.confirmation_token
1043 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1044 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1046 assert 500 == conn.status
1049 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1050 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1052 assert 500 == conn.status
1056 describe "POST /api/account/resend_confirmation_email" do
1058 setting = Pleroma.Config.get([:instance, :account_activation_required])
1061 Pleroma.Config.put([:instance, :account_activation_required], true)
1062 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1065 user = insert(:user)
1066 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1070 |> Changeset.change()
1071 |> Changeset.put_embed(:info, info_change)
1074 assert user.info.confirmation_pending
1079 test "it returns 204 No Content", %{conn: conn, user: user} do
1081 |> assign(:user, user)
1082 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1083 |> json_response(:no_content)
1086 test "it sends confirmation email", %{conn: conn, user: user} do
1088 |> assign(:user, user)
1089 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1091 Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
1095 describe "GET /api/externalprofile/show" do
1096 test "it returns the user", %{conn: conn} do
1097 user = insert(:user)
1098 other_user = insert(:user)
1102 |> assign(:user, user)
1103 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1105 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1109 describe "GET /api/statuses/followers" do
1110 test "it returns a user's followers", %{conn: conn} do
1111 user = insert(:user)
1112 follower_one = insert(:user)
1113 follower_two = insert(:user)
1114 _not_follower = insert(:user)
1116 {:ok, follower_one} = User.follow(follower_one, user)
1117 {:ok, follower_two} = User.follow(follower_two, user)
1121 |> assign(:user, user)
1122 |> get("/api/statuses/followers")
1124 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1125 result = json_response(conn, 200)
1126 assert Enum.sort(expected) == Enum.sort(result)
1129 test "it returns 20 followers per page", %{conn: conn} do
1130 user = insert(:user)
1131 followers = insert_list(21, :user)
1133 Enum.each(followers, fn follower ->
1134 User.follow(follower, user)
1139 |> assign(:user, user)
1140 |> get("/api/statuses/followers")
1142 result = json_response(res_conn, 200)
1143 assert length(result) == 20
1147 |> assign(:user, user)
1148 |> get("/api/statuses/followers?page=2")
1150 result = json_response(res_conn, 200)
1151 assert length(result) == 1
1154 test "it returns a given user's followers with user_id", %{conn: conn} do
1155 user = insert(:user)
1156 follower_one = insert(:user)
1157 follower_two = insert(:user)
1158 not_follower = insert(:user)
1160 {:ok, follower_one} = User.follow(follower_one, user)
1161 {:ok, follower_two} = User.follow(follower_two, user)
1165 |> assign(:user, not_follower)
1166 |> get("/api/statuses/followers", %{"user_id" => user.id})
1168 assert MapSet.equal?(
1169 MapSet.new(json_response(conn, 200)),
1171 UserView.render("index.json", %{
1172 users: [follower_one, follower_two],
1179 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1180 user = insert(:user, %{info: %{hide_followers: true}})
1181 follower_one = insert(:user)
1182 follower_two = insert(:user)
1183 not_follower = insert(:user)
1185 {:ok, _follower_one} = User.follow(follower_one, user)
1186 {:ok, _follower_two} = User.follow(follower_two, user)
1190 |> assign(:user, not_follower)
1191 |> get("/api/statuses/followers", %{"user_id" => user.id})
1192 |> json_response(200)
1194 assert [] == response
1197 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1201 user = insert(:user, %{info: %{hide_followers: true}})
1202 follower_one = insert(:user)
1203 follower_two = insert(:user)
1204 _not_follower = insert(:user)
1206 {:ok, _follower_one} = User.follow(follower_one, user)
1207 {:ok, _follower_two} = User.follow(follower_two, user)
1211 |> assign(:user, user)
1212 |> get("/api/statuses/followers", %{"user_id" => user.id})
1214 refute [] == json_response(conn, 200)
1218 describe "GET /api/statuses/blocks" do
1219 test "it returns the list of users blocked by requester", %{conn: conn} do
1220 user = insert(:user)
1221 other_user = insert(:user)
1223 {:ok, user} = User.block(user, other_user)
1227 |> assign(:user, user)
1228 |> get("/api/statuses/blocks")
1230 expected = UserView.render("index.json", %{users: [other_user], for: user})
1231 result = json_response(conn, 200)
1232 assert Enum.sort(expected) == Enum.sort(result)
1236 describe "GET /api/statuses/friends" do
1237 test "it returns the logged in user's friends", %{conn: conn} do
1238 user = insert(:user)
1239 followed_one = insert(:user)
1240 followed_two = insert(:user)
1241 _not_followed = insert(:user)
1243 {:ok, user} = User.follow(user, followed_one)
1244 {:ok, user} = User.follow(user, followed_two)
1248 |> assign(:user, user)
1249 |> get("/api/statuses/friends")
1251 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1252 result = json_response(conn, 200)
1253 assert Enum.sort(expected) == Enum.sort(result)
1256 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1257 user = insert(:user)
1258 followeds = insert_list(21, :user)
1261 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1262 User.follow(user, followed)
1267 |> assign(:user, user)
1268 |> get("/api/statuses/friends")
1270 result = json_response(res_conn, 200)
1271 assert length(result) == 20
1275 |> assign(:user, user)
1276 |> get("/api/statuses/friends", %{page: 2})
1278 result = json_response(res_conn, 200)
1279 assert length(result) == 1
1283 |> assign(:user, user)
1284 |> get("/api/statuses/friends", %{all: true})
1286 result = json_response(res_conn, 200)
1287 assert length(result) == 21
1290 test "it returns a given user's friends with user_id", %{conn: conn} do
1291 user = insert(:user)
1292 followed_one = insert(:user)
1293 followed_two = insert(:user)
1294 _not_followed = insert(:user)
1296 {:ok, user} = User.follow(user, followed_one)
1297 {:ok, user} = User.follow(user, followed_two)
1301 |> assign(:user, user)
1302 |> get("/api/statuses/friends", %{"user_id" => user.id})
1304 assert MapSet.equal?(
1305 MapSet.new(json_response(conn, 200)),
1307 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1312 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1313 user = insert(:user, %{info: %{hide_follows: true}})
1314 followed_one = insert(:user)
1315 followed_two = insert(:user)
1316 not_followed = insert(:user)
1318 {:ok, user} = User.follow(user, followed_one)
1319 {:ok, user} = User.follow(user, followed_two)
1323 |> assign(:user, not_followed)
1324 |> get("/api/statuses/friends", %{"user_id" => user.id})
1326 assert [] == json_response(conn, 200)
1329 test "it returns friends when hide_follows is set to true if the user themselves request it",
1333 user = insert(:user, %{info: %{hide_follows: true}})
1334 followed_one = insert(:user)
1335 followed_two = insert(:user)
1336 _not_followed = insert(:user)
1338 {:ok, _user} = User.follow(user, followed_one)
1339 {:ok, _user} = User.follow(user, followed_two)
1343 |> assign(:user, user)
1344 |> get("/api/statuses/friends", %{"user_id" => user.id})
1345 |> json_response(200)
1347 refute [] == response
1350 test "it returns a given user's friends with screen_name", %{conn: conn} do
1351 user = insert(:user)
1352 followed_one = insert(:user)
1353 followed_two = insert(:user)
1354 _not_followed = insert(:user)
1356 {:ok, user} = User.follow(user, followed_one)
1357 {:ok, user} = User.follow(user, followed_two)
1361 |> assign(:user, user)
1362 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1364 assert MapSet.equal?(
1365 MapSet.new(json_response(conn, 200)),
1367 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1373 describe "GET /friends/ids" do
1374 test "it returns a user's friends", %{conn: conn} do
1375 user = insert(:user)
1376 followed_one = insert(:user)
1377 followed_two = insert(:user)
1378 _not_followed = insert(:user)
1380 {:ok, user} = User.follow(user, followed_one)
1381 {:ok, user} = User.follow(user, followed_two)
1385 |> assign(:user, user)
1386 |> get("/api/friends/ids")
1388 expected = [followed_one.id, followed_two.id]
1390 assert MapSet.equal?(
1391 MapSet.new(Poison.decode!(json_response(conn, 200))),
1392 MapSet.new(expected)
1397 describe "POST /api/account/update_profile.json" do
1398 test "it updates a user's profile", %{conn: conn} do
1399 user = insert(:user)
1400 user2 = insert(:user)
1404 |> assign(:user, user)
1405 |> post("/api/account/update_profile.json", %{
1406 "name" => "new name",
1407 "description" => "hi @#{user2.nickname}"
1410 user = Repo.get!(User, user.id)
1411 assert user.name == "new name"
1414 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1416 }'>@<span>#{user2.nickname}</span></a></span>"
1418 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1421 test "it sets and un-sets hide_follows", %{conn: conn} do
1422 user = insert(:user)
1425 |> assign(:user, user)
1426 |> post("/api/account/update_profile.json", %{
1427 "hide_follows" => "true"
1430 user = Repo.get!(User, user.id)
1431 assert user.info.hide_follows == true
1435 |> assign(:user, user)
1436 |> post("/api/account/update_profile.json", %{
1437 "hide_follows" => "false"
1440 user = Repo.get!(User, user.id)
1441 assert user.info.hide_follows == false
1442 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1445 test "it sets and un-sets hide_followers", %{conn: conn} do
1446 user = insert(:user)
1449 |> assign(:user, user)
1450 |> post("/api/account/update_profile.json", %{
1451 "hide_followers" => "true"
1454 user = Repo.get!(User, user.id)
1455 assert user.info.hide_followers == true
1459 |> assign(:user, user)
1460 |> post("/api/account/update_profile.json", %{
1461 "hide_followers" => "false"
1464 user = Repo.get!(User, user.id)
1465 assert user.info.hide_followers == false
1466 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1469 test "it sets and un-sets show_role", %{conn: conn} do
1470 user = insert(:user)
1473 |> assign(:user, user)
1474 |> post("/api/account/update_profile.json", %{
1475 "show_role" => "true"
1478 user = Repo.get!(User, user.id)
1479 assert user.info.show_role == true
1483 |> assign(:user, user)
1484 |> post("/api/account/update_profile.json", %{
1485 "show_role" => "false"
1488 user = Repo.get!(User, user.id)
1489 assert user.info.show_role == false
1490 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1493 test "it locks an account", %{conn: conn} do
1494 user = insert(:user)
1498 |> assign(:user, user)
1499 |> post("/api/account/update_profile.json", %{
1503 user = Repo.get!(User, user.id)
1504 assert user.info.locked == true
1506 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1509 test "it unlocks an account", %{conn: conn} do
1510 user = insert(:user)
1514 |> assign(:user, user)
1515 |> post("/api/account/update_profile.json", %{
1519 user = Repo.get!(User, user.id)
1520 assert user.info.locked == false
1522 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1526 defp valid_user(_context) do
1527 user = insert(:user)
1531 defp with_credentials(conn, username, password) do
1532 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1533 put_req_header(conn, "authorization", header_content)
1536 describe "GET /api/search.json" do
1537 test "it returns search results", %{conn: conn} do
1538 user = insert(:user)
1539 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1541 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1542 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1546 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1548 assert [status] = json_response(conn, 200)
1549 assert status["id"] == activity.id
1553 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1554 test "it returns the tags timeline", %{conn: conn} do
1555 user = insert(:user)
1556 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1558 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1559 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1563 |> get("/api/statusnet/tags/timeline/2hu.json")
1565 assert [status] = json_response(conn, 200)
1566 assert status["id"] == activity.id
1570 test "Convert newlines to <br> in bio", %{conn: conn} do
1571 user = insert(:user)
1575 |> assign(:user, user)
1576 |> post("/api/account/update_profile.json", %{
1577 "description" => "Hello,\r\nWorld! I\n am a test."
1580 user = Repo.get!(User, user.id)
1581 assert user.bio == "Hello,<br>World! I<br> am a test."
1584 describe "POST /api/pleroma/change_password" do
1587 test "without credentials", %{conn: conn} do
1588 conn = post(conn, "/api/pleroma/change_password")
1589 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1592 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1595 |> with_credentials(current_user.nickname, "test")
1596 |> post("/api/pleroma/change_password", %{
1598 "new_password" => "newpass",
1599 "new_password_confirmation" => "newpass"
1602 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1605 test "with credentials, valid password and new password and confirmation not matching", %{
1611 |> with_credentials(current_user.nickname, "test")
1612 |> post("/api/pleroma/change_password", %{
1613 "password" => "test",
1614 "new_password" => "newpass",
1615 "new_password_confirmation" => "notnewpass"
1618 assert json_response(conn, 200) == %{
1619 "error" => "New password does not match confirmation."
1623 test "with credentials, valid password and invalid new password", %{
1629 |> with_credentials(current_user.nickname, "test")
1630 |> post("/api/pleroma/change_password", %{
1631 "password" => "test",
1632 "new_password" => "",
1633 "new_password_confirmation" => ""
1636 assert json_response(conn, 200) == %{
1637 "error" => "New password can't be blank."
1641 test "with credentials, valid password and matching new password and confirmation", %{
1647 |> with_credentials(current_user.nickname, "test")
1648 |> post("/api/pleroma/change_password", %{
1649 "password" => "test",
1650 "new_password" => "newpass",
1651 "new_password_confirmation" => "newpass"
1654 assert json_response(conn, 200) == %{"status" => "success"}
1655 fetched_user = Repo.get(User, current_user.id)
1656 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1660 describe "POST /api/pleroma/delete_account" do
1663 test "without credentials", %{conn: conn} do
1664 conn = post(conn, "/api/pleroma/delete_account")
1665 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1668 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1671 |> with_credentials(current_user.nickname, "test")
1672 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1674 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1677 test "with credentials and valid password", %{conn: conn, user: current_user} do
1680 |> with_credentials(current_user.nickname, "test")
1681 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1683 assert json_response(conn, 200) == %{"status" => "success"}
1684 # Wait a second for the started task to end
1689 describe "GET /api/pleroma/friend_requests" do
1690 test "it lists friend requests" do
1691 user = insert(:user)
1692 other_user = insert(:user)
1694 {:ok, _activity} = ActivityPub.follow(other_user, user)
1696 user = Repo.get(User, user.id)
1697 other_user = Repo.get(User, other_user.id)
1699 assert User.following?(other_user, user) == false
1703 |> assign(:user, user)
1704 |> get("/api/pleroma/friend_requests")
1706 assert [relationship] = json_response(conn, 200)
1707 assert other_user.id == relationship["id"]
1710 test "requires 'read' permission", %{conn: conn} do
1711 token1 = insert(:oauth_token, scopes: ["write"])
1712 token2 = insert(:oauth_token, scopes: ["read"])
1714 for token <- [token1, token2] do
1717 |> put_req_header("authorization", "Bearer #{token.token}")
1718 |> get("/api/pleroma/friend_requests")
1720 if token == token1 do
1721 assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
1723 assert json_response(conn, 200)
1729 describe "POST /api/pleroma/friendships/approve" do
1730 test "it approves a friend request" do
1731 user = insert(:user)
1732 other_user = insert(:user)
1734 {:ok, _activity} = ActivityPub.follow(other_user, user)
1736 user = Repo.get(User, user.id)
1737 other_user = Repo.get(User, other_user.id)
1739 assert User.following?(other_user, user) == false
1740 assert user.info.follow_request_count == 1
1744 |> assign(:user, user)
1745 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1747 user = Repo.get(User, user.id)
1749 assert relationship = json_response(conn, 200)
1750 assert other_user.id == relationship["id"]
1751 assert relationship["follows_you"] == true
1752 assert user.info.follow_request_count == 0
1756 describe "POST /api/pleroma/friendships/deny" do
1757 test "it denies a friend request" do
1758 user = insert(:user)
1759 other_user = insert(:user)
1761 {:ok, _activity} = ActivityPub.follow(other_user, user)
1763 user = Repo.get(User, user.id)
1764 other_user = Repo.get(User, other_user.id)
1766 assert User.following?(other_user, user) == false
1767 assert user.info.follow_request_count == 1
1771 |> assign(:user, user)
1772 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1774 user = Repo.get(User, user.id)
1776 assert relationship = json_response(conn, 200)
1777 assert other_user.id == relationship["id"]
1778 assert relationship["follows_you"] == false
1779 assert user.info.follow_request_count == 0
1783 describe "GET /api/pleroma/search_user" do
1784 test "it returns users, ordered by similarity", %{conn: conn} do
1785 user = insert(:user, %{name: "eal"})
1786 user_two = insert(:user, %{name: "eal me"})
1787 _user_three = insert(:user, %{name: "zzz"})
1791 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1792 |> json_response(200)
1794 assert length(resp) == 2
1795 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1799 describe "POST /api/media/upload" do
1801 Pleroma.DataCase.ensure_local_uploader(context)
1804 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1807 user = insert(:user)
1809 upload_filename = "test/fixtures/image_tmp.jpg"
1810 File.cp!("test/fixtures/image.jpg", upload_filename)
1812 file = %Plug.Upload{
1813 content_type: "image/jpg",
1814 path: Path.absname(upload_filename),
1815 filename: "image.jpg"
1820 |> assign(:user, user)
1821 |> put_req_header("content-type", "application/octet-stream")
1822 |> post("/api/media/upload", %{
1825 |> json_response(:ok)
1827 assert response["media_id"]
1828 object = Repo.get(Object, response["media_id"])
1830 assert object.data["actor"] == User.ap_id(user)
1834 describe "POST /api/media/metadata/create" do
1836 object = insert(:note)
1837 user = User.get_by_ap_id(object.data["actor"])
1838 %{object: object, user: user}
1841 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1845 initial_description = object.data["name"]
1846 another_user = insert(:user)
1849 |> assign(:user, another_user)
1850 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1851 |> json_response(:forbidden)
1853 object = Repo.get(Object, object.id)
1854 assert object.data["name"] == initial_description
1857 test "it updates `data[name]` of referenced Object with provided value", %{
1862 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1865 |> assign(:user, user)
1866 |> post("/api/media/metadata/create", %{
1867 "media_id" => object.id,
1868 "alt_text" => %{"text" => description}
1870 |> json_response(:no_content)
1872 object = Repo.get(Object, object.id)
1873 assert object.data["name"] == description
1877 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1878 test "it returns a list of pinned statuses", %{conn: conn} do
1879 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1881 user = insert(:user, %{name: "egor"})
1882 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1883 {:ok, _} = CommonAPI.pin(activity_id, user)
1887 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1888 |> json_response(200)
1890 assert length(resp) == 1
1891 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1895 describe "POST /api/statuses/pin/:id" do
1897 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1898 [user: insert(:user)]
1901 test "without valid credentials", %{conn: conn} do
1902 note_activity = insert(:note_activity)
1903 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1904 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1907 test "with credentials", %{conn: conn, user: user} do
1908 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1910 request_path = "/api/statuses/pin/#{activity.id}.json"
1914 |> with_credentials(user.nickname, "test")
1915 |> post(request_path)
1917 user = refresh_record(user)
1919 assert json_response(response, 200) ==
1920 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1924 describe "POST /api/statuses/unpin/:id" do
1926 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1927 [user: insert(:user)]
1930 test "without valid credentials", %{conn: conn} do
1931 note_activity = insert(:note_activity)
1932 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1933 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1936 test "with credentials", %{conn: conn, user: user} do
1937 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1938 {:ok, activity} = CommonAPI.pin(activity.id, user)
1940 request_path = "/api/statuses/unpin/#{activity.id}.json"
1944 |> with_credentials(user.nickname, "test")
1945 |> post(request_path)
1947 user = refresh_record(user)
1949 assert json_response(response, 200) ==
1950 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1954 describe "GET /api/oauth_tokens" do
1956 token = insert(:oauth_token) |> Repo.preload(:user)
1961 test "renders list", %{token: token} do
1964 |> assign(:user, token.user)
1965 |> get("/api/oauth_tokens")
1968 json_response(response, 200)
1972 assert keys -- ["id", "app_name", "valid_until"] == []
1975 test "revoke token", %{token: token} do
1978 |> assign(:user, token.user)
1979 |> delete("/api/oauth_tokens/#{token.id}")
1981 tokens = Token.get_user_tokens(token.user)
1984 assert response.status == 201