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}
6 alias Pleroma.Web.ActivityPub.ActivityPub
7 alias Pleroma.Web.TwitterAPI.UserView
8 alias Pleroma.Web.CommonAPI
9 alias Pleroma.Web.TwitterAPI.TwitterAPI
11 import Pleroma.Factory
13 describe "POST /api/account/verify_credentials" do
16 test "without valid credentials", %{conn: conn} do
17 conn = post(conn, "/api/account/verify_credentials.json")
18 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
21 test "with credentials", %{conn: conn, user: user} do
24 |> with_credentials(user.nickname, "test")
25 |> post("/api/account/verify_credentials.json")
27 assert response = json_response(conn, 200)
28 assert response == UserView.render("show.json", %{user: user, token: response["token"]})
32 describe "POST /api/account/most_recent_notification" do
35 test "without valid credentials", %{conn: conn} do
36 conn = post(conn, "/api/account/most_recent_notification.json")
37 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
40 test "with credentials", %{conn: conn, user: user} do
43 |> with_credentials(user.nickname, "test")
44 |> post("/api/account/most_recent_notification.json", %{id: "200"})
46 assert json_response(conn, 200)
47 user = User.get_by_nickname(user.nickname)
48 assert user.info["most_recent_notification"] == 200
52 describe "POST /statuses/update.json" do
55 test "without valid credentials", %{conn: conn} do
56 conn = post(conn, "/api/statuses/update.json")
57 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
60 test "with credentials", %{conn: conn, user: user} do
61 conn_with_creds = conn |> with_credentials(user.nickname, "test")
62 request_path = "/api/statuses/update.json"
65 "request" => request_path,
66 "error" => "Client must provide a 'status' parameter with a value."
69 conn = conn_with_creds |> post(request_path)
70 assert json_response(conn, 400) == error_response
72 conn = conn_with_creds |> post(request_path, %{status: ""})
73 assert json_response(conn, 400) == error_response
75 conn = conn_with_creds |> post(request_path, %{status: " "})
76 assert json_response(conn, 400) == error_response
78 conn = conn_with_creds |> post(request_path, %{status: "Nice meme."})
80 assert json_response(conn, 200) ==
81 ActivityRepresenter.to_map(Repo.one(Activity), %{user: user})
85 describe "GET /statuses/public_timeline.json" do
86 test "returns statuses", %{conn: conn} do
87 {:ok, user} = UserBuilder.insert()
88 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
89 ActivityBuilder.insert_list(10, %{}, %{user: user})
90 since_id = List.last(activities).id
94 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
96 response = json_response(conn, 200)
98 assert length(response) == 10
102 describe "GET /statuses/show/:id.json" do
103 test "returns one status", %{conn: conn} do
105 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
106 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
110 |> get("/api/statuses/show/#{activity.id}.json")
112 response = json_response(conn, 200)
114 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
118 describe "GET /users/show.json" do
119 test "gets user with screen_name", %{conn: conn} do
124 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
126 response = json_response(conn, 200)
128 assert response["id"] == user.id
131 test "gets user with user_id", %{conn: conn} do
136 |> get("/api/users/show.json", %{"user_id" => user.id})
138 response = json_response(conn, 200)
140 assert response["id"] == user.id
143 test "gets a user for a logged in user", %{conn: conn} do
145 logged_in = insert(:user)
147 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
151 |> with_credentials(logged_in.nickname, "test")
152 |> get("/api/users/show.json", %{"user_id" => user.id})
154 response = json_response(conn, 200)
156 assert response["following"] == true
160 describe "GET /statusnet/conversation/:id.json" do
161 test "returns the statuses in the conversation", %{conn: conn} do
162 {:ok, _user} = UserBuilder.insert()
163 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
164 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
165 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
169 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
171 response = json_response(conn, 200)
173 assert length(response) == 2
177 describe "GET /statuses/friends_timeline.json" do
180 test "without valid credentials", %{conn: conn} do
181 conn = get(conn, "/api/statuses/friends_timeline.json")
182 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
185 test "with credentials", %{conn: conn, user: current_user} do
189 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
191 returned_activities =
192 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
194 other_user = insert(:user)
195 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
196 since_id = List.last(activities).id
199 Ecto.Changeset.change(current_user, following: [User.ap_followers(user)])
204 |> with_credentials(current_user.nickname, "test")
205 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
207 response = json_response(conn, 200)
209 assert length(response) == 10
212 Enum.map(returned_activities, fn activity ->
213 ActivityRepresenter.to_map(activity, %{
214 user: User.get_cached_by_ap_id(activity.data["actor"]),
221 describe "GET /statuses/mentions.json" do
224 test "without valid credentials", %{conn: conn} do
225 conn = get(conn, "/api/statuses/mentions.json")
226 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
229 test "with credentials", %{conn: conn, user: current_user} do
231 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
235 |> with_credentials(current_user.nickname, "test")
236 |> get("/api/statuses/mentions.json")
238 response = json_response(conn, 200)
240 assert length(response) == 1
242 assert Enum.at(response, 0) ==
243 ActivityRepresenter.to_map(activity, %{
245 mentioned: [current_user]
250 describe "GET /statuses/user_timeline.json" do
253 test "without any params", %{conn: conn} do
254 conn = get(conn, "/api/statuses/user_timeline.json")
256 assert json_response(conn, 400) == %{
257 "error" => "You need to specify screen_name or user_id",
258 "request" => "/api/statuses/user_timeline.json"
262 test "with user_id", %{conn: conn} do
264 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
266 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
267 response = json_response(conn, 200)
268 assert length(response) == 1
269 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
272 test "with screen_name", %{conn: conn} do
274 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
276 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
277 response = json_response(conn, 200)
278 assert length(response) == 1
279 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
282 test "with credentials", %{conn: conn, user: current_user} do
283 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
287 |> with_credentials(current_user.nickname, "test")
288 |> get("/api/statuses/user_timeline.json")
290 response = json_response(conn, 200)
292 assert length(response) == 1
293 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
296 test "with credentials with user_id", %{conn: conn, user: current_user} do
298 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
302 |> with_credentials(current_user.nickname, "test")
303 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
305 response = json_response(conn, 200)
307 assert length(response) == 1
308 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
311 test "with credentials screen_name", %{conn: conn, user: current_user} do
313 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
317 |> with_credentials(current_user.nickname, "test")
318 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
320 response = json_response(conn, 200)
322 assert length(response) == 1
323 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
327 describe "POST /friendships/create.json" do
330 test "without valid credentials", %{conn: conn} do
331 conn = post(conn, "/api/friendships/create.json")
332 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
335 test "with credentials", %{conn: conn, user: current_user} do
336 followed = insert(:user)
340 |> with_credentials(current_user.nickname, "test")
341 |> post("/api/friendships/create.json", %{user_id: followed.id})
343 current_user = Repo.get(User, current_user.id)
344 assert User.ap_followers(followed) in current_user.following
346 assert json_response(conn, 200) ==
347 UserView.render("show.json", %{user: followed, for: current_user})
351 describe "POST /friendships/destroy.json" do
354 test "without valid credentials", %{conn: conn} do
355 conn = post(conn, "/api/friendships/destroy.json")
356 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
359 test "with credentials", %{conn: conn, user: current_user} do
360 followed = insert(:user)
362 {:ok, current_user} = User.follow(current_user, followed)
363 assert User.ap_followers(followed) in current_user.following
364 ActivityPub.follow(current_user, followed)
368 |> with_credentials(current_user.nickname, "test")
369 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
371 current_user = Repo.get(User, current_user.id)
372 assert current_user.following == [current_user.ap_id]
374 assert json_response(conn, 200) ==
375 UserView.render("show.json", %{user: followed, for: current_user})
379 describe "POST /blocks/create.json" do
382 test "without valid credentials", %{conn: conn} do
383 conn = post(conn, "/api/blocks/create.json")
384 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
387 test "with credentials", %{conn: conn, user: current_user} do
388 blocked = insert(:user)
392 |> with_credentials(current_user.nickname, "test")
393 |> post("/api/blocks/create.json", %{user_id: blocked.id})
395 current_user = Repo.get(User, current_user.id)
396 assert User.blocks?(current_user, blocked)
398 assert json_response(conn, 200) ==
399 UserView.render("show.json", %{user: blocked, for: current_user})
403 describe "POST /blocks/destroy.json" do
406 test "without valid credentials", %{conn: conn} do
407 conn = post(conn, "/api/blocks/destroy.json")
408 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
411 test "with credentials", %{conn: conn, user: current_user} do
412 blocked = insert(:user)
414 {:ok, current_user} = User.block(current_user, blocked)
415 assert User.blocks?(current_user, blocked)
419 |> with_credentials(current_user.nickname, "test")
420 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
422 current_user = Repo.get(User, current_user.id)
423 assert current_user.info["blocks"] == []
425 assert json_response(conn, 200) ==
426 UserView.render("show.json", %{user: blocked, for: current_user})
430 describe "GET /help/test.json" do
431 test "returns \"ok\"", %{conn: conn} do
432 conn = get(conn, "/api/help/test.json")
433 assert json_response(conn, 200) == "ok"
437 describe "POST /api/qvitter/update_avatar.json" do
440 test "without valid credentials", %{conn: conn} do
441 conn = post(conn, "/api/qvitter/update_avatar.json")
442 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
445 test "with credentials", %{conn: conn, user: current_user} do
446 avatar_image = File.read!("test/fixtures/avatar_data_uri")
450 |> with_credentials(current_user.nickname, "test")
451 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
453 current_user = Repo.get(User, current_user.id)
454 assert is_map(current_user.avatar)
456 assert json_response(conn, 200) ==
457 UserView.render("show.json", %{user: current_user, for: current_user})
461 describe "POST /api/favorites/create/:id" do
464 test "without valid credentials", %{conn: conn} do
465 note_activity = insert(:note_activity)
466 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
467 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
470 test "with credentials", %{conn: conn, user: current_user} do
471 note_activity = insert(:note_activity)
475 |> with_credentials(current_user.nickname, "test")
476 |> post("/api/favorites/create/#{note_activity.id}.json")
478 assert json_response(conn, 200)
482 describe "POST /api/favorites/destroy/:id" do
485 test "without valid credentials", %{conn: conn} do
486 note_activity = insert(:note_activity)
487 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
488 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
491 test "with credentials", %{conn: conn, user: current_user} do
492 note_activity = insert(:note_activity)
493 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
494 ActivityPub.like(current_user, object)
498 |> with_credentials(current_user.nickname, "test")
499 |> post("/api/favorites/destroy/#{note_activity.id}.json")
501 assert json_response(conn, 200)
505 describe "POST /api/statuses/retweet/:id" do
508 test "without valid credentials", %{conn: conn} do
509 note_activity = insert(:note_activity)
510 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
511 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
514 test "with credentials", %{conn: conn, user: current_user} do
515 note_activity = insert(:note_activity)
517 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
521 |> with_credentials(current_user.nickname, "test")
522 |> post(request_path)
524 activity = Repo.get(Activity, note_activity.id)
525 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
527 assert json_response(response, 200) ==
528 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
532 describe "POST /api/account/register" do
533 test "it creates a new user", %{conn: conn} do
535 "nickname" => "lain",
536 "email" => "lain@wired.jp",
537 "fullname" => "lain iwakura",
538 "bio" => "close the world.",
539 "password" => "bear",
545 |> post("/api/account/register", data)
547 user = json_response(conn, 200)
549 fetched_user = Repo.get_by(User, nickname: "lain")
550 assert user == UserView.render("show.json", %{user: fetched_user})
553 test "it returns errors on a problem", %{conn: conn} do
555 "email" => "lain@wired.jp",
556 "fullname" => "lain iwakura",
557 "bio" => "close the world.",
558 "password" => "bear",
564 |> post("/api/account/register", data)
566 errors = json_response(conn, 400)
568 assert is_binary(errors["error"])
572 describe "GET /api/externalprofile/show" do
573 test "it returns the user", %{conn: conn} do
575 other_user = insert(:user)
579 |> assign(:user, user)
580 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
582 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
586 describe "GET /api/statuses/followers" do
587 test "it returns a user's followers", %{conn: conn} do
589 follower_one = insert(:user)
590 follower_two = insert(:user)
591 _not_follower = insert(:user)
593 {:ok, follower_one} = User.follow(follower_one, user)
594 {:ok, follower_two} = User.follow(follower_two, user)
598 |> assign(:user, user)
599 |> get("/api/statuses/followers")
601 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
602 result = json_response(conn, 200)
603 assert Enum.sort(expected) == Enum.sort(result)
607 describe "GET /api/statuses/friends" do
608 test "it returns the logged in user's friends", %{conn: conn} do
610 followed_one = insert(:user)
611 followed_two = insert(:user)
612 _not_followed = insert(:user)
614 {:ok, user} = User.follow(user, followed_one)
615 {:ok, user} = User.follow(user, followed_two)
619 |> assign(:user, user)
620 |> get("/api/statuses/friends")
622 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
623 result = json_response(conn, 200)
624 assert Enum.sort(expected) == Enum.sort(result)
627 test "it returns a given user's friends with user_id", %{conn: conn} do
629 followed_one = insert(:user)
630 followed_two = insert(:user)
631 _not_followed = insert(:user)
633 {:ok, user} = User.follow(user, followed_one)
634 {:ok, user} = User.follow(user, followed_two)
638 |> get("/api/statuses/friends", %{"user_id" => user.id})
640 assert MapSet.equal?(
641 MapSet.new(json_response(conn, 200)),
643 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
648 test "it returns a given user's friends with screen_name", %{conn: conn} do
650 followed_one = insert(:user)
651 followed_two = insert(:user)
652 _not_followed = insert(:user)
654 {:ok, user} = User.follow(user, followed_one)
655 {:ok, user} = User.follow(user, followed_two)
659 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
661 assert MapSet.equal?(
662 MapSet.new(json_response(conn, 200)),
664 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
670 describe "GET /friends/ids" do
671 test "it returns a user's friends", %{conn: conn} do
673 followed_one = insert(:user)
674 followed_two = insert(:user)
675 _not_followed = insert(:user)
677 {:ok, user} = User.follow(user, followed_one)
678 {:ok, user} = User.follow(user, followed_two)
682 |> assign(:user, user)
683 |> get("/api/friends/ids")
685 expected = [followed_one.id, followed_two.id]
687 assert MapSet.equal?(
688 MapSet.new(Poison.decode!(json_response(conn, 200))),
694 describe "POST /api/account/update_profile.json" do
695 test "it updates a user's profile", %{conn: conn} do
700 |> assign(:user, user)
701 |> post("/api/account/update_profile.json", %{
702 "name" => "new name",
703 "description" => "new description"
706 user = Repo.get!(User, user.id)
707 assert user.name == "new name"
708 assert user.bio == "new description"
710 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
714 defp valid_user(_context) do
719 defp with_credentials(conn, username, password) do
720 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
721 put_req_header(conn, "authorization", header_content)
724 describe "GET /api/search.json" do
725 test "it returns search results", %{conn: conn} do
727 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
729 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
730 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
734 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
736 assert [status] = json_response(conn, 200)
737 assert status["id"] == activity.id
741 describe "GET /api/statusnet/tags/timeline/:tag.json" do
742 test "it returns the tags timeline", %{conn: conn} do
744 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
746 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
747 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
751 |> get("/api/statusnet/tags/timeline/2hu.json")
753 assert [status] = json_response(conn, 200)
754 assert status["id"] == activity.id