fbeec66058da2ac0b7114bd8b8aa9003af011601
[akkoma] / test / web / twitter_api / twitter_api_controller_test.exs
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
10
11 import Pleroma.Factory
12
13 describe "POST /api/account/verify_credentials" do
14 setup [:valid_user]
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."}
18 end
19
20 test "with credentials", %{conn: conn, user: user} do
21 conn = conn
22 |> with_credentials(user.nickname, "test")
23 |> post("/api/account/verify_credentials.json")
24
25 assert response = json_response(conn, 200)
26 assert response == UserView.render("show.json", %{user: user, token: response["token"]})
27 end
28 end
29
30 describe "POST /api/account/most_recent_notification" do
31 setup [:valid_user]
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."}
35 end
36
37 test "with credentials", %{conn: conn, user: user} do
38 conn = conn
39 |> with_credentials(user.nickname, "test")
40 |> post("/api/account/most_recent_notification.json", %{id: "200"})
41
42 assert json_response(conn, 200)
43 user = User.get_by_nickname(user.nickname)
44 assert user.info["most_recent_notification"] == 200
45 end
46 end
47
48 describe "POST /statuses/update.json" do
49 setup [:valid_user]
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."}
53 end
54
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"
58
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
63
64 conn = conn_with_creds |> post(request_path, %{ status: "" })
65 assert json_response(conn, 400) == error_response
66
67 conn = conn_with_creds |> post(request_path, %{ status: " " })
68 assert json_response(conn, 400) == error_response
69
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})
72 end
73 end
74
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
81
82 conn = conn
83 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
84
85 response = json_response(conn, 200)
86
87 assert length(response) == 10
88 end
89 end
90
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"])
96
97 conn = conn
98 |> get("/api/statuses/show/#{activity.id}.json")
99
100 response = json_response(conn, 200)
101
102 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
103 end
104 end
105
106 describe "GET /users/show.json" do
107 test "gets user with screen_name", %{conn: conn} do
108 user = insert(:user)
109
110 conn = conn
111 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
112
113 response = json_response(conn, 200)
114
115 assert response["id"] == user.id
116 end
117
118 test "gets user with user_id", %{conn: conn} do
119 user = insert(:user)
120
121 conn = conn
122 |> get("/api/users/show.json", %{"user_id" => user.id})
123
124 response = json_response(conn, 200)
125
126 assert response["id"] == user.id
127 end
128
129 test "gets a user for a logged in user", %{conn: conn} do
130 user = insert(:user)
131 logged_in = insert(:user)
132
133 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
134
135 conn = conn
136 |> with_credentials(logged_in.nickname, "test")
137 |> get("/api/users/show.json", %{"user_id" => user.id})
138
139 response = json_response(conn, 200)
140
141 assert response["following"] == true
142 end
143 end
144
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"})
151
152 {:ok, object} = Object.context_mapping("2hu") |> Repo.insert
153 conn = conn
154 |> get("/api/statusnet/conversation/#{object.id}.json")
155
156 response = json_response(conn, 200)
157
158 assert length(response) == 2
159 end
160 end
161
162 describe "GET /statuses/friends_timeline.json" do
163 setup [:valid_user]
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."}
167 end
168
169 test "with credentials", %{conn: conn, user: current_user} do
170 user = insert(:user)
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
176
177 current_user = Ecto.Changeset.change(current_user, following: [User.ap_followers(user)]) |> Repo.update!
178
179 conn = conn
180 |> with_credentials(current_user.nickname, "test")
181 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
182
183 response = json_response(conn, 200)
184
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)
187 end
188 end
189
190 describe "GET /statuses/mentions.json" do
191 setup [:valid_user]
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."}
195 end
196
197 test "with credentials", %{conn: conn, user: current_user} do
198 {:ok, activity} = ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
199
200 conn = conn
201 |> with_credentials(current_user.nickname, "test")
202 |> get("/api/statuses/mentions.json")
203
204 response = json_response(conn, 200)
205
206 assert length(response) == 1
207 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user, mentioned: [current_user]})
208 end
209 end
210
211 describe "GET /statuses/user_timeline.json" do
212 setup [:valid_user]
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"}
216 end
217
218 test "with user_id", %{conn: conn} do
219 user = insert(:user)
220 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
221 |> IO.inspect
222
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})
227 end
228
229 test "with screen_name", %{conn: conn} do
230 user = insert(:user)
231 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
232
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})
237 end
238
239 test "with credentials", %{conn: conn, user: current_user} do
240 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
241 conn = conn
242 |> with_credentials(current_user.nickname, "test")
243 |> get("/api/statuses/user_timeline.json")
244
245 response = json_response(conn, 200)
246
247 assert length(response) == 1
248 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
249 end
250
251 test "with credentials with user_id", %{conn: conn, user: current_user} do
252 user = insert(:user)
253 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
254 conn = conn
255 |> with_credentials(current_user.nickname, "test")
256 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
257
258 response = json_response(conn, 200)
259
260 assert length(response) == 1
261 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
262 end
263
264 test "with credentials screen_name", %{conn: conn, user: current_user} do
265 user = insert(:user)
266 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
267 conn = conn
268 |> with_credentials(current_user.nickname, "test")
269 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
270
271 response = json_response(conn, 200)
272
273 assert length(response) == 1
274 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
275 end
276 end
277
278 describe "POST /friendships/create.json" do
279 setup [:valid_user]
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."}
283 end
284
285 test "with credentials", %{conn: conn, user: current_user} do
286 followed = insert(:user)
287
288 conn = conn
289 |> with_credentials(current_user.nickname, "test")
290 |> post("/api/friendships/create.json", %{user_id: followed.id})
291
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})
295 end
296 end
297
298 describe "POST /friendships/destroy.json" do
299 setup [:valid_user]
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."}
303 end
304
305 test "with credentials", %{conn: conn, user: current_user} do
306 followed = insert(:user)
307
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)
311
312 conn = conn
313 |> with_credentials(current_user.nickname, "test")
314 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
315
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})
319 end
320 end
321
322 describe "POST /blocks/create.json" do
323 setup [:valid_user]
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."}
327 end
328
329 test "with credentials", %{conn: conn, user: current_user} do
330 blocked = insert(:user)
331
332 conn = conn
333 |> with_credentials(current_user.nickname, "test")
334 |> post("/api/blocks/create.json", %{user_id: blocked.id})
335
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})
339 end
340 end
341
342 describe "POST /blocks/destroy.json" do
343 setup [:valid_user]
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."}
347 end
348
349 test "with credentials", %{conn: conn, user: current_user} do
350 blocked = insert(:user)
351
352 {:ok, current_user} = User.block(current_user, blocked)
353 assert User.blocks?(current_user, blocked)
354
355 conn = conn
356 |> with_credentials(current_user.nickname, "test")
357 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
358
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})
362 end
363 end
364
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"
369 end
370 end
371
372 describe "POST /api/qvitter/update_avatar.json" do
373 setup [:valid_user]
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."}
377 end
378
379 test "with credentials", %{conn: conn, user: current_user} do
380 avatar_image = File.read!("test/fixtures/avatar_data_uri")
381 conn = conn
382 |> with_credentials(current_user.nickname, "test")
383 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
384
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})
388 end
389 end
390
391 describe "POST /api/favorites/create/:id" do
392 setup [:valid_user]
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."}
397 end
398
399 test "with credentials", %{conn: conn, user: current_user} do
400 note_activity = insert(:note_activity)
401
402 conn = conn
403 |> with_credentials(current_user.nickname, "test")
404 |> post("/api/favorites/create/#{note_activity.id}.json")
405
406 assert json_response(conn, 200)
407 end
408 end
409
410 describe "POST /api/favorites/destroy/:id" do
411 setup [:valid_user]
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."}
416 end
417
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)
422
423 conn = conn
424 |> with_credentials(current_user.nickname, "test")
425 |> post("/api/favorites/destroy/#{note_activity.id}.json")
426
427 assert json_response(conn, 200)
428 end
429 end
430
431 describe "POST /api/statuses/retweet/:id" do
432 setup [:valid_user]
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."}
437 end
438
439 test "with credentials", %{conn: conn, user: current_user} do
440 note_activity = insert(:note_activity)
441
442 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
443
444 response = conn
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})
450 end
451 end
452
453 describe "POST /api/account/register" do
454 test "it creates a new user", %{conn: conn} do
455 data = %{
456 "nickname" => "lain",
457 "email" => "lain@wired.jp",
458 "fullname" => "lain iwakura",
459 "bio" => "close the world.",
460 "password" => "bear",
461 "confirm" => "bear"
462 }
463
464 conn = conn
465 |> post("/api/account/register", data)
466
467 user = json_response(conn, 200)
468
469 fetched_user = Repo.get_by(User, nickname: "lain")
470 assert user == UserView.render("show.json", %{user: fetched_user})
471 end
472
473 test "it returns errors on a problem", %{conn: conn} do
474 data = %{
475 "email" => "lain@wired.jp",
476 "fullname" => "lain iwakura",
477 "bio" => "close the world.",
478 "password" => "bear",
479 "confirm" => "bear"
480 }
481
482 conn = conn
483 |> post("/api/account/register", data)
484
485 errors = json_response(conn, 400)
486
487 assert is_binary(errors["error"])
488 end
489 end
490
491 describe "GET /api/externalprofile/show" do
492 test "it returns the user", %{conn: conn} do
493 user = insert(:user)
494 other_user = insert(:user)
495
496 conn = conn
497 |> assign(:user, user)
498 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
499
500 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
501 end
502 end
503
504 describe "GET /api/statuses/followers" do
505 test "it returns a user's followers", %{conn: conn} do
506 user = insert(:user)
507 follower_one = insert(:user)
508 follower_two = insert(:user)
509 _not_follower = insert(:user)
510
511 {:ok, follower_one} = User.follow(follower_one, user)
512 {:ok, follower_two} = User.follow(follower_two, user)
513
514 conn = conn
515 |> assign(:user, user)
516 |> get("/api/statuses/followers")
517
518 assert json_response(conn, 200) == UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
519 end
520 end
521
522 describe "GET /api/statuses/friends" do
523 test "it returns the logged in user's friends", %{conn: conn} do
524 user = insert(:user)
525 followed_one = insert(:user)
526 followed_two = insert(:user)
527 _not_followed = insert(:user)
528
529 {:ok, user} = User.follow(user, followed_one)
530 {:ok, user} = User.follow(user, followed_two)
531
532 conn = conn
533 |> assign(:user, user)
534 |> get("/api/statuses/friends")
535
536 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
537 end
538
539 test "it returns a given user's friends with user_id", %{conn: conn} do
540 user = insert(:user)
541 followed_one = insert(:user)
542 followed_two = insert(:user)
543 _not_followed = insert(:user)
544
545 {:ok, user} = User.follow(user, followed_one)
546 {:ok, user} = User.follow(user, followed_two)
547
548 conn = conn
549 |> get("/api/statuses/friends", %{"user_id" => user.id})
550
551 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
552 end
553
554 test "it returns a given user's friends with screen_name", %{conn: conn} do
555 user = insert(:user)
556 followed_one = insert(:user)
557 followed_two = insert(:user)
558 _not_followed = insert(:user)
559
560 {:ok, user} = User.follow(user, followed_one)
561 {:ok, user} = User.follow(user, followed_two)
562
563 conn = conn
564 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
565
566 assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user})))
567 end
568 end
569
570 describe "GET /friends/ids" do
571 test "it returns a user's friends", %{conn: conn} do
572 user = insert(:user)
573 followed_one = insert(:user)
574 followed_two = insert(:user)
575 _not_followed = insert(:user)
576
577 {:ok, user} = User.follow(user, followed_one)
578 {:ok, user} = User.follow(user, followed_two)
579
580 conn = conn
581 |> assign(:user, user)
582 |> get("/api/friends/ids")
583
584 expected = [followed_one.id, followed_two.id]
585 assert MapSet.equal?(MapSet.new(Poison.decode!(json_response(conn, 200))), MapSet.new(expected))
586 end
587 end
588
589 describe "POST /api/account/update_profile.json" do
590 test "it updates a user's profile", %{conn: conn} do
591 user = insert(:user)
592
593 conn = conn
594 |> assign(:user, user)
595 |> post("/api/account/update_profile.json", %{"name" => "new name", "description" => "new description"})
596
597 user = Repo.get!(User, user.id)
598 assert user.name == "new name"
599 assert user.bio == "new description"
600
601 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
602 end
603 end
604
605 defp valid_user(_context) do
606 user = insert(:user)
607 [user: user]
608 end
609
610 defp with_credentials(conn, username, password) do
611 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
612 put_req_header(conn, "authorization", header_content)
613 end
614
615 describe "GET /api/search.json" do
616 test "it returns search results", %{conn: conn} do
617 user = insert(:user)
618 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
619
620 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
621 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
622
623 conn = conn
624 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
625
626 assert [status] = json_response(conn, 200)
627 assert status["id"] == activity.id
628 end
629 end
630
631 describe "GET /api/statusnet/tags/timeline/:tag.json" do
632 test "it returns the tags timeline", %{conn: conn} do
633 user = insert(:user)
634 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
635
636 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
637 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
638
639 conn = conn
640 |> get("/api/statusnet/tags/timeline/2hu.json")
641
642 assert [status] = json_response(conn, 200)
643 assert status["id"] == activity.id
644 end
645 end
646 end