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})
222 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
223 response = json_response(conn, 200)
224 assert length(response) == 1
225 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
228 test "with screen_name", %{conn: conn} do
230 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
232 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
233 response = json_response(conn, 200)
234 assert length(response) == 1
235 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
238 test "with credentials", %{conn: conn, user: current_user} do
239 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
241 |> with_credentials(current_user.nickname, "test")
242 |> get("/api/statuses/user_timeline.json")
244 response = json_response(conn, 200)
246 assert length(response) == 1
247 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
250 test "with credentials with user_id", %{conn: conn, user: current_user} do
252 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
254 |> with_credentials(current_user.nickname, "test")
255 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
257 response = json_response(conn, 200)
259 assert length(response) == 1
260 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
263 test "with credentials screen_name", %{conn: conn, user: current_user} do
265 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
267 |> with_credentials(current_user.nickname, "test")
268 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
270 response = json_response(conn, 200)
272 assert length(response) == 1
273 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
277 describe "POST /friendships/create.json" do
279 test "without valid credentials", %{conn: conn} do
280 conn = post conn, "/api/friendships/create.json"
281 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
284 test "with credentials", %{conn: conn, user: current_user} do
285 followed = insert(:user)
288 |> with_credentials(current_user.nickname, "test")
289 |> post("/api/friendships/create.json", %{user_id: followed.id})
291 current_user = Repo.get(User, current_user.id)
292 assert User.ap_followers(followed) in current_user.following
293 assert json_response(conn, 200) == UserView.render("show.json", %{user: followed, for: current_user})
297 describe "POST /friendships/destroy.json" do
299 test "without valid credentials", %{conn: conn} do
300 conn = post conn, "/api/friendships/destroy.json"
301 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
304 test "with credentials", %{conn: conn, user: current_user} do
305 followed = insert(:user)
307 {:ok, current_user} = User.follow(current_user, followed)
308 assert User.ap_followers(followed) in current_user.following
309 ActivityPub.follow(current_user, followed)
312 |> with_credentials(current_user.nickname, "test")
313 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
315 current_user = Repo.get(User, current_user.id)
316 assert current_user.following == [current_user.ap_id]
317 assert json_response(conn, 200) == UserView.render("show.json", %{user: followed, for: current_user})
321 describe "POST /blocks/create.json" do
323 test "without valid credentials", %{conn: conn} do
324 conn = post conn, "/api/blocks/create.json"
325 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
328 test "with credentials", %{conn: conn, user: current_user} do
329 blocked = insert(:user)
332 |> with_credentials(current_user.nickname, "test")
333 |> post("/api/blocks/create.json", %{user_id: blocked.id})
335 current_user = Repo.get(User, current_user.id)
336 assert User.blocks?(current_user, blocked)
337 assert json_response(conn, 200) == UserView.render("show.json", %{user: blocked, for: current_user})
341 describe "POST /blocks/destroy.json" do
343 test "without valid credentials", %{conn: conn} do
344 conn = post conn, "/api/blocks/destroy.json"
345 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
348 test "with credentials", %{conn: conn, user: current_user} do
349 blocked = insert(:user)
351 {:ok, current_user} = User.block(current_user, blocked)
352 assert User.blocks?(current_user, blocked)
355 |> with_credentials(current_user.nickname, "test")
356 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
358 current_user = Repo.get(User, current_user.id)
359 assert current_user.info["blocks"] == []
360 assert json_response(conn, 200) == UserView.render("show.json", %{user: blocked, for: current_user})
364 describe "GET /help/test.json" do
365 test "returns \"ok\"", %{conn: conn} do
366 conn = get conn, "/api/help/test.json"
367 assert json_response(conn, 200) == "ok"
371 describe "POST /api/qvitter/update_avatar.json" do
373 test "without valid credentials", %{conn: conn} do
374 conn = post conn, "/api/qvitter/update_avatar.json"
375 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
378 test "with credentials", %{conn: conn, user: current_user} do
379 avatar_image = File.read!("test/fixtures/avatar_data_uri")
381 |> with_credentials(current_user.nickname, "test")
382 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
384 current_user = Repo.get(User, current_user.id)
385 assert is_map(current_user.avatar)
386 assert json_response(conn, 200) == UserView.render("show.json", %{user: current_user, for: current_user})
390 describe "POST /api/favorites/create/:id" do
392 test "without valid credentials", %{conn: conn} do
393 note_activity = insert(:note_activity)
394 conn = post conn, "/api/favorites/create/#{note_activity.id}.json"
395 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
398 test "with credentials", %{conn: conn, user: current_user} do
399 note_activity = insert(:note_activity)
402 |> with_credentials(current_user.nickname, "test")
403 |> post("/api/favorites/create/#{note_activity.id}.json")
405 assert json_response(conn, 200)
409 describe "POST /api/favorites/destroy/:id" do
411 test "without valid credentials", %{conn: conn} do
412 note_activity = insert(:note_activity)
413 conn = post conn, "/api/favorites/destroy/#{note_activity.id}.json"
414 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
417 test "with credentials", %{conn: conn, user: current_user} do
418 note_activity = insert(:note_activity)
419 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
420 ActivityPub.like(current_user, object)
423 |> with_credentials(current_user.nickname, "test")
424 |> post("/api/favorites/destroy/#{note_activity.id}.json")
426 assert json_response(conn, 200)
430 describe "POST /api/statuses/retweet/:id" do
432 test "without valid credentials", %{conn: conn} do
433 note_activity = insert(:note_activity)
434 conn = post conn, "/api/statuses/retweet/#{note_activity.id}.json"
435 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
438 test "with credentials", %{conn: conn, user: current_user} do
439 note_activity = insert(:note_activity)
441 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
444 |> with_credentials(current_user.nickname, "test")
445 |> post(request_path)
446 activity = Repo.get(Activity, note_activity.id)
447 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
448 assert json_response(response, 200) == ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
452 describe "POST /api/account/register" do
453 test "it creates a new user", %{conn: conn} do
455 "nickname" => "lain",
456 "email" => "lain@wired.jp",
457 "fullname" => "lain iwakura",
458 "bio" => "close the world.",
459 "password" => "bear",
464 |> post("/api/account/register", data)
466 user = json_response(conn, 200)
468 fetched_user = Repo.get_by(User, nickname: "lain")
469 assert user == UserView.render("show.json", %{user: fetched_user})
472 test "it returns errors on a problem", %{conn: conn} do
474 "email" => "lain@wired.jp",
475 "fullname" => "lain iwakura",
476 "bio" => "close the world.",
477 "password" => "bear",
482 |> post("/api/account/register", data)
484 errors = json_response(conn, 400)
486 assert is_binary(errors["error"])
490 describe "GET /api/externalprofile/show" do
491 test "it returns the user", %{conn: conn} do
493 other_user = insert(:user)
496 |> assign(:user, user)
497 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
499 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
503 describe "GET /api/statuses/followers" do
504 test "it returns a user's followers", %{conn: conn} do
506 follower_one = insert(:user)
507 follower_two = insert(:user)
508 _not_follower = insert(:user)
510 {:ok, follower_one} = User.follow(follower_one, user)
511 {:ok, follower_two} = User.follow(follower_two, user)
514 |> assign(:user, user)
515 |> get("/api/statuses/followers")
517 assert json_response(conn, 200) == UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
521 describe "GET /api/statuses/friends" do
522 test "it returns the logged in user's friends", %{conn: conn} do
524 followed_one = insert(:user)
525 followed_two = insert(:user)
526 _not_followed = insert(:user)
528 {:ok, user} = User.follow(user, followed_one)
529 {:ok, user} = User.follow(user, followed_two)
532 |> assign(:user, user)
533 |> get("/api/statuses/friends")
535 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
538 test "it returns a given user's friends with user_id", %{conn: conn} do
540 followed_one = insert(:user)
541 followed_two = insert(:user)
542 _not_followed = insert(:user)
544 {:ok, user} = User.follow(user, followed_one)
545 {:ok, user} = User.follow(user, followed_two)
548 |> get("/api/statuses/friends", %{"user_id" => user.id})
550 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
553 test "it returns a given user's friends with screen_name", %{conn: conn} do
555 followed_one = insert(:user)
556 followed_two = insert(:user)
557 _not_followed = insert(:user)
559 {:ok, user} = User.follow(user, followed_one)
560 {:ok, user} = User.follow(user, followed_two)
563 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
565 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
569 describe "GET /friends/ids" do
570 test "it returns a user's friends", %{conn: conn} do
572 followed_one = insert(:user)
573 followed_two = insert(:user)
574 _not_followed = insert(:user)
576 {:ok, user} = User.follow(user, followed_one)
577 {:ok, user} = User.follow(user, followed_two)
580 |> assign(:user, user)
581 |> get("/api/friends/ids")
583 expected = [followed_one.id, followed_two.id]
584 assert MapSet.equal?(MapSet.new(Poison.decode!(json_response(conn, 200))), MapSet.new(expected))
588 describe "POST /api/account/update_profile.json" do
589 test "it updates a user's profile", %{conn: conn} do
593 |> assign(:user, user)
594 |> post("/api/account/update_profile.json", %{"name" => "new name", "description" => "new description"})
596 user = Repo.get!(User, user.id)
597 assert user.name == "new name"
598 assert user.bio == "new description"
600 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
604 defp valid_user(_context) do
609 defp with_credentials(conn, username, password) do
610 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
611 put_req_header(conn, "authorization", header_content)
614 describe "GET /api/search.json" do
615 test "it returns search results", %{conn: conn} do
617 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
619 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
620 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
623 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
625 assert [status] = json_response(conn, 200)
626 assert status["id"] == activity.id
630 describe "GET /api/statusnet/tags/timeline/:tag.json" do
631 test "it returns the tags timeline", %{conn: conn} do
633 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
635 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
636 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
639 |> get("/api/statusnet/tags/timeline/2hu.json")
641 assert [status] = json_response(conn, 200)
642 assert status["id"] == activity.id