1 defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
2 use Pleroma.Web.ConnCase
4 alias Pleroma.Web.TwitterAPI.TwitterAPI
5 alias Pleroma.{Repo, User, Activity, Notification}
6 alias Pleroma.Web.{OStatus, CommonAPI}
7 alias Pleroma.Web.ActivityPub.ActivityPub
10 import ExUnit.CaptureLog
14 mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
18 test "the home timeline", %{conn: conn} do
20 following = insert(:user)
22 {:ok, _activity} = TwitterAPI.create_status(following, %{"status" => "test"})
26 |> assign(:user, user)
27 |> get("/api/v1/timelines/home")
29 assert length(json_response(conn, 200)) == 0
31 {:ok, user} = User.follow(user, following)
35 |> assign(:user, user)
36 |> get("/api/v1/timelines/home")
38 assert [%{"content" => "test"}] = json_response(conn, 200)
41 test "the public timeline", %{conn: conn} do
42 following = insert(:user)
45 {:ok, _activity} = TwitterAPI.create_status(following, %{"status" => "test"})
48 OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
52 |> get("/api/v1/timelines/public", %{"local" => "False"})
54 assert length(json_response(conn, 200)) == 2
58 |> get("/api/v1/timelines/public", %{"local" => "True"})
60 assert [%{"content" => "test"}] = json_response(conn, 200)
64 |> get("/api/v1/timelines/public", %{"local" => "1"})
66 assert [%{"content" => "test"}] = json_response(conn, 200)
70 test "posting a status", %{conn: conn} do
73 idempotency_key = "Pikachu rocks!"
77 |> assign(:user, user)
78 |> put_req_header("idempotency-key", idempotency_key)
79 |> post("/api/v1/statuses", %{
81 "spoiler_text" => "2hu",
82 "sensitive" => "false"
85 {:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
87 assert ttl > :timer.seconds(6 * 60 * 60 - 1)
89 assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
90 json_response(conn_one, 200)
92 assert Repo.get(Activity, id)
96 |> assign(:user, user)
97 |> put_req_header("idempotency-key", idempotency_key)
98 |> post("/api/v1/statuses", %{
100 "spoiler_text" => "2hu",
101 "sensitive" => "false"
104 assert %{"id" => second_id} = json_response(conn_two, 200)
106 assert id == second_id
110 |> assign(:user, user)
111 |> post("/api/v1/statuses", %{
113 "spoiler_text" => "2hu",
114 "sensitive" => "false"
117 assert %{"id" => third_id} = json_response(conn_three, 200)
119 refute id == third_id
122 test "posting a sensitive status", %{conn: conn} do
127 |> assign(:user, user)
128 |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
130 assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200)
131 assert Repo.get(Activity, id)
134 test "posting a direct status", %{conn: conn} do
135 user1 = insert(:user)
136 user2 = insert(:user)
137 content = "direct cofe @#{user2.nickname}"
141 |> assign(:user, user1)
142 |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
144 assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200)
145 assert activity = Repo.get(Activity, id)
146 assert activity.recipients == [user2.ap_id]
147 assert activity.data["to"] == [user2.ap_id]
148 assert activity.data["cc"] == []
151 test "direct timeline", %{conn: conn} do
152 user_one = insert(:user)
153 user_two = insert(:user)
155 {:ok, user_two} = User.follow(user_two, user_one)
158 CommonAPI.post(user_one, %{
159 "status" => "Hi @#{user_two.nickname}!",
160 "visibility" => "direct"
163 {:ok, _follower_only} =
164 CommonAPI.post(user_one, %{
165 "status" => "Hi @#{user_two.nickname}!",
166 "visibility" => "private"
169 # Only direct should be visible here
172 |> assign(:user, user_two)
173 |> get("api/v1/timelines/direct")
175 [status] = json_response(res_conn, 200)
177 assert %{"visibility" => "direct"} = status
178 assert status["url"] != direct.data["id"]
180 # Both should be visible here
183 |> assign(:user, user_two)
184 |> get("api/v1/timelines/home")
186 [_s1, _s2] = json_response(res_conn, 200)
189 Enum.each(1..20, fn _ ->
191 CommonAPI.post(user_one, %{
192 "status" => "Hi @#{user_two.nickname}!",
193 "visibility" => "direct"
199 |> assign(:user, user_two)
200 |> get("api/v1/timelines/direct")
202 statuses = json_response(res_conn, 200)
203 assert length(statuses) == 20
207 |> assign(:user, user_two)
208 |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]})
210 [status] = json_response(res_conn, 200)
212 assert status["url"] != direct.data["id"]
215 test "replying to a status", %{conn: conn} do
218 {:ok, replied_to} = TwitterAPI.create_status(user, %{"status" => "cofe"})
222 |> assign(:user, user)
223 |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
225 assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
227 activity = Repo.get(Activity, id)
229 assert activity.data["context"] == replied_to.data["context"]
230 assert activity.data["object"]["inReplyToStatusId"] == replied_to.id
233 test "posting a status with an invalid in_reply_to_id", %{conn: conn} do
238 |> assign(:user, user)
239 |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""})
241 assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
243 activity = Repo.get(Activity, id)
248 test "verify_credentials", %{conn: conn} do
253 |> assign(:user, user)
254 |> get("/api/v1/accounts/verify_credentials")
256 assert %{"id" => id, "source" => %{"privacy" => "public"}} = json_response(conn, 200)
257 assert id == to_string(user.id)
260 test "verify_credentials default scope unlisted", %{conn: conn} do
261 user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}})
265 |> assign(:user, user)
266 |> get("/api/v1/accounts/verify_credentials")
268 assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
269 assert id == to_string(user.id)
272 test "get a status", %{conn: conn} do
273 activity = insert(:note_activity)
277 |> get("/api/v1/statuses/#{activity.id}")
279 assert %{"id" => id} = json_response(conn, 200)
280 assert id == to_string(activity.id)
283 describe "deleting a status" do
284 test "when you created it", %{conn: conn} do
285 activity = insert(:note_activity)
286 author = User.get_by_ap_id(activity.data["actor"])
290 |> assign(:user, author)
291 |> delete("/api/v1/statuses/#{activity.id}")
293 assert %{} = json_response(conn, 200)
295 assert Repo.get(Activity, activity.id) == nil
298 test "when you didn't create it", %{conn: conn} do
299 activity = insert(:note_activity)
304 |> assign(:user, user)
305 |> delete("/api/v1/statuses/#{activity.id}")
307 assert %{"error" => _} = json_response(conn, 403)
309 assert Repo.get(Activity, activity.id) == activity
313 describe "filters" do
314 test "creating a filter", %{conn: conn} do
317 filter = %Pleroma.Filter{
324 |> assign(:user, user)
325 |> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context})
327 assert response = json_response(conn, 200)
328 assert response["phrase"] == filter.phrase
329 assert response["context"] == filter.context
330 assert response["id"] != nil
331 assert response["id"] != ""
334 test "fetching a list of filters", %{conn: conn} do
337 query_one = %Pleroma.Filter{
344 query_two = %Pleroma.Filter{
351 {:ok, filter_one} = Pleroma.Filter.create(query_one)
352 {:ok, filter_two} = Pleroma.Filter.create(query_two)
356 |> assign(:user, user)
357 |> get("/api/v1/filters")
359 assert response = json_response(conn, 200)
362 test "get a filter", %{conn: conn} do
365 query = %Pleroma.Filter{
372 {:ok, filter} = Pleroma.Filter.create(query)
376 |> assign(:user, user)
377 |> get("/api/v1/filters/#{filter.filter_id}")
379 assert response = json_response(conn, 200)
382 test "update a filter", %{conn: conn} do
385 query = %Pleroma.Filter{
392 {:ok, filter} = Pleroma.Filter.create(query)
394 new = %Pleroma.Filter{
401 |> assign(:user, user)
402 |> put("/api/v1/filters/#{query.filter_id}", %{
407 assert response = json_response(conn, 200)
408 assert response["phrase"] == new.phrase
409 assert response["context"] == new.context
412 test "delete a filter", %{conn: conn} do
415 query = %Pleroma.Filter{
422 {:ok, filter} = Pleroma.Filter.create(query)
426 |> assign(:user, user)
427 |> delete("/api/v1/filters/#{filter.filter_id}")
429 assert response = json_response(conn, 200)
430 assert response == %{}
435 test "creating a list", %{conn: conn} do
440 |> assign(:user, user)
441 |> post("/api/v1/lists", %{"title" => "cuties"})
443 assert %{"title" => title} = json_response(conn, 200)
444 assert title == "cuties"
447 test "adding users to a list", %{conn: conn} do
449 other_user = insert(:user)
450 {:ok, list} = Pleroma.List.create("name", user)
454 |> assign(:user, user)
455 |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
457 assert %{} == json_response(conn, 200)
458 %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
459 assert following == [other_user.follower_address]
462 test "removing users from a list", %{conn: conn} do
464 other_user = insert(:user)
465 third_user = insert(:user)
466 {:ok, list} = Pleroma.List.create("name", user)
467 {:ok, list} = Pleroma.List.follow(list, other_user)
468 {:ok, list} = Pleroma.List.follow(list, third_user)
472 |> assign(:user, user)
473 |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
475 assert %{} == json_response(conn, 200)
476 %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
477 assert following == [third_user.follower_address]
480 test "listing users in a list", %{conn: conn} do
482 other_user = insert(:user)
483 {:ok, list} = Pleroma.List.create("name", user)
484 {:ok, list} = Pleroma.List.follow(list, other_user)
488 |> assign(:user, user)
489 |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
491 assert [%{"id" => id}] = json_response(conn, 200)
492 assert id == to_string(other_user.id)
495 test "retrieving a list", %{conn: conn} do
497 {:ok, list} = Pleroma.List.create("name", user)
501 |> assign(:user, user)
502 |> get("/api/v1/lists/#{list.id}")
504 assert %{"id" => id} = json_response(conn, 200)
505 assert id == to_string(list.id)
508 test "renaming a list", %{conn: conn} do
510 {:ok, list} = Pleroma.List.create("name", user)
514 |> assign(:user, user)
515 |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"})
517 assert %{"title" => name} = json_response(conn, 200)
518 assert name == "newname"
521 test "deleting a list", %{conn: conn} do
523 {:ok, list} = Pleroma.List.create("name", user)
527 |> assign(:user, user)
528 |> delete("/api/v1/lists/#{list.id}")
530 assert %{} = json_response(conn, 200)
531 assert is_nil(Repo.get(Pleroma.List, list.id))
534 test "list timeline", %{conn: conn} do
536 other_user = insert(:user)
537 {:ok, _activity_one} = TwitterAPI.create_status(user, %{"status" => "Marisa is cute."})
538 {:ok, activity_two} = TwitterAPI.create_status(other_user, %{"status" => "Marisa is cute."})
539 {:ok, list} = Pleroma.List.create("name", user)
540 {:ok, list} = Pleroma.List.follow(list, other_user)
544 |> assign(:user, user)
545 |> get("/api/v1/timelines/list/#{list.id}")
547 assert [%{"id" => id}] = json_response(conn, 200)
549 assert id == to_string(activity_two.id)
552 test "list timeline does not leak non-public statuses for unfollowed users", %{conn: conn} do
554 other_user = insert(:user)
555 {:ok, activity_one} = TwitterAPI.create_status(other_user, %{"status" => "Marisa is cute."})
557 {:ok, activity_two} =
558 TwitterAPI.create_status(other_user, %{
559 "status" => "Marisa is cute.",
560 "visibility" => "private"
563 {:ok, list} = Pleroma.List.create("name", user)
564 {:ok, list} = Pleroma.List.follow(list, other_user)
568 |> assign(:user, user)
569 |> get("/api/v1/timelines/list/#{list.id}")
571 assert [%{"id" => id}] = json_response(conn, 200)
573 assert id == to_string(activity_one.id)
577 describe "notifications" do
578 test "list of notifications", %{conn: conn} do
580 other_user = insert(:user)
583 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
585 {:ok, [_notification]} = Notification.create_notifications(activity)
589 |> assign(:user, user)
590 |> get("/api/v1/notifications")
593 "hi <span><a data-user=\"#{user.id}\" href=\"#{user.ap_id}\">@<span>#{user.nickname}</span></a></span>"
595 assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
596 assert response == expected_response
599 test "getting a single notification", %{conn: conn} do
601 other_user = insert(:user)
604 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
606 {:ok, [notification]} = Notification.create_notifications(activity)
610 |> assign(:user, user)
611 |> get("/api/v1/notifications/#{notification.id}")
614 "hi <span><a data-user=\"#{user.id}\" href=\"#{user.ap_id}\">@<span>#{user.nickname}</span></a></span>"
616 assert %{"status" => %{"content" => response}} = json_response(conn, 200)
617 assert response == expected_response
620 test "dismissing a single notification", %{conn: conn} do
622 other_user = insert(:user)
625 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
627 {:ok, [notification]} = Notification.create_notifications(activity)
631 |> assign(:user, user)
632 |> post("/api/v1/notifications/dismiss", %{"id" => notification.id})
634 assert %{} = json_response(conn, 200)
637 test "clearing all notifications", %{conn: conn} do
639 other_user = insert(:user)
642 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
644 {:ok, [_notification]} = Notification.create_notifications(activity)
648 |> assign(:user, user)
649 |> post("/api/v1/notifications/clear")
651 assert %{} = json_response(conn, 200)
655 |> assign(:user, user)
656 |> get("/api/v1/notifications")
658 assert all = json_response(conn, 200)
663 describe "reblogging" do
664 test "reblogs and returns the reblogged status", %{conn: conn} do
665 activity = insert(:note_activity)
670 |> assign(:user, user)
671 |> post("/api/v1/statuses/#{activity.id}/reblog")
673 assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} =
674 json_response(conn, 200)
676 assert to_string(activity.id) == id
680 describe "unreblogging" do
681 test "unreblogs and returns the unreblogged status", %{conn: conn} do
682 activity = insert(:note_activity)
685 {:ok, _, _} = CommonAPI.repeat(activity.id, user)
689 |> assign(:user, user)
690 |> post("/api/v1/statuses/#{activity.id}/unreblog")
692 assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200)
694 assert to_string(activity.id) == id
698 describe "favoriting" do
699 test "favs a status and returns it", %{conn: conn} do
700 activity = insert(:note_activity)
705 |> assign(:user, user)
706 |> post("/api/v1/statuses/#{activity.id}/favourite")
708 assert %{"id" => id, "favourites_count" => 1, "favourited" => true} =
709 json_response(conn, 200)
711 assert to_string(activity.id) == id
714 test "returns 500 for a wrong id", %{conn: conn} do
719 |> assign(:user, user)
720 |> post("/api/v1/statuses/1/favourite")
721 |> json_response(500)
723 assert resp == "Something went wrong"
727 describe "unfavoriting" do
728 test "unfavorites a status and returns it", %{conn: conn} do
729 activity = insert(:note_activity)
732 {:ok, _, _} = CommonAPI.favorite(activity.id, user)
736 |> assign(:user, user)
737 |> post("/api/v1/statuses/#{activity.id}/unfavourite")
739 assert %{"id" => id, "favourites_count" => 0, "favourited" => false} =
740 json_response(conn, 200)
742 assert to_string(activity.id) == id
746 describe "user timelines" do
747 test "gets a users statuses", %{conn: conn} do
748 user_one = insert(:user)
749 user_two = insert(:user)
750 user_three = insert(:user)
752 {:ok, user_three} = User.follow(user_three, user_one)
754 {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})
756 {:ok, direct_activity} =
757 CommonAPI.post(user_one, %{
758 "status" => "Hi, @#{user_two.nickname}.",
759 "visibility" => "direct"
762 {:ok, private_activity} =
763 CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})
767 |> get("/api/v1/accounts/#{user_one.id}/statuses")
769 assert [%{"id" => id}] = json_response(resp, 200)
770 assert id == to_string(activity.id)
774 |> assign(:user, user_two)
775 |> get("/api/v1/accounts/#{user_one.id}/statuses")
777 assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
778 assert id_one == to_string(direct_activity.id)
779 assert id_two == to_string(activity.id)
783 |> assign(:user, user_three)
784 |> get("/api/v1/accounts/#{user_one.id}/statuses")
786 assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
787 assert id_one == to_string(private_activity.id)
788 assert id_two == to_string(activity.id)
791 test "unimplemented pinned statuses feature", %{conn: conn} do
792 note = insert(:note_activity)
793 user = User.get_by_ap_id(note.data["actor"])
797 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
799 assert json_response(conn, 200) == []
802 test "gets an users media", %{conn: conn} do
803 note = insert(:note_activity)
804 user = User.get_by_ap_id(note.data["actor"])
807 content_type: "image/jpg",
808 path: Path.absname("test/fixtures/image.jpg"),
809 filename: "an_image.jpg"
813 TwitterAPI.upload(file, "json")
817 TwitterAPI.create_status(user, %{"status" => "cofe", "media_ids" => [media["media_id"]]})
821 |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
823 assert [%{"id" => id}] = json_response(conn, 200)
824 assert id == to_string(image_post.id)
828 |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
830 assert [%{"id" => id}] = json_response(conn, 200)
831 assert id == to_string(image_post.id)
835 describe "user relationships" do
836 test "returns the relationships for the current user", %{conn: conn} do
838 other_user = insert(:user)
839 {:ok, user} = User.follow(user, other_user)
843 |> assign(:user, user)
844 |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
846 assert [relationship] = json_response(conn, 200)
848 assert to_string(other_user.id) == relationship["id"]
852 describe "locked accounts" do
853 test "/api/v1/follow_requests works" do
854 user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
855 other_user = insert(:user)
857 {:ok, activity} = ActivityPub.follow(other_user, user)
859 user = Repo.get(User, user.id)
860 other_user = Repo.get(User, other_user.id)
862 assert User.following?(other_user, user) == false
866 |> assign(:user, user)
867 |> get("/api/v1/follow_requests")
869 assert [relationship] = json_response(conn, 200)
870 assert to_string(other_user.id) == relationship["id"]
873 test "/api/v1/follow_requests/:id/authorize works" do
874 user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
875 other_user = insert(:user)
877 {:ok, activity} = ActivityPub.follow(other_user, user)
879 user = Repo.get(User, user.id)
880 other_user = Repo.get(User, other_user.id)
882 assert User.following?(other_user, user) == false
886 |> assign(:user, user)
887 |> post("/api/v1/follow_requests/#{other_user.id}/authorize")
889 assert relationship = json_response(conn, 200)
890 assert to_string(other_user.id) == relationship["id"]
892 user = Repo.get(User, user.id)
893 other_user = Repo.get(User, other_user.id)
895 assert User.following?(other_user, user) == true
898 test "verify_credentials", %{conn: conn} do
899 user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}})
903 |> assign(:user, user)
904 |> get("/api/v1/accounts/verify_credentials")
906 assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
907 assert id == to_string(user.id)
910 test "/api/v1/follow_requests/:id/reject works" do
911 user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
912 other_user = insert(:user)
914 {:ok, activity} = ActivityPub.follow(other_user, user)
918 |> assign(:user, user)
919 |> post("/api/v1/follow_requests/#{other_user.id}/reject")
921 assert relationship = json_response(conn, 200)
922 assert to_string(other_user.id) == relationship["id"]
924 user = Repo.get(User, user.id)
925 other_user = Repo.get(User, other_user.id)
927 assert User.following?(other_user, user) == false
931 test "account fetching", %{conn: conn} do
936 |> get("/api/v1/accounts/#{user.id}")
938 assert %{"id" => id} = json_response(conn, 200)
939 assert id == to_string(user.id)
943 |> get("/api/v1/accounts/-1")
945 assert %{"error" => "Can't find user"} = json_response(conn, 404)
948 test "media upload", %{conn: conn} do
950 content_type: "image/jpg",
951 path: Path.absname("test/fixtures/image.jpg"),
952 filename: "an_image.jpg"
955 desc = "Description of the image"
961 |> assign(:user, user)
962 |> post("/api/v1/media", %{"file" => file, "description" => desc})
964 assert media = json_response(conn, 200)
966 assert media["type"] == "image"
967 assert media["description"] == desc
970 test "hashtag timeline", %{conn: conn} do
971 following = insert(:user)
974 {:ok, activity} = TwitterAPI.create_status(following, %{"status" => "test #2hu"})
977 OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
981 |> get("/api/v1/timelines/tag/2hu")
983 assert [%{"id" => id}] = json_response(nconn, 200)
985 assert id == to_string(activity.id)
987 # works for different capitalization too
990 |> get("/api/v1/timelines/tag/2HU")
992 assert [%{"id" => id}] = json_response(nconn, 200)
994 assert id == to_string(activity.id)
998 test "getting followers", %{conn: conn} do
1000 other_user = insert(:user)
1001 {:ok, user} = User.follow(user, other_user)
1005 |> get("/api/v1/accounts/#{other_user.id}/followers")
1007 assert [%{"id" => id}] = json_response(conn, 200)
1008 assert id == to_string(user.id)
1011 test "getting followers, hide_network", %{conn: conn} do
1012 user = insert(:user)
1013 other_user = insert(:user, %{info: %{hide_network: true}})
1014 {:ok, user} = User.follow(user, other_user)
1018 |> get("/api/v1/accounts/#{other_user.id}/followers")
1020 assert [] == json_response(conn, 200)
1023 test "getting followers, hide_network, same user requesting", %{conn: conn} do
1024 user = insert(:user)
1025 other_user = insert(:user, %{info: %{hide_network: true}})
1026 {:ok, user} = User.follow(user, other_user)
1030 |> assign(:user, other_user)
1031 |> get("/api/v1/accounts/#{other_user.id}/followers")
1033 refute [] == json_response(conn, 200)
1036 test "getting following", %{conn: conn} do
1037 user = insert(:user)
1038 other_user = insert(:user)
1039 {:ok, user} = User.follow(user, other_user)
1043 |> get("/api/v1/accounts/#{user.id}/following")
1045 assert [%{"id" => id}] = json_response(conn, 200)
1046 assert id == to_string(other_user.id)
1049 test "getting following, hide_network", %{conn: conn} do
1050 user = insert(:user, %{info: %{hide_network: true}})
1051 other_user = insert(:user)
1052 {:ok, user} = User.follow(user, other_user)
1056 |> get("/api/v1/accounts/#{user.id}/following")
1058 assert [] == json_response(conn, 200)
1061 test "getting following, hide_network, same user requesting", %{conn: conn} do
1062 user = insert(:user, %{info: %{hide_network: true}})
1063 other_user = insert(:user)
1064 {:ok, user} = User.follow(user, other_user)
1068 |> assign(:user, user)
1069 |> get("/api/v1/accounts/#{user.id}/following")
1071 refute [] == json_response(conn, 200)
1074 test "following / unfollowing a user", %{conn: conn} do
1075 user = insert(:user)
1076 other_user = insert(:user)
1080 |> assign(:user, user)
1081 |> post("/api/v1/accounts/#{other_user.id}/follow")
1083 assert %{"id" => _id, "following" => true} = json_response(conn, 200)
1085 user = Repo.get(User, user.id)
1089 |> assign(:user, user)
1090 |> post("/api/v1/accounts/#{other_user.id}/unfollow")
1092 assert %{"id" => _id, "following" => false} = json_response(conn, 200)
1094 user = Repo.get(User, user.id)
1098 |> assign(:user, user)
1099 |> post("/api/v1/follows", %{"uri" => other_user.nickname})
1101 assert %{"id" => id} = json_response(conn, 200)
1102 assert id == to_string(other_user.id)
1105 test "blocking / unblocking a user", %{conn: conn} do
1106 user = insert(:user)
1107 other_user = insert(:user)
1111 |> assign(:user, user)
1112 |> post("/api/v1/accounts/#{other_user.id}/block")
1114 assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
1116 user = Repo.get(User, user.id)
1120 |> assign(:user, user)
1121 |> post("/api/v1/accounts/#{other_user.id}/unblock")
1123 assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
1126 test "getting a list of blocks", %{conn: conn} do
1127 user = insert(:user)
1128 other_user = insert(:user)
1130 {:ok, user} = User.block(user, other_user)
1134 |> assign(:user, user)
1135 |> get("/api/v1/blocks")
1137 other_user_id = to_string(other_user.id)
1138 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
1141 test "blocking / unblocking a domain", %{conn: conn} do
1142 user = insert(:user)
1143 other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
1147 |> assign(:user, user)
1148 |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
1150 assert %{} = json_response(conn, 200)
1151 user = User.get_cached_by_ap_id(user.ap_id)
1152 assert User.blocks?(user, other_user)
1156 |> assign(:user, user)
1157 |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
1159 assert %{} = json_response(conn, 200)
1160 user = User.get_cached_by_ap_id(user.ap_id)
1161 refute User.blocks?(user, other_user)
1164 test "getting a list of domain blocks", %{conn: conn} do
1165 user = insert(:user)
1167 {:ok, user} = User.block_domain(user, "bad.site")
1168 {:ok, user} = User.block_domain(user, "even.worse.site")
1172 |> assign(:user, user)
1173 |> get("/api/v1/domain_blocks")
1175 domain_blocks = json_response(conn, 200)
1177 assert "bad.site" in domain_blocks
1178 assert "even.worse.site" in domain_blocks
1181 test "unimplemented mute endpoints" do
1182 user = insert(:user)
1183 other_user = insert(:user)
1186 |> Enum.each(fn endpoint ->
1189 |> assign(:user, user)
1190 |> post("/api/v1/accounts/#{other_user.id}/#{endpoint}")
1192 assert %{"id" => id} = json_response(conn, 200)
1193 assert id == to_string(other_user.id)
1197 test "unimplemented mutes, follow_requests, blocks, domain blocks" do
1198 user = insert(:user)
1200 ["blocks", "domain_blocks", "mutes", "follow_requests"]
1201 |> Enum.each(fn endpoint ->
1204 |> assign(:user, user)
1205 |> get("/api/v1/#{endpoint}")
1207 assert [] = json_response(conn, 200)
1211 test "account search", %{conn: conn} do
1212 user = insert(:user)
1213 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1214 user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
1218 |> assign(:user, user)
1219 |> get("/api/v1/accounts/search", %{"q" => "shp"})
1220 |> json_response(200)
1222 result_ids = for result <- results, do: result["acct"]
1224 assert user_two.nickname in result_ids
1225 assert user_three.nickname in result_ids
1229 |> assign(:user, user)
1230 |> get("/api/v1/accounts/search", %{"q" => "2hu"})
1231 |> json_response(200)
1233 result_ids = for result <- results, do: result["acct"]
1235 assert user_three.nickname in result_ids
1238 test "search", %{conn: conn} do
1239 user = insert(:user)
1240 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1241 user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
1243 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1246 CommonAPI.post(user, %{
1247 "status" => "This is about 2hu, but private",
1248 "visibility" => "private"
1251 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1255 |> get("/api/v1/search", %{"q" => "2hu"})
1257 assert results = json_response(conn, 200)
1259 [account | _] = results["accounts"]
1260 assert account["id"] == to_string(user_three.id)
1262 assert results["hashtags"] == []
1264 [status] = results["statuses"]
1265 assert status["id"] == to_string(activity.id)
1268 test "search fetches remote statuses", %{conn: conn} do
1272 |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"})
1274 assert results = json_response(conn, 200)
1276 [status] = results["statuses"]
1277 assert status["uri"] == "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
1281 test "search fetches remote accounts", %{conn: conn} do
1284 |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"})
1286 assert results = json_response(conn, 200)
1287 [account] = results["accounts"]
1288 assert account["acct"] == "shp@social.heldscal.la"
1291 test "returns the favorites of a user", %{conn: conn} do
1292 user = insert(:user)
1293 other_user = insert(:user)
1295 {:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"})
1296 {:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"})
1298 {:ok, _, _} = CommonAPI.favorite(activity.id, user)
1302 |> assign(:user, user)
1303 |> get("/api/v1/favourites")
1305 assert [status] = json_response(conn, 200)
1306 assert status["id"] == to_string(activity.id)
1309 describe "updating credentials" do
1310 test "updates the user's bio", %{conn: conn} do
1311 user = insert(:user)
1312 user2 = insert(:user)
1316 |> assign(:user, user)
1317 |> patch("/api/v1/accounts/update_credentials", %{
1318 "note" => "I drink #cofe with @#{user2.nickname}"
1321 assert user = json_response(conn, 200)
1323 assert user["note"] ==
1324 "I drink <a data-tag=\"cofe\" href=\"http://localhost:4001/tag/cofe\">#cofe</a> with <span><a data-user=\"#{
1326 }\" href=\"#{user2.ap_id}\">@<span>#{user2.nickname}</span></a></span>"
1329 test "updates the user's locking status", %{conn: conn} do
1330 user = insert(:user)
1334 |> assign(:user, user)
1335 |> patch("/api/v1/accounts/update_credentials", %{locked: "true"})
1337 assert user = json_response(conn, 200)
1338 assert user["locked"] == true
1341 test "updates the user's name", %{conn: conn} do
1342 user = insert(:user)
1346 |> assign(:user, user)
1347 |> patch("/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
1349 assert user = json_response(conn, 200)
1350 assert user["display_name"] == "markorepairs"
1353 test "updates the user's avatar", %{conn: conn} do
1354 user = insert(:user)
1356 new_avatar = %Plug.Upload{
1357 content_type: "image/jpg",
1358 path: Path.absname("test/fixtures/image.jpg"),
1359 filename: "an_image.jpg"
1364 |> assign(:user, user)
1365 |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
1367 assert user_response = json_response(conn, 200)
1368 assert user_response["avatar"] != User.avatar_url(user)
1371 test "updates the user's banner", %{conn: conn} do
1372 user = insert(:user)
1374 new_header = %Plug.Upload{
1375 content_type: "image/jpg",
1376 path: Path.absname("test/fixtures/image.jpg"),
1377 filename: "an_image.jpg"
1382 |> assign(:user, user)
1383 |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
1385 assert user_response = json_response(conn, 200)
1386 assert user_response["header"] != User.banner_url(user)
1390 test "get instance information", %{conn: conn} do
1391 insert(:user, %{local: true})
1392 user = insert(:user, %{local: true})
1393 insert(:user, %{local: false})
1395 {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"})
1397 Pleroma.Stats.update_stats()
1401 |> get("/api/v1/instance")
1403 assert result = json_response(conn, 200)
1405 assert result["stats"]["user_count"] == 2
1406 assert result["stats"]["status_count"] == 1