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
15 test "without valid credentials", %{conn: conn} do
16 conn = post conn, "/api/account/verify_credentials.json"
17 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
20 test "with credentials", %{conn: conn, user: user} do
22 |> with_credentials(user.nickname, "test")
23 |> post("/api/account/verify_credentials.json")
25 assert response = json_response(conn, 200)
26 assert response == UserView.render("show.json", %{user: user, token: response["token"]})
30 describe "POST /api/account/most_recent_notification" do
32 test "without valid credentials", %{conn: conn} do
33 conn = post conn, "/api/account/most_recent_notification.json"
34 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
37 test "with credentials", %{conn: conn, user: user} do
39 |> with_credentials(user.nickname, "test")
40 |> post("/api/account/most_recent_notification.json", %{id: "200"})
42 assert json_response(conn, 200)
43 user = User.get_by_nickname(user.nickname)
44 assert user.info["most_recent_notification"] == 200
48 describe "POST /statuses/update.json" do
50 test "without valid credentials", %{conn: conn} do
51 conn = post conn, "/api/statuses/update.json"
52 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
55 test "with credentials", %{conn: conn, user: user} do
56 conn_with_creds = conn |> with_credentials(user.nickname, "test")
57 request_path = "/api/statuses/update.json"
59 error_response = %{"request" => request_path,
60 "error" => "Client must provide a 'status' parameter with a value."}
61 conn = conn_with_creds |> post(request_path)
62 assert json_response(conn, 400) == error_response
64 conn = conn_with_creds |> post(request_path, %{ status: "" })
65 assert json_response(conn, 400) == error_response
67 conn = conn_with_creds |> post(request_path, %{ status: " " })
68 assert json_response(conn, 400) == error_response
70 conn = conn_with_creds |> post(request_path, %{ status: "Nice meme." })
71 assert json_response(conn, 200) == ActivityRepresenter.to_map(Repo.one(Activity), %{user: user})
75 describe "GET /statuses/public_timeline.json" do
76 test "returns statuses", %{conn: conn} do
77 {:ok, user} = UserBuilder.insert
78 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
79 ActivityBuilder.insert_list(10, %{}, %{user: user})
80 since_id = List.last(activities).id
83 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
85 response = json_response(conn, 200)
87 assert length(response) == 10
91 describe "GET /statuses/show/:id.json" do
92 test "returns one status", %{conn: conn} do
93 {:ok, user} = UserBuilder.insert
94 {:ok, activity} = ActivityBuilder.insert(%{}, %{user: user})
95 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
98 |> get("/api/statuses/show/#{activity.id}.json")
100 response = json_response(conn, 200)
102 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
106 describe "GET /users/show.json" do
107 test "gets user with screen_name", %{conn: conn} do
111 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
113 response = json_response(conn, 200)
115 assert response["id"] == user.id
118 test "gets user with user_id", %{conn: conn} do
122 |> get("/api/users/show.json", %{"user_id" => user.id})
124 response = json_response(conn, 200)
126 assert response["id"] == user.id
129 test "gets a user for a logged in user", %{conn: conn} do
131 logged_in = insert(:user)
133 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
136 |> with_credentials(logged_in.nickname, "test")
137 |> get("/api/users/show.json", %{"user_id" => user.id})
139 response = json_response(conn, 200)
141 assert response["following"] == true
145 describe "GET /statusnet/conversation/:id.json" do
146 test "returns the statuses in the conversation", %{conn: conn} do
147 {:ok, _user} = UserBuilder.insert
148 {:ok, _activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
149 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
150 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
152 {:ok, object} = Object.context_mapping("2hu") |> Repo.insert
154 |> get("/api/statusnet/conversation/#{object.id}.json")
156 response = json_response(conn, 200)
158 assert length(response) == 2
162 describe "GET /statuses/friends_timeline.json" do
164 test "without valid credentials", %{conn: conn} do
165 conn = get conn, "/api/statuses/friends_timeline.json"
166 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
169 test "with credentials", %{conn: conn, user: current_user} do
171 activities = ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
172 returned_activities = ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
173 other_user = insert(:user)
174 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
175 since_id = List.last(activities).id
177 current_user = Ecto.Changeset.change(current_user, following: [User.ap_followers(user)]) |> Repo.update!
180 |> with_credentials(current_user.nickname, "test")
181 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
183 response = json_response(conn, 200)
185 assert length(response) == 10
186 assert response == Enum.map(returned_activities, fn (activity) -> ActivityRepresenter.to_map(activity, %{user: User.get_cached_by_ap_id(activity.data["actor"]), for: current_user}) end)
190 describe "GET /statuses/mentions.json" do
192 test "without valid credentials", %{conn: conn} do
193 conn = get conn, "/api/statuses/mentions.json"
194 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
197 test "with credentials", %{conn: conn, user: current_user} do
198 {:ok, activity} = ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
201 |> with_credentials(current_user.nickname, "test")
202 |> get("/api/statuses/mentions.json")
204 response = json_response(conn, 200)
206 assert length(response) == 1
207 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user, mentioned: [current_user]})
211 describe "GET /statuses/user_timeline.json" do
213 test "without any params", %{conn: conn} do
214 conn = get(conn, "/api/statuses/user_timeline.json")
215 assert json_response(conn, 400) == %{"error" => "You need to specify screen_name or user_id", "request" => "/api/statuses/user_timeline.json"}
218 test "with user_id", %{conn: conn} do
220 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
223 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
224 response = json_response(conn, 200)
225 assert length(response) == 1
226 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
229 test "with screen_name", %{conn: conn} do
231 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
233 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
234 response = json_response(conn, 200)
235 assert length(response) == 1
236 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
239 test "with credentials", %{conn: conn, user: current_user} do
240 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
242 |> with_credentials(current_user.nickname, "test")
243 |> get("/api/statuses/user_timeline.json")
245 response = json_response(conn, 200)
247 assert length(response) == 1
248 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
251 test "with credentials with user_id", %{conn: conn, user: current_user} do
253 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
255 |> with_credentials(current_user.nickname, "test")
256 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
258 response = json_response(conn, 200)
260 assert length(response) == 1
261 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
264 test "with credentials screen_name", %{conn: conn, user: current_user} do
266 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
268 |> with_credentials(current_user.nickname, "test")
269 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
271 response = json_response(conn, 200)
273 assert length(response) == 1
274 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
278 describe "POST /friendships/create.json" do
280 test "without valid credentials", %{conn: conn} do
281 conn = post conn, "/api/friendships/create.json"
282 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
285 test "with credentials", %{conn: conn, user: current_user} do
286 followed = insert(:user)
289 |> with_credentials(current_user.nickname, "test")
290 |> post("/api/friendships/create.json", %{user_id: followed.id})
292 current_user = Repo.get(User, current_user.id)
293 assert User.ap_followers(followed) in current_user.following
294 assert json_response(conn, 200) == UserView.render("show.json", %{user: followed, for: current_user})
298 describe "POST /friendships/destroy.json" do
300 test "without valid credentials", %{conn: conn} do
301 conn = post conn, "/api/friendships/destroy.json"
302 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
305 test "with credentials", %{conn: conn, user: current_user} do
306 followed = insert(:user)
308 {:ok, current_user} = User.follow(current_user, followed)
309 assert User.ap_followers(followed) in current_user.following
310 ActivityPub.follow(current_user, followed)
313 |> with_credentials(current_user.nickname, "test")
314 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
316 current_user = Repo.get(User, current_user.id)
317 assert current_user.following == [current_user.ap_id]
318 assert json_response(conn, 200) == UserView.render("show.json", %{user: followed, for: current_user})
322 describe "POST /blocks/create.json" do
324 test "without valid credentials", %{conn: conn} do
325 conn = post conn, "/api/blocks/create.json"
326 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
329 test "with credentials", %{conn: conn, user: current_user} do
330 blocked = insert(:user)
333 |> with_credentials(current_user.nickname, "test")
334 |> post("/api/blocks/create.json", %{user_id: blocked.id})
336 current_user = Repo.get(User, current_user.id)
337 assert User.blocks?(current_user, blocked)
338 assert json_response(conn, 200) == UserView.render("show.json", %{user: blocked, for: current_user})
342 describe "POST /blocks/destroy.json" do
344 test "without valid credentials", %{conn: conn} do
345 conn = post conn, "/api/blocks/destroy.json"
346 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
349 test "with credentials", %{conn: conn, user: current_user} do
350 blocked = insert(:user)
352 {:ok, current_user} = User.block(current_user, blocked)
353 assert User.blocks?(current_user, blocked)
356 |> with_credentials(current_user.nickname, "test")
357 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
359 current_user = Repo.get(User, current_user.id)
360 assert current_user.info["blocks"] == []
361 assert json_response(conn, 200) == UserView.render("show.json", %{user: blocked, for: current_user})
365 describe "GET /help/test.json" do
366 test "returns \"ok\"", %{conn: conn} do
367 conn = get conn, "/api/help/test.json"
368 assert json_response(conn, 200) == "ok"
372 describe "POST /api/qvitter/update_avatar.json" do
374 test "without valid credentials", %{conn: conn} do
375 conn = post conn, "/api/qvitter/update_avatar.json"
376 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
379 test "with credentials", %{conn: conn, user: current_user} do
380 avatar_image = File.read!("test/fixtures/avatar_data_uri")
382 |> with_credentials(current_user.nickname, "test")
383 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
385 current_user = Repo.get(User, current_user.id)
386 assert is_map(current_user.avatar)
387 assert json_response(conn, 200) == UserView.render("show.json", %{user: current_user, for: current_user})
391 describe "POST /api/favorites/create/:id" do
393 test "without valid credentials", %{conn: conn} do
394 note_activity = insert(:note_activity)
395 conn = post conn, "/api/favorites/create/#{note_activity.id}.json"
396 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
399 test "with credentials", %{conn: conn, user: current_user} do
400 note_activity = insert(:note_activity)
403 |> with_credentials(current_user.nickname, "test")
404 |> post("/api/favorites/create/#{note_activity.id}.json")
406 assert json_response(conn, 200)
410 describe "POST /api/favorites/destroy/:id" do
412 test "without valid credentials", %{conn: conn} do
413 note_activity = insert(:note_activity)
414 conn = post conn, "/api/favorites/destroy/#{note_activity.id}.json"
415 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
418 test "with credentials", %{conn: conn, user: current_user} do
419 note_activity = insert(:note_activity)
420 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
421 ActivityPub.like(current_user, object)
424 |> with_credentials(current_user.nickname, "test")
425 |> post("/api/favorites/destroy/#{note_activity.id}.json")
427 assert json_response(conn, 200)
431 describe "POST /api/statuses/retweet/:id" do
433 test "without valid credentials", %{conn: conn} do
434 note_activity = insert(:note_activity)
435 conn = post conn, "/api/statuses/retweet/#{note_activity.id}.json"
436 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
439 test "with credentials", %{conn: conn, user: current_user} do
440 note_activity = insert(:note_activity)
442 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
445 |> with_credentials(current_user.nickname, "test")
446 |> post(request_path)
447 activity = Repo.get(Activity, note_activity.id)
448 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
449 assert json_response(response, 200) == ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
453 describe "POST /api/account/register" do
454 test "it creates a new user", %{conn: conn} do
456 "nickname" => "lain",
457 "email" => "lain@wired.jp",
458 "fullname" => "lain iwakura",
459 "bio" => "close the world.",
460 "password" => "bear",
465 |> post("/api/account/register", data)
467 user = json_response(conn, 200)
469 fetched_user = Repo.get_by(User, nickname: "lain")
470 assert user == UserView.render("show.json", %{user: fetched_user})
473 test "it returns errors on a problem", %{conn: conn} do
475 "email" => "lain@wired.jp",
476 "fullname" => "lain iwakura",
477 "bio" => "close the world.",
478 "password" => "bear",
483 |> post("/api/account/register", data)
485 errors = json_response(conn, 400)
487 assert is_binary(errors["error"])
491 describe "GET /api/externalprofile/show" do
492 test "it returns the user", %{conn: conn} do
494 other_user = insert(:user)
497 |> assign(:user, user)
498 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
500 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
504 describe "GET /api/statuses/followers" do
505 test "it returns a user's followers", %{conn: conn} do
507 follower_one = insert(:user)
508 follower_two = insert(:user)
509 _not_follower = insert(:user)
511 {:ok, follower_one} = User.follow(follower_one, user)
512 {:ok, follower_two} = User.follow(follower_two, user)
515 |> assign(:user, user)
516 |> get("/api/statuses/followers")
518 assert json_response(conn, 200) == UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
522 describe "GET /api/statuses/friends" do
523 test "it returns the logged in user's friends", %{conn: conn} do
525 followed_one = insert(:user)
526 followed_two = insert(:user)
527 _not_followed = insert(:user)
529 {:ok, user} = User.follow(user, followed_one)
530 {:ok, user} = User.follow(user, followed_two)
533 |> assign(:user, user)
534 |> get("/api/statuses/friends")
536 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
539 test "it returns a given user's friends with user_id", %{conn: conn} do
541 followed_one = insert(:user)
542 followed_two = insert(:user)
543 _not_followed = insert(:user)
545 {:ok, user} = User.follow(user, followed_one)
546 {:ok, user} = User.follow(user, followed_two)
549 |> get("/api/statuses/friends", %{"user_id" => user.id})
551 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
554 test "it returns a given user's friends with screen_name", %{conn: conn} do
556 followed_one = insert(:user)
557 followed_two = insert(:user)
558 _not_followed = insert(:user)
560 {:ok, user} = User.follow(user, followed_one)
561 {:ok, user} = User.follow(user, followed_two)
564 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
566 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
570 describe "GET /friends/ids" do
571 test "it returns a user's friends", %{conn: conn} do
573 followed_one = insert(:user)
574 followed_two = insert(:user)
575 _not_followed = insert(:user)
577 {:ok, user} = User.follow(user, followed_one)
578 {:ok, user} = User.follow(user, followed_two)
581 |> assign(:user, user)
582 |> get("/api/friends/ids")
584 expected = [followed_one.id, followed_two.id]
585 assert MapSet.equal?(MapSet.new(Poison.decode!(json_response(conn, 200))), MapSet.new(expected))
589 describe "POST /api/account/update_profile.json" do
590 test "it updates a user's profile", %{conn: conn} do
594 |> assign(:user, user)
595 |> post("/api/account/update_profile.json", %{"name" => "new name", "description" => "new description"})
597 user = Repo.get!(User, user.id)
598 assert user.name == "new name"
599 assert user.bio == "new description"
601 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
605 defp valid_user(_context) do
610 defp with_credentials(conn, username, password) do
611 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
612 put_req_header(conn, "authorization", header_content)
615 describe "GET /api/search.json" do
616 test "it returns search results", %{conn: conn} do
618 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
620 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
621 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
624 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
626 assert [status] = json_response(conn, 200)
627 assert status["id"] == activity.id
631 describe "GET /api/statusnet/tags/timeline/:tag.json" do
632 test "it returns the tags timeline", %{conn: conn} do
634 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
636 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
637 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
640 |> get("/api/statusnet/tags/timeline/2hu.json")
642 assert [status] = json_response(conn, 200)
643 assert status["id"] == activity.id