1 defmodule Pleroma.Web.TwitterAPI.ControllerTest do
2 use Pleroma.Web.ConnCase
3 alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
4 alias Pleroma.Builders.{ActivityBuilder, UserBuilder}
5 alias Pleroma.{Repo, Activity, User, Object, Notification}
6 alias Pleroma.Web.ActivityPub.ActivityPub
7 alias Pleroma.Web.TwitterAPI.UserView
8 alias Pleroma.Web.TwitterAPI.NotificationView
9 alias Pleroma.Web.CommonAPI
10 alias Pleroma.Web.TwitterAPI.TwitterAPI
13 import Pleroma.Factory
15 describe "POST /api/account/update_profile_banner" do
16 test "it updates the banner", %{conn: conn} do
20 "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
24 |> assign(:user, user)
25 |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => new_banner})
28 user = Repo.get(User, user.id)
29 assert user.info.banner["type"] == "Image"
33 describe "POST /api/qvitter/update_background_image" do
34 test "it updates the background", %{conn: conn} do
38 "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
42 |> assign(:user, user)
43 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => new_bg})
46 user = Repo.get(User, user.id)
47 assert user.info.background["type"] == "Image"
51 describe "POST /api/account/verify_credentials" do
54 test "without valid credentials", %{conn: conn} do
55 conn = post(conn, "/api/account/verify_credentials.json")
56 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
59 test "with credentials", %{conn: conn, user: user} do
62 |> with_credentials(user.nickname, "test")
63 |> post("/api/account/verify_credentials.json")
65 assert response = json_response(conn, 200)
66 assert response == UserView.render("show.json", %{user: user, token: response["token"]})
70 describe "POST /statuses/update.json" do
73 test "without valid credentials", %{conn: conn} do
74 conn = post(conn, "/api/statuses/update.json")
75 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
78 test "with credentials", %{conn: conn, user: user} do
79 conn_with_creds = conn |> with_credentials(user.nickname, "test")
80 request_path = "/api/statuses/update.json"
83 "request" => request_path,
84 "error" => "Client must provide a 'status' parameter with a value."
87 conn = conn_with_creds |> post(request_path)
88 assert json_response(conn, 400) == error_response
90 conn = conn_with_creds |> post(request_path, %{status: ""})
91 assert json_response(conn, 400) == error_response
93 conn = conn_with_creds |> post(request_path, %{status: " "})
94 assert json_response(conn, 400) == error_response
96 # we post with visibility private in order to avoid triggering relay
97 conn = conn_with_creds |> post(request_path, %{status: "Nice meme.", visibility: "private"})
99 assert json_response(conn, 200) ==
100 ActivityRepresenter.to_map(Repo.one(Activity), %{user: user})
104 describe "GET /statuses/public_timeline.json" do
105 test "returns statuses", %{conn: conn} do
107 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
108 ActivityBuilder.insert_list(10, %{}, %{user: user})
109 since_id = List.last(activities).id
113 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
115 response = json_response(conn, 200)
117 assert length(response) == 10
120 test "returns 403 to unauthenticated request when the instance is not public" do
122 Application.get_env(:pleroma, :instance)
123 |> Keyword.put(:public, false)
125 Application.put_env(:pleroma, :instance, instance)
128 |> get("/api/statuses/public_timeline.json")
129 |> json_response(403)
132 Application.get_env(:pleroma, :instance)
133 |> Keyword.put(:public, true)
135 Application.put_env(:pleroma, :instance, instance)
138 test "returns 200 to unauthenticated request when the instance is public" do
140 |> get("/api/statuses/public_timeline.json")
141 |> json_response(200)
145 describe "GET /statuses/public_and_external_timeline.json" do
146 test "returns 403 to unauthenticated request when the instance is not public" do
148 Application.get_env(:pleroma, :instance)
149 |> Keyword.put(:public, false)
151 Application.put_env(:pleroma, :instance, instance)
154 |> get("/api/statuses/public_and_external_timeline.json")
155 |> json_response(403)
158 Application.get_env(:pleroma, :instance)
159 |> Keyword.put(:public, true)
161 Application.put_env(:pleroma, :instance, instance)
164 test "returns 200 to unauthenticated request when the instance is public" do
166 |> get("/api/statuses/public_and_external_timeline.json")
167 |> json_response(200)
171 describe "GET /statuses/show/:id.json" do
172 test "returns one status", %{conn: conn} do
174 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
175 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
179 |> get("/api/statuses/show/#{activity.id}.json")
181 response = json_response(conn, 200)
183 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
187 describe "GET /users/show.json" do
188 test "gets user with screen_name", %{conn: conn} do
193 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
195 response = json_response(conn, 200)
197 assert response["id"] == user.id
200 test "gets user with user_id", %{conn: conn} do
205 |> get("/api/users/show.json", %{"user_id" => user.id})
207 response = json_response(conn, 200)
209 assert response["id"] == user.id
212 test "gets a user for a logged in user", %{conn: conn} do
214 logged_in = insert(:user)
216 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
220 |> with_credentials(logged_in.nickname, "test")
221 |> get("/api/users/show.json", %{"user_id" => user.id})
223 response = json_response(conn, 200)
225 assert response["following"] == true
229 describe "GET /statusnet/conversation/:id.json" do
230 test "returns the statuses in the conversation", %{conn: conn} do
231 {:ok, _user} = UserBuilder.insert()
232 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
233 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
234 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
238 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
240 response = json_response(conn, 200)
242 assert length(response) == 2
246 describe "GET /statuses/friends_timeline.json" do
249 test "without valid credentials", %{conn: conn} do
250 conn = get(conn, "/api/statuses/friends_timeline.json")
251 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
254 test "with credentials", %{conn: conn, user: current_user} do
258 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
260 returned_activities =
261 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
263 other_user = insert(:user)
264 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
265 since_id = List.last(activities).id
268 Ecto.Changeset.change(current_user, following: [User.ap_followers(user)])
273 |> with_credentials(current_user.nickname, "test")
274 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
276 response = json_response(conn, 200)
278 assert length(response) == 10
281 Enum.map(returned_activities, fn activity ->
282 ActivityRepresenter.to_map(activity, %{
283 user: User.get_cached_by_ap_id(activity.data["actor"]),
290 describe "GET /statuses/dm_timeline.json" do
291 test "it show direct messages", %{conn: conn} do
292 user_one = insert(:user)
293 user_two = insert(:user)
295 {:ok, user_two} = User.follow(user_two, user_one)
298 CommonAPI.post(user_one, %{
299 "status" => "Hi @#{user_two.nickname}!",
300 "visibility" => "direct"
304 CommonAPI.post(user_two, %{
305 "status" => "Hi @#{user_one.nickname}!",
306 "visibility" => "direct"
309 {:ok, _follower_only} =
310 CommonAPI.post(user_one, %{
311 "status" => "Hi @#{user_two.nickname}!",
312 "visibility" => "private"
315 # Only direct should be visible here
318 |> assign(:user, user_two)
319 |> get("/api/statuses/dm_timeline.json")
321 [status, status_two] = json_response(res_conn, 200)
322 assert status["id"] == direct_two.id
323 assert status_two["id"] == direct.id
327 describe "GET /statuses/mentions.json" do
330 test "without valid credentials", %{conn: conn} do
331 conn = get(conn, "/api/statuses/mentions.json")
332 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
335 test "with credentials", %{conn: conn, user: current_user} do
337 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
341 |> with_credentials(current_user.nickname, "test")
342 |> get("/api/statuses/mentions.json")
344 response = json_response(conn, 200)
346 assert length(response) == 1
348 assert Enum.at(response, 0) ==
349 ActivityRepresenter.to_map(activity, %{
351 mentioned: [current_user]
356 describe "GET /api/qvitter/statuses/notifications.json" do
359 test "without valid credentials", %{conn: conn} do
360 conn = get(conn, "/api/qvitter/statuses/notifications.json")
361 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
364 test "with credentials", %{conn: conn, user: current_user} do
365 other_user = insert(:user)
368 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
372 |> with_credentials(current_user.nickname, "test")
373 |> get("/api/qvitter/statuses/notifications.json")
375 response = json_response(conn, 200)
377 assert length(response) == 1
380 NotificationView.render("notification.json", %{
381 notifications: Notification.for_user(current_user),
387 describe "POST /api/qvitter/statuses/notifications/read" do
390 test "without valid credentials", %{conn: conn} do
391 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
392 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
395 test "with credentials, without any params", %{conn: conn, user: current_user} do
398 |> with_credentials(current_user.nickname, "test")
399 |> post("/api/qvitter/statuses/notifications/read")
401 assert json_response(conn, 400) == %{
402 "error" => "You need to specify latest_id",
403 "request" => "/api/qvitter/statuses/notifications/read"
407 test "with credentials, with params", %{conn: conn, user: current_user} do
408 other_user = insert(:user)
411 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
415 |> with_credentials(current_user.nickname, "test")
416 |> get("/api/qvitter/statuses/notifications.json")
418 [notification] = response = json_response(response_conn, 200)
420 assert length(response) == 1
422 assert notification["is_seen"] == 0
426 |> with_credentials(current_user.nickname, "test")
427 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
429 [notification] = response = json_response(response_conn, 200)
431 assert length(response) == 1
433 assert notification["is_seen"] == 1
437 describe "GET /statuses/user_timeline.json" do
440 test "without any params", %{conn: conn} do
441 conn = get(conn, "/api/statuses/user_timeline.json")
443 assert json_response(conn, 400) == %{
444 "error" => "You need to specify screen_name or user_id",
445 "request" => "/api/statuses/user_timeline.json"
449 test "with user_id", %{conn: conn} do
451 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
453 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
454 response = json_response(conn, 200)
455 assert length(response) == 1
456 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
459 test "with screen_name", %{conn: conn} do
461 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
463 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
464 response = json_response(conn, 200)
465 assert length(response) == 1
466 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
469 test "with credentials", %{conn: conn, user: current_user} do
470 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
474 |> with_credentials(current_user.nickname, "test")
475 |> get("/api/statuses/user_timeline.json")
477 response = json_response(conn, 200)
479 assert length(response) == 1
480 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
483 test "with credentials with user_id", %{conn: conn, user: current_user} do
485 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
489 |> with_credentials(current_user.nickname, "test")
490 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
492 response = json_response(conn, 200)
494 assert length(response) == 1
495 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
498 test "with credentials screen_name", %{conn: conn, user: current_user} do
500 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
504 |> with_credentials(current_user.nickname, "test")
505 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
507 response = json_response(conn, 200)
509 assert length(response) == 1
510 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
514 describe "POST /friendships/create.json" do
517 test "without valid credentials", %{conn: conn} do
518 conn = post(conn, "/api/friendships/create.json")
519 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
522 test "with credentials", %{conn: conn, user: current_user} do
523 followed = insert(:user)
527 |> with_credentials(current_user.nickname, "test")
528 |> post("/api/friendships/create.json", %{user_id: followed.id})
530 current_user = Repo.get(User, current_user.id)
531 assert User.ap_followers(followed) in current_user.following
533 assert json_response(conn, 200) ==
534 UserView.render("show.json", %{user: followed, for: current_user})
538 describe "POST /friendships/destroy.json" do
541 test "without valid credentials", %{conn: conn} do
542 conn = post(conn, "/api/friendships/destroy.json")
543 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
546 test "with credentials", %{conn: conn, user: current_user} do
547 followed = insert(:user)
549 {:ok, current_user} = User.follow(current_user, followed)
550 assert User.ap_followers(followed) in current_user.following
551 ActivityPub.follow(current_user, followed)
555 |> with_credentials(current_user.nickname, "test")
556 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
558 current_user = Repo.get(User, current_user.id)
559 assert current_user.following == [current_user.ap_id]
561 assert json_response(conn, 200) ==
562 UserView.render("show.json", %{user: followed, for: current_user})
566 describe "POST /blocks/create.json" do
569 test "without valid credentials", %{conn: conn} do
570 conn = post(conn, "/api/blocks/create.json")
571 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
574 test "with credentials", %{conn: conn, user: current_user} do
575 blocked = insert(:user)
579 |> with_credentials(current_user.nickname, "test")
580 |> post("/api/blocks/create.json", %{user_id: blocked.id})
582 current_user = Repo.get(User, current_user.id)
583 assert User.blocks?(current_user, blocked)
585 assert json_response(conn, 200) ==
586 UserView.render("show.json", %{user: blocked, for: current_user})
590 describe "POST /blocks/destroy.json" do
593 test "without valid credentials", %{conn: conn} do
594 conn = post(conn, "/api/blocks/destroy.json")
595 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
598 test "with credentials", %{conn: conn, user: current_user} do
599 blocked = insert(:user)
601 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
602 assert User.blocks?(current_user, blocked)
606 |> with_credentials(current_user.nickname, "test")
607 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
609 current_user = Repo.get(User, current_user.id)
610 assert current_user.info.blocks == []
612 assert json_response(conn, 200) ==
613 UserView.render("show.json", %{user: blocked, for: current_user})
617 describe "GET /help/test.json" do
618 test "returns \"ok\"", %{conn: conn} do
619 conn = get(conn, "/api/help/test.json")
620 assert json_response(conn, 200) == "ok"
624 describe "POST /api/qvitter/update_avatar.json" do
627 test "without valid credentials", %{conn: conn} do
628 conn = post(conn, "/api/qvitter/update_avatar.json")
629 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
632 test "with credentials", %{conn: conn, user: current_user} do
633 avatar_image = File.read!("test/fixtures/avatar_data_uri")
637 |> with_credentials(current_user.nickname, "test")
638 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
640 current_user = Repo.get(User, current_user.id)
641 assert is_map(current_user.avatar)
643 assert json_response(conn, 200) ==
644 UserView.render("show.json", %{user: current_user, for: current_user})
648 describe "GET /api/qvitter/mutes.json" do
651 test "unimplemented mutes without valid credentials", %{conn: conn} do
652 conn = get(conn, "/api/qvitter/mutes.json")
653 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
656 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
659 |> with_credentials(current_user.nickname, "test")
660 |> get("/api/qvitter/mutes.json")
662 current_user = Repo.get(User, current_user.id)
664 assert [] = json_response(conn, 200)
668 describe "POST /api/favorites/create/:id" do
671 test "without valid credentials", %{conn: conn} do
672 note_activity = insert(:note_activity)
673 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
674 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
677 test "with credentials", %{conn: conn, user: current_user} do
678 note_activity = insert(:note_activity)
682 |> with_credentials(current_user.nickname, "test")
683 |> post("/api/favorites/create/#{note_activity.id}.json")
685 assert json_response(conn, 200)
688 test "with credentials, invalid param", %{conn: conn, user: current_user} do
691 |> with_credentials(current_user.nickname, "test")
692 |> post("/api/favorites/create/wrong.json")
694 assert json_response(conn, 400)
697 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
700 |> with_credentials(current_user.nickname, "test")
701 |> post("/api/favorites/create/1.json")
703 assert json_response(conn, 500)
707 describe "POST /api/favorites/destroy/:id" do
710 test "without valid credentials", %{conn: conn} do
711 note_activity = insert(:note_activity)
712 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
713 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
716 test "with credentials", %{conn: conn, user: current_user} do
717 note_activity = insert(:note_activity)
718 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
719 ActivityPub.like(current_user, object)
723 |> with_credentials(current_user.nickname, "test")
724 |> post("/api/favorites/destroy/#{note_activity.id}.json")
726 assert json_response(conn, 200)
730 describe "POST /api/statuses/retweet/:id" do
733 test "without valid credentials", %{conn: conn} do
734 note_activity = insert(:note_activity)
735 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
736 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
739 test "with credentials", %{conn: conn, user: current_user} do
740 note_activity = insert(:note_activity)
742 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
746 |> with_credentials(current_user.nickname, "test")
747 |> post(request_path)
749 activity = Repo.get(Activity, note_activity.id)
750 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
752 assert json_response(response, 200) ==
753 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
757 describe "POST /api/statuses/unretweet/:id" do
760 test "without valid credentials", %{conn: conn} do
761 note_activity = insert(:note_activity)
762 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
763 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
766 test "with credentials", %{conn: conn, user: current_user} do
767 note_activity = insert(:note_activity)
769 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
773 |> with_credentials(current_user.nickname, "test")
774 |> post(request_path)
776 request_path = String.replace(request_path, "retweet", "unretweet")
780 |> with_credentials(current_user.nickname, "test")
781 |> post(request_path)
783 activity = Repo.get(Activity, note_activity.id)
784 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
786 assert json_response(response, 200) ==
787 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
791 describe "POST /api/account/register" do
792 test "it creates a new user", %{conn: conn} do
794 "nickname" => "lain",
795 "email" => "lain@wired.jp",
796 "fullname" => "lain iwakura",
797 "bio" => "close the world.",
798 "password" => "bear",
804 |> post("/api/account/register", data)
806 user = json_response(conn, 200)
808 fetched_user = Repo.get_by(User, nickname: "lain")
809 assert user == UserView.render("show.json", %{user: fetched_user})
812 test "it returns errors on a problem", %{conn: conn} do
814 "email" => "lain@wired.jp",
815 "fullname" => "lain iwakura",
816 "bio" => "close the world.",
817 "password" => "bear",
823 |> post("/api/account/register", data)
825 errors = json_response(conn, 400)
827 assert is_binary(errors["error"])
831 describe "GET /api/externalprofile/show" do
832 test "it returns the user", %{conn: conn} do
834 other_user = insert(:user)
838 |> assign(:user, user)
839 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
841 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
845 describe "GET /api/statuses/followers" do
846 test "it returns a user's followers", %{conn: conn} do
848 follower_one = insert(:user)
849 follower_two = insert(:user)
850 _not_follower = insert(:user)
852 {:ok, follower_one} = User.follow(follower_one, user)
853 {:ok, follower_two} = User.follow(follower_two, user)
857 |> assign(:user, user)
858 |> get("/api/statuses/followers")
860 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
861 result = json_response(conn, 200)
862 assert Enum.sort(expected) == Enum.sort(result)
865 test "it returns a given user's followers with user_id", %{conn: conn} do
867 follower_one = insert(:user)
868 follower_two = insert(:user)
869 not_follower = insert(:user)
871 {:ok, follower_one} = User.follow(follower_one, user)
872 {:ok, follower_two} = User.follow(follower_two, user)
876 |> assign(:user, not_follower)
877 |> get("/api/statuses/followers", %{"user_id" => user.id})
879 assert MapSet.equal?(
880 MapSet.new(json_response(conn, 200)),
882 UserView.render("index.json", %{
883 users: [follower_one, follower_two],
890 test "it returns empty for a hidden network", %{conn: conn} do
891 user = insert(:user, %{info: %{hide_network: true}})
892 follower_one = insert(:user)
893 follower_two = insert(:user)
894 not_follower = insert(:user)
896 {:ok, follower_one} = User.follow(follower_one, user)
897 {:ok, follower_two} = User.follow(follower_two, user)
901 |> assign(:user, not_follower)
902 |> get("/api/statuses/followers", %{"user_id" => user.id})
904 assert [] == json_response(conn, 200)
907 test "it returns the followers for a hidden network if requested by the user themselves", %{
910 user = insert(:user, %{info: %{hide_network: true}})
911 follower_one = insert(:user)
912 follower_two = insert(:user)
913 not_follower = insert(:user)
915 {:ok, follower_one} = User.follow(follower_one, user)
916 {:ok, follower_two} = User.follow(follower_two, user)
920 |> assign(:user, user)
921 |> get("/api/statuses/followers", %{"user_id" => user.id})
923 refute [] == json_response(conn, 200)
927 describe "GET /api/statuses/friends" do
928 test "it returns the logged in user's friends", %{conn: conn} do
930 followed_one = insert(:user)
931 followed_two = insert(:user)
932 _not_followed = insert(:user)
934 {:ok, user} = User.follow(user, followed_one)
935 {:ok, user} = User.follow(user, followed_two)
939 |> assign(:user, user)
940 |> get("/api/statuses/friends")
942 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
943 result = json_response(conn, 200)
944 assert Enum.sort(expected) == Enum.sort(result)
947 test "it returns a given user's friends with user_id", %{conn: conn} do
949 followed_one = insert(:user)
950 followed_two = insert(:user)
951 _not_followed = insert(:user)
953 {:ok, user} = User.follow(user, followed_one)
954 {:ok, user} = User.follow(user, followed_two)
958 |> assign(:user, user)
959 |> get("/api/statuses/friends", %{"user_id" => user.id})
961 assert MapSet.equal?(
962 MapSet.new(json_response(conn, 200)),
964 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
969 test "it returns empty for a hidden network", %{conn: conn} do
970 user = insert(:user, %{info: %{hide_network: true}})
971 followed_one = insert(:user)
972 followed_two = insert(:user)
973 not_followed = insert(:user)
975 {:ok, user} = User.follow(user, followed_one)
976 {:ok, user} = User.follow(user, followed_two)
980 |> assign(:user, not_followed)
981 |> get("/api/statuses/friends", %{"user_id" => user.id})
983 assert [] == json_response(conn, 200)
986 test "it returns friends for a hidden network if the user themselves request it", %{
989 user = insert(:user, %{info: %{hide_network: true}})
990 followed_one = insert(:user)
991 followed_two = insert(:user)
992 not_followed = insert(:user)
994 {:ok, user} = User.follow(user, followed_one)
995 {:ok, user} = User.follow(user, followed_two)
999 |> assign(:user, user)
1000 |> get("/api/statuses/friends", %{"user_id" => user.id})
1002 refute [] == json_response(conn, 200)
1005 test "it returns a given user's friends with screen_name", %{conn: conn} do
1006 user = insert(:user)
1007 followed_one = insert(:user)
1008 followed_two = insert(:user)
1009 _not_followed = insert(:user)
1011 {:ok, user} = User.follow(user, followed_one)
1012 {:ok, user} = User.follow(user, followed_two)
1016 |> assign(:user, user)
1017 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1019 assert MapSet.equal?(
1020 MapSet.new(json_response(conn, 200)),
1022 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1028 describe "GET /friends/ids" do
1029 test "it returns a user's friends", %{conn: conn} do
1030 user = insert(:user)
1031 followed_one = insert(:user)
1032 followed_two = insert(:user)
1033 _not_followed = insert(:user)
1035 {:ok, user} = User.follow(user, followed_one)
1036 {:ok, user} = User.follow(user, followed_two)
1040 |> assign(:user, user)
1041 |> get("/api/friends/ids")
1043 expected = [followed_one.id, followed_two.id]
1045 assert MapSet.equal?(
1046 MapSet.new(Poison.decode!(json_response(conn, 200))),
1047 MapSet.new(expected)
1052 describe "POST /api/account/update_profile.json" do
1053 test "it updates a user's profile", %{conn: conn} do
1054 user = insert(:user)
1055 user2 = insert(:user)
1059 |> assign(:user, user)
1060 |> post("/api/account/update_profile.json", %{
1061 "name" => "new name",
1062 "description" => "hi @#{user2.nickname}"
1065 user = Repo.get!(User, user.id)
1066 assert user.name == "new name"
1069 "hi <span><a data-user='#{user2.id}' class='mention' href='#{user2.ap_id}'>@<span>#{
1071 }</span></a></span>"
1073 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1076 test "it sets and un-sets hide_network", %{conn: conn} do
1077 user = insert(:user)
1080 |> assign(:user, user)
1081 |> post("/api/account/update_profile.json", %{
1082 "hide_network" => "true"
1085 user = Repo.get!(User, user.id)
1086 assert user.info.hide_network == true
1090 |> assign(:user, user)
1091 |> post("/api/account/update_profile.json", %{
1092 "hide_network" => "false"
1095 user = Repo.get!(User, user.id)
1096 assert user.info.hide_network == false
1097 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1100 test "it locks an account", %{conn: conn} do
1101 user = insert(:user)
1105 |> assign(:user, user)
1106 |> post("/api/account/update_profile.json", %{
1110 user = Repo.get!(User, user.id)
1111 assert user.info.locked == true
1113 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1116 test "it unlocks an account", %{conn: conn} do
1117 user = insert(:user)
1121 |> assign(:user, user)
1122 |> post("/api/account/update_profile.json", %{
1126 user = Repo.get!(User, user.id)
1127 assert user.info.locked == false
1129 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1133 defp valid_user(_context) do
1134 user = insert(:user)
1138 defp with_credentials(conn, username, password) do
1139 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1140 put_req_header(conn, "authorization", header_content)
1143 describe "GET /api/search.json" do
1144 test "it returns search results", %{conn: conn} do
1145 user = insert(:user)
1146 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1148 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1149 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1153 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1155 assert [status] = json_response(conn, 200)
1156 assert status["id"] == activity.id
1160 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1161 test "it returns the tags timeline", %{conn: conn} do
1162 user = insert(:user)
1163 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1165 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1166 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1170 |> get("/api/statusnet/tags/timeline/2hu.json")
1172 assert [status] = json_response(conn, 200)
1173 assert status["id"] == activity.id
1177 test "Convert newlines to <br> in bio", %{conn: conn} do
1178 user = insert(:user)
1182 |> assign(:user, user)
1183 |> post("/api/account/update_profile.json", %{
1184 "description" => "Hello,\r\nWorld! I\n am a test."
1187 user = Repo.get!(User, user.id)
1188 assert user.bio == "Hello,<br>World! I<br> am a test."
1191 describe "POST /api/pleroma/change_password" do
1194 test "without credentials", %{conn: conn} do
1195 conn = post(conn, "/api/pleroma/change_password")
1196 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1199 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1202 |> with_credentials(current_user.nickname, "test")
1203 |> post("/api/pleroma/change_password", %{
1205 "new_password" => "newpass",
1206 "new_password_confirmation" => "newpass"
1209 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1212 test "with credentials, valid password and new password and confirmation not matching", %{
1218 |> with_credentials(current_user.nickname, "test")
1219 |> post("/api/pleroma/change_password", %{
1220 "password" => "test",
1221 "new_password" => "newpass",
1222 "new_password_confirmation" => "notnewpass"
1225 assert json_response(conn, 200) == %{
1226 "error" => "New password does not match confirmation."
1230 test "with credentials, valid password and invalid new password", %{
1236 |> with_credentials(current_user.nickname, "test")
1237 |> post("/api/pleroma/change_password", %{
1238 "password" => "test",
1239 "new_password" => "",
1240 "new_password_confirmation" => ""
1243 assert json_response(conn, 200) == %{
1244 "error" => "New password can't be blank."
1248 test "with credentials, valid password and matching new password and confirmation", %{
1254 |> with_credentials(current_user.nickname, "test")
1255 |> post("/api/pleroma/change_password", %{
1256 "password" => "test",
1257 "new_password" => "newpass",
1258 "new_password_confirmation" => "newpass"
1261 assert json_response(conn, 200) == %{"status" => "success"}
1262 fetched_user = Repo.get(User, current_user.id)
1263 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1267 describe "POST /api/pleroma/delete_account" do
1270 test "without credentials", %{conn: conn} do
1271 conn = post(conn, "/api/pleroma/delete_account")
1272 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1275 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1278 |> with_credentials(current_user.nickname, "test")
1279 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1281 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1284 test "with credentials and valid password", %{conn: conn, user: current_user} do
1287 |> with_credentials(current_user.nickname, "test")
1288 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1290 assert json_response(conn, 200) == %{"status" => "success"}
1291 # Wait a second for the started task to end
1296 describe "GET /api/pleroma/friend_requests" do
1297 test "it lists friend requests" do
1298 user = insert(:user)
1299 other_user = insert(:user)
1301 {:ok, _activity} = ActivityPub.follow(other_user, user)
1303 user = Repo.get(User, user.id)
1304 other_user = Repo.get(User, other_user.id)
1306 assert User.following?(other_user, user) == false
1310 |> assign(:user, user)
1311 |> get("/api/pleroma/friend_requests")
1313 assert [relationship] = json_response(conn, 200)
1314 assert other_user.id == relationship["id"]
1318 describe "POST /api/pleroma/friendships/approve" do
1319 test "it approves a friend request" do
1320 user = insert(:user)
1321 other_user = insert(:user)
1323 {:ok, _activity} = ActivityPub.follow(other_user, user)
1325 user = Repo.get(User, user.id)
1326 other_user = Repo.get(User, other_user.id)
1328 assert User.following?(other_user, user) == false
1332 |> assign(:user, user)
1333 |> post("/api/pleroma/friendships/approve", %{"user_id" => to_string(other_user.id)})
1335 assert relationship = json_response(conn, 200)
1336 assert other_user.id == relationship["id"]
1337 assert relationship["follows_you"] == true
1341 describe "POST /api/pleroma/friendships/deny" do
1342 test "it denies a friend request" do
1343 user = insert(:user)
1344 other_user = insert(:user)
1346 {:ok, _activity} = ActivityPub.follow(other_user, user)
1348 user = Repo.get(User, user.id)
1349 other_user = Repo.get(User, other_user.id)
1351 assert User.following?(other_user, user) == false
1355 |> assign(:user, user)
1356 |> post("/api/pleroma/friendships/deny", %{"user_id" => to_string(other_user.id)})
1358 assert relationship = json_response(conn, 200)
1359 assert other_user.id == relationship["id"]
1360 assert relationship["follows_you"] == false
1364 describe "GET /api/pleroma/search_user" do
1365 test "it returns users, ordered by similarity", %{conn: conn} do
1366 user = insert(:user, %{name: "eal"})
1367 user_two = insert(:user, %{name: "ean"})
1368 user_three = insert(:user, %{name: "ebn"})
1372 |> get(twitter_api_search__path(conn, :search_user), query: "eal")
1373 |> json_response(200)
1375 assert length(resp) == 3
1376 assert [user.id, user_two.id, user_three.id] == Enum.map(resp, fn %{"id" => id} -> id end)