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"})
167 {:ok, object} = Object.context_mapping("2hu") |> Repo.insert()
171 |> get("/api/statusnet/conversation/#{object.id}.json")
173 response = json_response(conn, 200)
175 assert length(response) == 2
179 describe "GET /statuses/friends_timeline.json" do
182 test "without valid credentials", %{conn: conn} do
183 conn = get(conn, "/api/statuses/friends_timeline.json")
184 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
187 test "with credentials", %{conn: conn, user: current_user} do
191 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
193 returned_activities =
194 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
196 other_user = insert(:user)
197 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
198 since_id = List.last(activities).id
201 Ecto.Changeset.change(current_user, following: [User.ap_followers(user)])
206 |> with_credentials(current_user.nickname, "test")
207 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
209 response = json_response(conn, 200)
211 assert length(response) == 10
214 Enum.map(returned_activities, fn activity ->
215 ActivityRepresenter.to_map(activity, %{
216 user: User.get_cached_by_ap_id(activity.data["actor"]),
223 describe "GET /statuses/mentions.json" do
226 test "without valid credentials", %{conn: conn} do
227 conn = get(conn, "/api/statuses/mentions.json")
228 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
231 test "with credentials", %{conn: conn, user: current_user} do
233 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
237 |> with_credentials(current_user.nickname, "test")
238 |> get("/api/statuses/mentions.json")
240 response = json_response(conn, 200)
242 assert length(response) == 1
244 assert Enum.at(response, 0) ==
245 ActivityRepresenter.to_map(activity, %{
247 mentioned: [current_user]
252 describe "GET /statuses/user_timeline.json" do
255 test "without any params", %{conn: conn} do
256 conn = get(conn, "/api/statuses/user_timeline.json")
258 assert json_response(conn, 400) == %{
259 "error" => "You need to specify screen_name or user_id",
260 "request" => "/api/statuses/user_timeline.json"
264 test "with user_id", %{conn: conn} do
266 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
268 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
269 response = json_response(conn, 200)
270 assert length(response) == 1
271 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
274 test "with screen_name", %{conn: conn} do
276 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
278 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
279 response = json_response(conn, 200)
280 assert length(response) == 1
281 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
284 test "with credentials", %{conn: conn, user: current_user} do
285 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
289 |> with_credentials(current_user.nickname, "test")
290 |> get("/api/statuses/user_timeline.json")
292 response = json_response(conn, 200)
294 assert length(response) == 1
295 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
298 test "with credentials with user_id", %{conn: conn, user: current_user} do
300 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
304 |> with_credentials(current_user.nickname, "test")
305 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
307 response = json_response(conn, 200)
309 assert length(response) == 1
310 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
313 test "with credentials screen_name", %{conn: conn, user: current_user} do
315 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
319 |> with_credentials(current_user.nickname, "test")
320 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
322 response = json_response(conn, 200)
324 assert length(response) == 1
325 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
329 describe "POST /friendships/create.json" do
332 test "without valid credentials", %{conn: conn} do
333 conn = post(conn, "/api/friendships/create.json")
334 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
337 test "with credentials", %{conn: conn, user: current_user} do
338 followed = insert(:user)
342 |> with_credentials(current_user.nickname, "test")
343 |> post("/api/friendships/create.json", %{user_id: followed.id})
345 current_user = Repo.get(User, current_user.id)
346 assert User.ap_followers(followed) in current_user.following
348 assert json_response(conn, 200) ==
349 UserView.render("show.json", %{user: followed, for: current_user})
353 describe "POST /friendships/destroy.json" do
356 test "without valid credentials", %{conn: conn} do
357 conn = post(conn, "/api/friendships/destroy.json")
358 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
361 test "with credentials", %{conn: conn, user: current_user} do
362 followed = insert(:user)
364 {:ok, current_user} = User.follow(current_user, followed)
365 assert User.ap_followers(followed) in current_user.following
366 ActivityPub.follow(current_user, followed)
370 |> with_credentials(current_user.nickname, "test")
371 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
373 current_user = Repo.get(User, current_user.id)
374 assert current_user.following == [current_user.ap_id]
376 assert json_response(conn, 200) ==
377 UserView.render("show.json", %{user: followed, for: current_user})
381 describe "POST /blocks/create.json" do
384 test "without valid credentials", %{conn: conn} do
385 conn = post(conn, "/api/blocks/create.json")
386 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
389 test "with credentials", %{conn: conn, user: current_user} do
390 blocked = insert(:user)
394 |> with_credentials(current_user.nickname, "test")
395 |> post("/api/blocks/create.json", %{user_id: blocked.id})
397 current_user = Repo.get(User, current_user.id)
398 assert User.blocks?(current_user, blocked)
400 assert json_response(conn, 200) ==
401 UserView.render("show.json", %{user: blocked, for: current_user})
405 describe "POST /blocks/destroy.json" do
408 test "without valid credentials", %{conn: conn} do
409 conn = post(conn, "/api/blocks/destroy.json")
410 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
413 test "with credentials", %{conn: conn, user: current_user} do
414 blocked = insert(:user)
416 {:ok, current_user} = User.block(current_user, blocked)
417 assert User.blocks?(current_user, blocked)
421 |> with_credentials(current_user.nickname, "test")
422 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
424 current_user = Repo.get(User, current_user.id)
425 assert current_user.info["blocks"] == []
427 assert json_response(conn, 200) ==
428 UserView.render("show.json", %{user: blocked, for: current_user})
432 describe "GET /help/test.json" do
433 test "returns \"ok\"", %{conn: conn} do
434 conn = get(conn, "/api/help/test.json")
435 assert json_response(conn, 200) == "ok"
439 describe "POST /api/qvitter/update_avatar.json" do
442 test "without valid credentials", %{conn: conn} do
443 conn = post(conn, "/api/qvitter/update_avatar.json")
444 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
447 test "with credentials", %{conn: conn, user: current_user} do
448 avatar_image = File.read!("test/fixtures/avatar_data_uri")
452 |> with_credentials(current_user.nickname, "test")
453 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
455 current_user = Repo.get(User, current_user.id)
456 assert is_map(current_user.avatar)
458 assert json_response(conn, 200) ==
459 UserView.render("show.json", %{user: current_user, for: current_user})
463 describe "POST /api/favorites/create/:id" do
466 test "without valid credentials", %{conn: conn} do
467 note_activity = insert(:note_activity)
468 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
469 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
472 test "with credentials", %{conn: conn, user: current_user} do
473 note_activity = insert(:note_activity)
477 |> with_credentials(current_user.nickname, "test")
478 |> post("/api/favorites/create/#{note_activity.id}.json")
480 assert json_response(conn, 200)
484 describe "POST /api/favorites/destroy/:id" do
487 test "without valid credentials", %{conn: conn} do
488 note_activity = insert(:note_activity)
489 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
490 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
493 test "with credentials", %{conn: conn, user: current_user} do
494 note_activity = insert(:note_activity)
495 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
496 ActivityPub.like(current_user, object)
500 |> with_credentials(current_user.nickname, "test")
501 |> post("/api/favorites/destroy/#{note_activity.id}.json")
503 assert json_response(conn, 200)
507 describe "POST /api/statuses/retweet/:id" do
510 test "without valid credentials", %{conn: conn} do
511 note_activity = insert(:note_activity)
512 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
513 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
516 test "with credentials", %{conn: conn, user: current_user} do
517 note_activity = insert(:note_activity)
519 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
523 |> with_credentials(current_user.nickname, "test")
524 |> post(request_path)
526 activity = Repo.get(Activity, note_activity.id)
527 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
529 assert json_response(response, 200) ==
530 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
534 describe "POST /api/account/register" do
535 test "it creates a new user", %{conn: conn} do
537 "nickname" => "lain",
538 "email" => "lain@wired.jp",
539 "fullname" => "lain iwakura",
540 "bio" => "close the world.",
541 "password" => "bear",
547 |> post("/api/account/register", data)
549 user = json_response(conn, 200)
551 fetched_user = Repo.get_by(User, nickname: "lain")
552 assert user == UserView.render("show.json", %{user: fetched_user})
555 test "it returns errors on a problem", %{conn: conn} do
557 "email" => "lain@wired.jp",
558 "fullname" => "lain iwakura",
559 "bio" => "close the world.",
560 "password" => "bear",
566 |> post("/api/account/register", data)
568 errors = json_response(conn, 400)
570 assert is_binary(errors["error"])
574 describe "GET /api/externalprofile/show" do
575 test "it returns the user", %{conn: conn} do
577 other_user = insert(:user)
581 |> assign(:user, user)
582 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
584 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
588 describe "GET /api/statuses/followers" do
589 test "it returns a user's followers", %{conn: conn} do
591 follower_one = insert(:user)
592 follower_two = insert(:user)
593 _not_follower = insert(:user)
595 {:ok, follower_one} = User.follow(follower_one, user)
596 {:ok, follower_two} = User.follow(follower_two, user)
600 |> assign(:user, user)
601 |> get("/api/statuses/followers")
603 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
604 result = json_response(conn, 200)
605 assert Enum.sort(expected) == Enum.sort(result)
609 describe "GET /api/statuses/friends" do
610 test "it returns the logged in user's friends", %{conn: conn} do
612 followed_one = insert(:user)
613 followed_two = insert(:user)
614 _not_followed = insert(:user)
616 {:ok, user} = User.follow(user, followed_one)
617 {:ok, user} = User.follow(user, followed_two)
621 |> assign(:user, user)
622 |> get("/api/statuses/friends")
624 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
625 result = json_response(conn, 200)
626 assert Enum.sort(expected) == Enum.sort(result)
629 test "it returns a given user's friends with user_id", %{conn: conn} do
631 followed_one = insert(:user)
632 followed_two = insert(:user)
633 _not_followed = insert(:user)
635 {:ok, user} = User.follow(user, followed_one)
636 {:ok, user} = User.follow(user, followed_two)
640 |> get("/api/statuses/friends", %{"user_id" => user.id})
642 assert MapSet.equal?(
643 MapSet.new(json_response(conn, 200)),
645 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
650 test "it returns a given user's friends with screen_name", %{conn: conn} do
652 followed_one = insert(:user)
653 followed_two = insert(:user)
654 _not_followed = insert(:user)
656 {:ok, user} = User.follow(user, followed_one)
657 {:ok, user} = User.follow(user, followed_two)
661 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
663 assert MapSet.equal?(
664 MapSet.new(json_response(conn, 200)),
666 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
672 describe "GET /friends/ids" do
673 test "it returns a user's friends", %{conn: conn} do
675 followed_one = insert(:user)
676 followed_two = insert(:user)
677 _not_followed = insert(:user)
679 {:ok, user} = User.follow(user, followed_one)
680 {:ok, user} = User.follow(user, followed_two)
684 |> assign(:user, user)
685 |> get("/api/friends/ids")
687 expected = [followed_one.id, followed_two.id]
689 assert MapSet.equal?(
690 MapSet.new(Poison.decode!(json_response(conn, 200))),
696 describe "POST /api/account/update_profile.json" do
697 test "it updates a user's profile", %{conn: conn} do
702 |> assign(:user, user)
703 |> post("/api/account/update_profile.json", %{
704 "name" => "new name",
705 "description" => "new description"
708 user = Repo.get!(User, user.id)
709 assert user.name == "new name"
710 assert user.bio == "new description"
712 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
716 defp valid_user(_context) do
721 defp with_credentials(conn, username, password) do
722 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
723 put_req_header(conn, "authorization", header_content)
726 describe "GET /api/search.json" do
727 test "it returns search results", %{conn: conn} do
729 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
731 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
732 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
736 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
738 assert [status] = json_response(conn, 200)
739 assert status["id"] == activity.id
743 describe "GET /api/statusnet/tags/timeline/:tag.json" do
744 test "it returns the tags timeline", %{conn: conn} do
746 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
748 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
749 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
753 |> get("/api/statusnet/tags/timeline/2hu.json")
755 assert [status] = json_response(conn, 200)
756 assert status["id"] == activity.id