50b19fd86d6cfba241b305129e1c9c37f0798c4b
[akkoma] / test / web / twitter_api / twitter_api_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.TwitterAPI.ControllerTest do
6 use Pleroma.Web.ConnCase
7 alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
8 alias Pleroma.Builders.ActivityBuilder
9 alias Pleroma.Builders.UserBuilder
10 alias Pleroma.Repo
11 alias Pleroma.Activity
12 alias Pleroma.User
13 alias Pleroma.Object
14 alias Pleroma.Notification
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.TwitterAPI.UserView
17 alias Pleroma.Web.TwitterAPI.NotificationView
18 alias Pleroma.Web.CommonAPI
19 alias Pleroma.Web.TwitterAPI.TwitterAPI
20 alias Comeonin.Pbkdf2
21 alias Ecto.Changeset
22
23 import Pleroma.Factory
24
25 @banner "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
26
27 describe "POST /api/account/update_profile_banner" do
28 test "it updates the banner", %{conn: conn} do
29 user = insert(:user)
30
31 conn
32 |> assign(:user, user)
33 |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => @banner})
34 |> json_response(200)
35
36 user = refresh_record(user)
37 assert user.info.banner["type"] == "Image"
38 end
39 end
40
41 describe "POST /api/qvitter/update_background_image" do
42 test "it updates the background", %{conn: conn} do
43 user = insert(:user)
44
45 conn
46 |> assign(:user, user)
47 |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => @banner})
48 |> json_response(200)
49
50 user = refresh_record(user)
51 assert user.info.background["type"] == "Image"
52 end
53 end
54
55 describe "POST /api/account/verify_credentials" do
56 setup [:valid_user]
57
58 test "without valid credentials", %{conn: conn} do
59 conn = post(conn, "/api/account/verify_credentials.json")
60 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
61 end
62
63 test "with credentials", %{conn: conn, user: user} do
64 response =
65 conn
66 |> with_credentials(user.nickname, "test")
67 |> post("/api/account/verify_credentials.json")
68 |> json_response(200)
69
70 assert response ==
71 UserView.render("show.json", %{user: user, token: response["token"], for: user})
72 end
73 end
74
75 describe "POST /statuses/update.json" do
76 setup [:valid_user]
77
78 test "without valid credentials", %{conn: conn} do
79 conn = post(conn, "/api/statuses/update.json")
80 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
81 end
82
83 test "with credentials", %{conn: conn, user: user} do
84 conn_with_creds = conn |> with_credentials(user.nickname, "test")
85 request_path = "/api/statuses/update.json"
86
87 error_response = %{
88 "request" => request_path,
89 "error" => "Client must provide a 'status' parameter with a value."
90 }
91
92 conn =
93 conn_with_creds
94 |> post(request_path)
95
96 assert json_response(conn, 400) == error_response
97
98 conn =
99 conn_with_creds
100 |> post(request_path, %{status: ""})
101
102 assert json_response(conn, 400) == error_response
103
104 conn =
105 conn_with_creds
106 |> post(request_path, %{status: " "})
107
108 assert json_response(conn, 400) == error_response
109
110 # we post with visibility private in order to avoid triggering relay
111 conn =
112 conn_with_creds
113 |> post(request_path, %{status: "Nice meme.", visibility: "private"})
114
115 assert json_response(conn, 200) ==
116 ActivityRepresenter.to_map(Repo.one(Activity), %{user: user, for: user})
117 end
118 end
119
120 describe "GET /statuses/public_timeline.json" do
121 setup [:valid_user]
122
123 test "returns statuses", %{conn: conn} do
124 user = insert(:user)
125 activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
126 ActivityBuilder.insert_list(10, %{}, %{user: user})
127 since_id = List.last(activities).id
128
129 conn =
130 conn
131 |> get("/api/statuses/public_timeline.json", %{since_id: since_id})
132
133 response = json_response(conn, 200)
134
135 assert length(response) == 10
136 end
137
138 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
139 instance =
140 Application.get_env(:pleroma, :instance)
141 |> Keyword.put(:public, false)
142
143 Application.put_env(:pleroma, :instance, instance)
144
145 conn
146 |> get("/api/statuses/public_timeline.json")
147 |> json_response(403)
148
149 instance =
150 Application.get_env(:pleroma, :instance)
151 |> Keyword.put(:public, true)
152
153 Application.put_env(:pleroma, :instance, instance)
154 end
155
156 test "returns 200 to authenticated request when the instance is not public",
157 %{conn: conn, user: user} do
158 instance =
159 Application.get_env(:pleroma, :instance)
160 |> Keyword.put(:public, false)
161
162 Application.put_env(:pleroma, :instance, instance)
163
164 conn
165 |> with_credentials(user.nickname, "test")
166 |> get("/api/statuses/public_timeline.json")
167 |> json_response(200)
168
169 instance =
170 Application.get_env(:pleroma, :instance)
171 |> Keyword.put(:public, true)
172
173 Application.put_env(:pleroma, :instance, instance)
174 end
175
176 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
177 conn
178 |> get("/api/statuses/public_timeline.json")
179 |> json_response(200)
180 end
181
182 test "returns 200 to authenticated request when the instance is public",
183 %{conn: conn, user: user} do
184 conn
185 |> with_credentials(user.nickname, "test")
186 |> get("/api/statuses/public_timeline.json")
187 |> json_response(200)
188 end
189 end
190
191 describe "GET /statuses/public_and_external_timeline.json" do
192 setup [:valid_user]
193
194 test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
195 instance =
196 Application.get_env(:pleroma, :instance)
197 |> Keyword.put(:public, false)
198
199 Application.put_env(:pleroma, :instance, instance)
200
201 conn
202 |> get("/api/statuses/public_and_external_timeline.json")
203 |> json_response(403)
204
205 instance =
206 Application.get_env(:pleroma, :instance)
207 |> Keyword.put(:public, true)
208
209 Application.put_env(:pleroma, :instance, instance)
210 end
211
212 test "returns 200 to authenticated request when the instance is not public",
213 %{conn: conn, user: user} do
214 instance =
215 Application.get_env(:pleroma, :instance)
216 |> Keyword.put(:public, false)
217
218 Application.put_env(:pleroma, :instance, instance)
219
220 conn
221 |> with_credentials(user.nickname, "test")
222 |> get("/api/statuses/public_and_external_timeline.json")
223 |> json_response(200)
224
225 instance =
226 Application.get_env(:pleroma, :instance)
227 |> Keyword.put(:public, true)
228
229 Application.put_env(:pleroma, :instance, instance)
230 end
231
232 test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
233 conn
234 |> get("/api/statuses/public_and_external_timeline.json")
235 |> json_response(200)
236 end
237
238 test "returns 200 to authenticated request when the instance is public",
239 %{conn: conn, user: user} do
240 conn
241 |> with_credentials(user.nickname, "test")
242 |> get("/api/statuses/public_and_external_timeline.json")
243 |> json_response(200)
244 end
245 end
246
247 describe "GET /statuses/show/:id.json" do
248 test "returns one status", %{conn: conn} do
249 user = insert(:user)
250 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey!"})
251 actor = Repo.get_by!(User, ap_id: activity.data["actor"])
252
253 conn =
254 conn
255 |> get("/api/statuses/show/#{activity.id}.json")
256
257 response = json_response(conn, 200)
258
259 assert response == ActivityRepresenter.to_map(activity, %{user: actor})
260 end
261 end
262
263 describe "GET /users/show.json" do
264 test "gets user with screen_name", %{conn: conn} do
265 user = insert(:user)
266
267 conn =
268 conn
269 |> get("/api/users/show.json", %{"screen_name" => user.nickname})
270
271 response = json_response(conn, 200)
272
273 assert response["id"] == user.id
274 end
275
276 test "gets user with user_id", %{conn: conn} do
277 user = insert(:user)
278
279 conn =
280 conn
281 |> get("/api/users/show.json", %{"user_id" => user.id})
282
283 response = json_response(conn, 200)
284
285 assert response["id"] == user.id
286 end
287
288 test "gets a user for a logged in user", %{conn: conn} do
289 user = insert(:user)
290 logged_in = insert(:user)
291
292 {:ok, logged_in, user, _activity} = TwitterAPI.follow(logged_in, %{"user_id" => user.id})
293
294 conn =
295 conn
296 |> with_credentials(logged_in.nickname, "test")
297 |> get("/api/users/show.json", %{"user_id" => user.id})
298
299 response = json_response(conn, 200)
300
301 assert response["following"] == true
302 end
303 end
304
305 describe "GET /statusnet/conversation/:id.json" do
306 test "returns the statuses in the conversation", %{conn: conn} do
307 {:ok, _user} = UserBuilder.insert()
308 {:ok, activity} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
309 {:ok, _activity_two} = ActivityBuilder.insert(%{"type" => "Create", "context" => "2hu"})
310 {:ok, _activity_three} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
311
312 conn =
313 conn
314 |> get("/api/statusnet/conversation/#{activity.data["context_id"]}.json")
315
316 response = json_response(conn, 200)
317
318 assert length(response) == 2
319 end
320 end
321
322 describe "GET /statuses/friends_timeline.json" do
323 setup [:valid_user]
324
325 test "without valid credentials", %{conn: conn} do
326 conn = get(conn, "/api/statuses/friends_timeline.json")
327 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
328 end
329
330 test "with credentials", %{conn: conn, user: current_user} do
331 user = insert(:user)
332
333 activities =
334 ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
335
336 returned_activities =
337 ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
338
339 other_user = insert(:user)
340 ActivityBuilder.insert_list(10, %{}, %{user: other_user})
341 since_id = List.last(activities).id
342
343 current_user =
344 Changeset.change(current_user, following: [User.ap_followers(user)])
345 |> Repo.update!()
346
347 conn =
348 conn
349 |> with_credentials(current_user.nickname, "test")
350 |> get("/api/statuses/friends_timeline.json", %{since_id: since_id})
351
352 response = json_response(conn, 200)
353
354 assert length(response) == 10
355
356 assert response ==
357 Enum.map(returned_activities, fn activity ->
358 ActivityRepresenter.to_map(activity, %{
359 user: User.get_cached_by_ap_id(activity.data["actor"]),
360 for: current_user
361 })
362 end)
363 end
364 end
365
366 describe "GET /statuses/dm_timeline.json" do
367 test "it show direct messages", %{conn: conn} do
368 user_one = insert(:user)
369 user_two = insert(:user)
370
371 {:ok, user_two} = User.follow(user_two, user_one)
372
373 {:ok, direct} =
374 CommonAPI.post(user_one, %{
375 "status" => "Hi @#{user_two.nickname}!",
376 "visibility" => "direct"
377 })
378
379 {:ok, direct_two} =
380 CommonAPI.post(user_two, %{
381 "status" => "Hi @#{user_one.nickname}!",
382 "visibility" => "direct"
383 })
384
385 {:ok, _follower_only} =
386 CommonAPI.post(user_one, %{
387 "status" => "Hi @#{user_two.nickname}!",
388 "visibility" => "private"
389 })
390
391 # Only direct should be visible here
392 res_conn =
393 conn
394 |> assign(:user, user_two)
395 |> get("/api/statuses/dm_timeline.json")
396
397 [status, status_two] = json_response(res_conn, 200)
398 assert status["id"] == direct_two.id
399 assert status_two["id"] == direct.id
400 end
401 end
402
403 describe "GET /statuses/mentions.json" do
404 setup [:valid_user]
405
406 test "without valid credentials", %{conn: conn} do
407 conn = get(conn, "/api/statuses/mentions.json")
408 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
409 end
410
411 test "with credentials", %{conn: conn, user: current_user} do
412 {:ok, activity} =
413 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: current_user})
414
415 conn =
416 conn
417 |> with_credentials(current_user.nickname, "test")
418 |> get("/api/statuses/mentions.json")
419
420 response = json_response(conn, 200)
421
422 assert length(response) == 1
423
424 assert Enum.at(response, 0) ==
425 ActivityRepresenter.to_map(activity, %{
426 user: current_user,
427 for: current_user,
428 mentioned: [current_user]
429 })
430 end
431 end
432
433 describe "GET /api/qvitter/statuses/notifications.json" do
434 setup [:valid_user]
435
436 test "without valid credentials", %{conn: conn} do
437 conn = get(conn, "/api/qvitter/statuses/notifications.json")
438 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
439 end
440
441 test "with credentials", %{conn: conn, user: current_user} do
442 other_user = insert(:user)
443
444 {:ok, _activity} =
445 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
446
447 conn =
448 conn
449 |> with_credentials(current_user.nickname, "test")
450 |> get("/api/qvitter/statuses/notifications.json")
451
452 response = json_response(conn, 200)
453
454 assert length(response) == 1
455
456 assert response ==
457 NotificationView.render("notification.json", %{
458 notifications: Notification.for_user(current_user),
459 for: current_user
460 })
461 end
462 end
463
464 describe "POST /api/qvitter/statuses/notifications/read" do
465 setup [:valid_user]
466
467 test "without valid credentials", %{conn: conn} do
468 conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
469 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
470 end
471
472 test "with credentials, without any params", %{conn: conn, user: current_user} do
473 conn =
474 conn
475 |> with_credentials(current_user.nickname, "test")
476 |> post("/api/qvitter/statuses/notifications/read")
477
478 assert json_response(conn, 400) == %{
479 "error" => "You need to specify latest_id",
480 "request" => "/api/qvitter/statuses/notifications/read"
481 }
482 end
483
484 test "with credentials, with params", %{conn: conn, user: current_user} do
485 other_user = insert(:user)
486
487 {:ok, _activity} =
488 ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
489
490 response_conn =
491 conn
492 |> with_credentials(current_user.nickname, "test")
493 |> get("/api/qvitter/statuses/notifications.json")
494
495 [notification] = response = json_response(response_conn, 200)
496
497 assert length(response) == 1
498
499 assert notification["is_seen"] == 0
500
501 response_conn =
502 conn
503 |> with_credentials(current_user.nickname, "test")
504 |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
505
506 [notification] = response = json_response(response_conn, 200)
507
508 assert length(response) == 1
509
510 assert notification["is_seen"] == 1
511 end
512 end
513
514 describe "GET /statuses/user_timeline.json" do
515 setup [:valid_user]
516
517 test "without any params", %{conn: conn} do
518 conn = get(conn, "/api/statuses/user_timeline.json")
519
520 assert json_response(conn, 400) == %{
521 "error" => "You need to specify screen_name or user_id",
522 "request" => "/api/statuses/user_timeline.json"
523 }
524 end
525
526 test "with user_id", %{conn: conn} do
527 user = insert(:user)
528 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
529
530 conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
531 response = json_response(conn, 200)
532 assert length(response) == 1
533 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
534 end
535
536 test "with screen_name", %{conn: conn} do
537 user = insert(:user)
538 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
539
540 conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
541 response = json_response(conn, 200)
542 assert length(response) == 1
543 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
544 end
545
546 test "with credentials", %{conn: conn, user: current_user} do
547 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: current_user})
548
549 conn =
550 conn
551 |> with_credentials(current_user.nickname, "test")
552 |> get("/api/statuses/user_timeline.json")
553
554 response = json_response(conn, 200)
555
556 assert length(response) == 1
557
558 assert Enum.at(response, 0) ==
559 ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
560 end
561
562 test "with credentials with user_id", %{conn: conn, user: current_user} do
563 user = insert(:user)
564 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
565
566 conn =
567 conn
568 |> with_credentials(current_user.nickname, "test")
569 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id})
570
571 response = json_response(conn, 200)
572
573 assert length(response) == 1
574 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
575 end
576
577 test "with credentials screen_name", %{conn: conn, user: current_user} do
578 user = insert(:user)
579 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1}, %{user: user})
580
581 conn =
582 conn
583 |> with_credentials(current_user.nickname, "test")
584 |> get("/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
585
586 response = json_response(conn, 200)
587
588 assert length(response) == 1
589 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
590 end
591
592 test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
593 user = insert(:user)
594 {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
595 {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
596
597 conn =
598 conn
599 |> with_credentials(current_user.nickname, "test")
600 |> get("/api/statuses/user_timeline.json", %{
601 "user_id" => user.id,
602 "include_rts" => "false"
603 })
604
605 response = json_response(conn, 200)
606
607 assert length(response) == 1
608 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
609
610 conn =
611 conn
612 |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
613
614 response = json_response(conn, 200)
615
616 assert length(response) == 1
617 assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
618 end
619 end
620
621 describe "POST /friendships/create.json" do
622 setup [:valid_user]
623
624 test "without valid credentials", %{conn: conn} do
625 conn = post(conn, "/api/friendships/create.json")
626 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
627 end
628
629 test "with credentials", %{conn: conn, user: current_user} do
630 followed = insert(:user)
631
632 conn =
633 conn
634 |> with_credentials(current_user.nickname, "test")
635 |> post("/api/friendships/create.json", %{user_id: followed.id})
636
637 current_user = Repo.get(User, current_user.id)
638 assert User.ap_followers(followed) in current_user.following
639
640 assert json_response(conn, 200) ==
641 UserView.render("show.json", %{user: followed, for: current_user})
642 end
643
644 test "for restricted account", %{conn: conn, user: current_user} do
645 followed = insert(:user, info: %User.Info{locked: true})
646
647 conn =
648 conn
649 |> with_credentials(current_user.nickname, "test")
650 |> post("/api/friendships/create.json", %{user_id: followed.id})
651
652 current_user = Repo.get(User, current_user.id)
653 followed = Repo.get(User, followed.id)
654
655 refute User.ap_followers(followed) in current_user.following
656 assert followed.info.follow_request_count == 1
657
658 assert json_response(conn, 200) ==
659 UserView.render("show.json", %{user: followed, for: current_user})
660 end
661 end
662
663 describe "POST /friendships/destroy.json" do
664 setup [:valid_user]
665
666 test "without valid credentials", %{conn: conn} do
667 conn = post(conn, "/api/friendships/destroy.json")
668 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
669 end
670
671 test "with credentials", %{conn: conn, user: current_user} do
672 followed = insert(:user)
673
674 {:ok, current_user} = User.follow(current_user, followed)
675 assert User.ap_followers(followed) in current_user.following
676 ActivityPub.follow(current_user, followed)
677
678 conn =
679 conn
680 |> with_credentials(current_user.nickname, "test")
681 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
682
683 current_user = Repo.get(User, current_user.id)
684 assert current_user.following == [current_user.ap_id]
685
686 assert json_response(conn, 200) ==
687 UserView.render("show.json", %{user: followed, for: current_user})
688 end
689 end
690
691 describe "POST /blocks/create.json" do
692 setup [:valid_user]
693
694 test "without valid credentials", %{conn: conn} do
695 conn = post(conn, "/api/blocks/create.json")
696 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
697 end
698
699 test "with credentials", %{conn: conn, user: current_user} do
700 blocked = insert(:user)
701
702 conn =
703 conn
704 |> with_credentials(current_user.nickname, "test")
705 |> post("/api/blocks/create.json", %{user_id: blocked.id})
706
707 current_user = Repo.get(User, current_user.id)
708 assert User.blocks?(current_user, blocked)
709
710 assert json_response(conn, 200) ==
711 UserView.render("show.json", %{user: blocked, for: current_user})
712 end
713 end
714
715 describe "POST /blocks/destroy.json" do
716 setup [:valid_user]
717
718 test "without valid credentials", %{conn: conn} do
719 conn = post(conn, "/api/blocks/destroy.json")
720 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
721 end
722
723 test "with credentials", %{conn: conn, user: current_user} do
724 blocked = insert(:user)
725
726 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
727 assert User.blocks?(current_user, blocked)
728
729 conn =
730 conn
731 |> with_credentials(current_user.nickname, "test")
732 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
733
734 current_user = Repo.get(User, current_user.id)
735 assert current_user.info.blocks == []
736
737 assert json_response(conn, 200) ==
738 UserView.render("show.json", %{user: blocked, for: current_user})
739 end
740 end
741
742 describe "GET /help/test.json" do
743 test "returns \"ok\"", %{conn: conn} do
744 conn = get(conn, "/api/help/test.json")
745 assert json_response(conn, 200) == "ok"
746 end
747 end
748
749 describe "POST /api/qvitter/update_avatar.json" do
750 setup [:valid_user]
751
752 test "without valid credentials", %{conn: conn} do
753 conn = post(conn, "/api/qvitter/update_avatar.json")
754 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
755 end
756
757 test "with credentials", %{conn: conn, user: current_user} do
758 avatar_image = File.read!("test/fixtures/avatar_data_uri")
759
760 conn =
761 conn
762 |> with_credentials(current_user.nickname, "test")
763 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
764
765 current_user = Repo.get(User, current_user.id)
766 assert is_map(current_user.avatar)
767
768 assert json_response(conn, 200) ==
769 UserView.render("show.json", %{user: current_user, for: current_user})
770 end
771 end
772
773 describe "GET /api/qvitter/mutes.json" do
774 setup [:valid_user]
775
776 test "unimplemented mutes without valid credentials", %{conn: conn} do
777 conn = get(conn, "/api/qvitter/mutes.json")
778 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
779 end
780
781 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
782 response =
783 conn
784 |> with_credentials(current_user.nickname, "test")
785 |> get("/api/qvitter/mutes.json")
786 |> json_response(200)
787
788 assert [] = response
789 end
790 end
791
792 describe "POST /api/favorites/create/:id" do
793 setup [:valid_user]
794
795 test "without valid credentials", %{conn: conn} do
796 note_activity = insert(:note_activity)
797 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
798 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
799 end
800
801 test "with credentials", %{conn: conn, user: current_user} do
802 note_activity = insert(:note_activity)
803
804 conn =
805 conn
806 |> with_credentials(current_user.nickname, "test")
807 |> post("/api/favorites/create/#{note_activity.id}.json")
808
809 assert json_response(conn, 200)
810 end
811
812 test "with credentials, invalid param", %{conn: conn, user: current_user} do
813 conn =
814 conn
815 |> with_credentials(current_user.nickname, "test")
816 |> post("/api/favorites/create/wrong.json")
817
818 assert json_response(conn, 400)
819 end
820
821 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
822 conn =
823 conn
824 |> with_credentials(current_user.nickname, "test")
825 |> post("/api/favorites/create/1.json")
826
827 assert json_response(conn, 400)
828 end
829 end
830
831 describe "POST /api/favorites/destroy/:id" do
832 setup [:valid_user]
833
834 test "without valid credentials", %{conn: conn} do
835 note_activity = insert(:note_activity)
836 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
837 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
838 end
839
840 test "with credentials", %{conn: conn, user: current_user} do
841 note_activity = insert(:note_activity)
842 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
843 ActivityPub.like(current_user, object)
844
845 conn =
846 conn
847 |> with_credentials(current_user.nickname, "test")
848 |> post("/api/favorites/destroy/#{note_activity.id}.json")
849
850 assert json_response(conn, 200)
851 end
852 end
853
854 describe "POST /api/statuses/retweet/:id" do
855 setup [:valid_user]
856
857 test "without valid credentials", %{conn: conn} do
858 note_activity = insert(:note_activity)
859 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
860 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
861 end
862
863 test "with credentials", %{conn: conn, user: current_user} do
864 note_activity = insert(:note_activity)
865
866 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
867
868 response =
869 conn
870 |> with_credentials(current_user.nickname, "test")
871 |> post(request_path)
872
873 activity = Repo.get(Activity, note_activity.id)
874 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
875
876 assert json_response(response, 200) ==
877 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
878 end
879 end
880
881 describe "POST /api/statuses/unretweet/:id" do
882 setup [:valid_user]
883
884 test "without valid credentials", %{conn: conn} do
885 note_activity = insert(:note_activity)
886 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
887 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
888 end
889
890 test "with credentials", %{conn: conn, user: current_user} do
891 note_activity = insert(:note_activity)
892
893 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
894
895 _response =
896 conn
897 |> with_credentials(current_user.nickname, "test")
898 |> post(request_path)
899
900 request_path = String.replace(request_path, "retweet", "unretweet")
901
902 response =
903 conn
904 |> with_credentials(current_user.nickname, "test")
905 |> post(request_path)
906
907 activity = Repo.get(Activity, note_activity.id)
908 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
909
910 assert json_response(response, 200) ==
911 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
912 end
913 end
914
915 describe "POST /api/account/register" do
916 test "it creates a new user", %{conn: conn} do
917 data = %{
918 "nickname" => "lain",
919 "email" => "lain@wired.jp",
920 "fullname" => "lain iwakura",
921 "bio" => "close the world.",
922 "password" => "bear",
923 "confirm" => "bear"
924 }
925
926 conn =
927 conn
928 |> post("/api/account/register", data)
929
930 user = json_response(conn, 200)
931
932 fetched_user = Repo.get_by(User, nickname: "lain")
933 assert user == UserView.render("show.json", %{user: fetched_user})
934 end
935
936 test "it returns errors on a problem", %{conn: conn} do
937 data = %{
938 "email" => "lain@wired.jp",
939 "fullname" => "lain iwakura",
940 "bio" => "close the world.",
941 "password" => "bear",
942 "confirm" => "bear"
943 }
944
945 conn =
946 conn
947 |> post("/api/account/register", data)
948
949 errors = json_response(conn, 400)
950
951 assert is_binary(errors["error"])
952 end
953 end
954
955 describe "POST /api/account/password_reset, with valid parameters" do
956 setup %{conn: conn} do
957 user = insert(:user)
958 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
959 %{conn: conn, user: user}
960 end
961
962 test "it returns 204", %{conn: conn} do
963 assert json_response(conn, :no_content)
964 end
965
966 test "it creates a PasswordResetToken record for user", %{user: user} do
967 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
968 assert token_record
969 end
970
971 test "it sends an email to user", %{user: user} do
972 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
973
974 Swoosh.TestAssertions.assert_email_sent(
975 Pleroma.UserEmail.password_reset_email(user, token_record.token)
976 )
977 end
978 end
979
980 describe "POST /api/account/password_reset, with invalid parameters" do
981 setup [:valid_user]
982
983 test "it returns 500 when user is not found", %{conn: conn, user: user} do
984 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
985 assert json_response(conn, :internal_server_error)
986 end
987
988 test "it returns 500 when user is not local", %{conn: conn, user: user} do
989 {:ok, user} = Repo.update(Changeset.change(user, local: false))
990 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
991 assert json_response(conn, :internal_server_error)
992 end
993 end
994
995 describe "GET /api/account/confirm_email/:id/:token" do
996 setup do
997 user = insert(:user)
998 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
999
1000 {:ok, user} =
1001 user
1002 |> Changeset.change()
1003 |> Changeset.put_embed(:info, info_change)
1004 |> Repo.update()
1005
1006 assert user.info.confirmation_pending
1007
1008 [user: user]
1009 end
1010
1011 test "it redirects to root url", %{conn: conn, user: user} do
1012 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1013
1014 assert 302 == conn.status
1015 end
1016
1017 test "it confirms the user account", %{conn: conn, user: user} do
1018 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1019
1020 user = Repo.get(User, user.id)
1021
1022 refute user.info.confirmation_pending
1023 refute user.info.confirmation_token
1024 end
1025
1026 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1027 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1028
1029 assert 500 == conn.status
1030 end
1031
1032 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1033 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1034
1035 assert 500 == conn.status
1036 end
1037 end
1038
1039 describe "POST /api/account/resend_confirmation_email" do
1040 setup do
1041 setting = Pleroma.Config.get([:instance, :account_activation_required])
1042
1043 unless setting do
1044 Pleroma.Config.put([:instance, :account_activation_required], true)
1045 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1046 end
1047
1048 user = insert(:user)
1049 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1050
1051 {:ok, user} =
1052 user
1053 |> Changeset.change()
1054 |> Changeset.put_embed(:info, info_change)
1055 |> Repo.update()
1056
1057 assert user.info.confirmation_pending
1058
1059 [user: user]
1060 end
1061
1062 test "it returns 204 No Content", %{conn: conn, user: user} do
1063 conn
1064 |> assign(:user, user)
1065 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1066 |> json_response(:no_content)
1067 end
1068
1069 test "it sends confirmation email", %{conn: conn, user: user} do
1070 conn
1071 |> assign(:user, user)
1072 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1073
1074 Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
1075 end
1076 end
1077
1078 describe "GET /api/externalprofile/show" do
1079 test "it returns the user", %{conn: conn} do
1080 user = insert(:user)
1081 other_user = insert(:user)
1082
1083 conn =
1084 conn
1085 |> assign(:user, user)
1086 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1087
1088 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1089 end
1090 end
1091
1092 describe "GET /api/statuses/followers" do
1093 test "it returns a user's followers", %{conn: conn} do
1094 user = insert(:user)
1095 follower_one = insert(:user)
1096 follower_two = insert(:user)
1097 _not_follower = insert(:user)
1098
1099 {:ok, follower_one} = User.follow(follower_one, user)
1100 {:ok, follower_two} = User.follow(follower_two, user)
1101
1102 conn =
1103 conn
1104 |> assign(:user, user)
1105 |> get("/api/statuses/followers")
1106
1107 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1108 result = json_response(conn, 200)
1109 assert Enum.sort(expected) == Enum.sort(result)
1110 end
1111
1112 test "it returns 20 followers per page", %{conn: conn} do
1113 user = insert(:user)
1114 followers = insert_list(21, :user)
1115
1116 Enum.each(followers, fn follower ->
1117 User.follow(follower, user)
1118 end)
1119
1120 res_conn =
1121 conn
1122 |> assign(:user, user)
1123 |> get("/api/statuses/followers")
1124
1125 result = json_response(res_conn, 200)
1126 assert length(result) == 20
1127
1128 res_conn =
1129 conn
1130 |> assign(:user, user)
1131 |> get("/api/statuses/followers?page=2")
1132
1133 result = json_response(res_conn, 200)
1134 assert length(result) == 1
1135 end
1136
1137 test "it returns a given user's followers with user_id", %{conn: conn} do
1138 user = insert(:user)
1139 follower_one = insert(:user)
1140 follower_two = insert(:user)
1141 not_follower = insert(:user)
1142
1143 {:ok, follower_one} = User.follow(follower_one, user)
1144 {:ok, follower_two} = User.follow(follower_two, user)
1145
1146 conn =
1147 conn
1148 |> assign(:user, not_follower)
1149 |> get("/api/statuses/followers", %{"user_id" => user.id})
1150
1151 assert MapSet.equal?(
1152 MapSet.new(json_response(conn, 200)),
1153 MapSet.new(
1154 UserView.render("index.json", %{
1155 users: [follower_one, follower_two],
1156 for: not_follower
1157 })
1158 )
1159 )
1160 end
1161
1162 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1163 user = insert(:user, %{info: %{hide_followers: true}})
1164 follower_one = insert(:user)
1165 follower_two = insert(:user)
1166 not_follower = insert(:user)
1167
1168 {:ok, _follower_one} = User.follow(follower_one, user)
1169 {:ok, _follower_two} = User.follow(follower_two, user)
1170
1171 response =
1172 conn
1173 |> assign(:user, not_follower)
1174 |> get("/api/statuses/followers", %{"user_id" => user.id})
1175 |> json_response(200)
1176
1177 assert [] == response
1178 end
1179
1180 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1181 %{
1182 conn: conn
1183 } do
1184 user = insert(:user, %{info: %{hide_followers: true}})
1185 follower_one = insert(:user)
1186 follower_two = insert(:user)
1187 _not_follower = insert(:user)
1188
1189 {:ok, _follower_one} = User.follow(follower_one, user)
1190 {:ok, _follower_two} = User.follow(follower_two, user)
1191
1192 conn =
1193 conn
1194 |> assign(:user, user)
1195 |> get("/api/statuses/followers", %{"user_id" => user.id})
1196
1197 refute [] == json_response(conn, 200)
1198 end
1199 end
1200
1201 describe "GET /api/statuses/blocks" do
1202 test "it returns the list of users blocked by requester", %{conn: conn} do
1203 user = insert(:user)
1204 other_user = insert(:user)
1205
1206 {:ok, user} = User.block(user, other_user)
1207
1208 conn =
1209 conn
1210 |> assign(:user, user)
1211 |> get("/api/statuses/blocks")
1212
1213 expected = UserView.render("index.json", %{users: [other_user], for: user})
1214 result = json_response(conn, 200)
1215 assert Enum.sort(expected) == Enum.sort(result)
1216 end
1217 end
1218
1219 describe "GET /api/statuses/friends" do
1220 test "it returns the logged in user's friends", %{conn: conn} do
1221 user = insert(:user)
1222 followed_one = insert(:user)
1223 followed_two = insert(:user)
1224 _not_followed = insert(:user)
1225
1226 {:ok, user} = User.follow(user, followed_one)
1227 {:ok, user} = User.follow(user, followed_two)
1228
1229 conn =
1230 conn
1231 |> assign(:user, user)
1232 |> get("/api/statuses/friends")
1233
1234 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1235 result = json_response(conn, 200)
1236 assert Enum.sort(expected) == Enum.sort(result)
1237 end
1238
1239 test "it returns 20 friends per page", %{conn: conn} do
1240 user = insert(:user)
1241 followeds = insert_list(21, :user)
1242
1243 {:ok, user} =
1244 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1245 User.follow(user, followed)
1246 end)
1247
1248 res_conn =
1249 conn
1250 |> assign(:user, user)
1251 |> get("/api/statuses/friends")
1252
1253 result = json_response(res_conn, 200)
1254 assert length(result) == 20
1255
1256 res_conn =
1257 conn
1258 |> assign(:user, user)
1259 |> get("/api/statuses/friends", %{page: 2})
1260
1261 result = json_response(res_conn, 200)
1262 assert length(result) == 1
1263 end
1264
1265 test "it returns a given user's friends with user_id", %{conn: conn} do
1266 user = insert(:user)
1267 followed_one = insert(:user)
1268 followed_two = insert(:user)
1269 _not_followed = insert(:user)
1270
1271 {:ok, user} = User.follow(user, followed_one)
1272 {:ok, user} = User.follow(user, followed_two)
1273
1274 conn =
1275 conn
1276 |> assign(:user, user)
1277 |> get("/api/statuses/friends", %{"user_id" => user.id})
1278
1279 assert MapSet.equal?(
1280 MapSet.new(json_response(conn, 200)),
1281 MapSet.new(
1282 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1283 )
1284 )
1285 end
1286
1287 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1288 user = insert(:user, %{info: %{hide_follows: true}})
1289 followed_one = insert(:user)
1290 followed_two = insert(:user)
1291 not_followed = insert(:user)
1292
1293 {:ok, user} = User.follow(user, followed_one)
1294 {:ok, user} = User.follow(user, followed_two)
1295
1296 conn =
1297 conn
1298 |> assign(:user, not_followed)
1299 |> get("/api/statuses/friends", %{"user_id" => user.id})
1300
1301 assert [] == json_response(conn, 200)
1302 end
1303
1304 test "it returns friends when hide_follows is set to true if the user themselves request it",
1305 %{
1306 conn: conn
1307 } do
1308 user = insert(:user, %{info: %{hide_follows: true}})
1309 followed_one = insert(:user)
1310 followed_two = insert(:user)
1311 _not_followed = insert(:user)
1312
1313 {:ok, _user} = User.follow(user, followed_one)
1314 {:ok, _user} = User.follow(user, followed_two)
1315
1316 response =
1317 conn
1318 |> assign(:user, user)
1319 |> get("/api/statuses/friends", %{"user_id" => user.id})
1320 |> json_response(200)
1321
1322 refute [] == response
1323 end
1324
1325 test "it returns a given user's friends with screen_name", %{conn: conn} do
1326 user = insert(:user)
1327 followed_one = insert(:user)
1328 followed_two = insert(:user)
1329 _not_followed = insert(:user)
1330
1331 {:ok, user} = User.follow(user, followed_one)
1332 {:ok, user} = User.follow(user, followed_two)
1333
1334 conn =
1335 conn
1336 |> assign(:user, user)
1337 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1338
1339 assert MapSet.equal?(
1340 MapSet.new(json_response(conn, 200)),
1341 MapSet.new(
1342 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1343 )
1344 )
1345 end
1346 end
1347
1348 describe "GET /friends/ids" do
1349 test "it returns a user's friends", %{conn: conn} do
1350 user = insert(:user)
1351 followed_one = insert(:user)
1352 followed_two = insert(:user)
1353 _not_followed = insert(:user)
1354
1355 {:ok, user} = User.follow(user, followed_one)
1356 {:ok, user} = User.follow(user, followed_two)
1357
1358 conn =
1359 conn
1360 |> assign(:user, user)
1361 |> get("/api/friends/ids")
1362
1363 expected = [followed_one.id, followed_two.id]
1364
1365 assert MapSet.equal?(
1366 MapSet.new(Poison.decode!(json_response(conn, 200))),
1367 MapSet.new(expected)
1368 )
1369 end
1370 end
1371
1372 describe "POST /api/account/update_profile.json" do
1373 test "it updates a user's profile", %{conn: conn} do
1374 user = insert(:user)
1375 user2 = insert(:user)
1376
1377 conn =
1378 conn
1379 |> assign(:user, user)
1380 |> post("/api/account/update_profile.json", %{
1381 "name" => "new name",
1382 "description" => "hi @#{user2.nickname}"
1383 })
1384
1385 user = Repo.get!(User, user.id)
1386 assert user.name == "new name"
1387
1388 assert user.bio ==
1389 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1390 user2.ap_id
1391 }'>@<span>#{user2.nickname}</span></a></span>"
1392
1393 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1394 end
1395
1396 test "it sets and un-sets hide_follows", %{conn: conn} do
1397 user = insert(:user)
1398
1399 conn
1400 |> assign(:user, user)
1401 |> post("/api/account/update_profile.json", %{
1402 "hide_follows" => "true"
1403 })
1404
1405 user = Repo.get!(User, user.id)
1406 assert user.info.hide_follows == true
1407
1408 conn =
1409 conn
1410 |> assign(:user, user)
1411 |> post("/api/account/update_profile.json", %{
1412 "hide_follows" => "false"
1413 })
1414
1415 user = Repo.get!(User, user.id)
1416 assert user.info.hide_follows == false
1417 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1418 end
1419
1420 test "it sets and un-sets hide_followers", %{conn: conn} do
1421 user = insert(:user)
1422
1423 conn
1424 |> assign(:user, user)
1425 |> post("/api/account/update_profile.json", %{
1426 "hide_followers" => "true"
1427 })
1428
1429 user = Repo.get!(User, user.id)
1430 assert user.info.hide_followers == true
1431
1432 conn =
1433 conn
1434 |> assign(:user, user)
1435 |> post("/api/account/update_profile.json", %{
1436 "hide_followers" => "false"
1437 })
1438
1439 user = Repo.get!(User, user.id)
1440 assert user.info.hide_followers == false
1441 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1442 end
1443
1444 test "it sets and un-sets show_role", %{conn: conn} do
1445 user = insert(:user)
1446
1447 conn
1448 |> assign(:user, user)
1449 |> post("/api/account/update_profile.json", %{
1450 "show_role" => "true"
1451 })
1452
1453 user = Repo.get!(User, user.id)
1454 assert user.info.show_role == true
1455
1456 conn =
1457 conn
1458 |> assign(:user, user)
1459 |> post("/api/account/update_profile.json", %{
1460 "show_role" => "false"
1461 })
1462
1463 user = Repo.get!(User, user.id)
1464 assert user.info.show_role == false
1465 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1466 end
1467
1468 test "it locks an account", %{conn: conn} do
1469 user = insert(:user)
1470
1471 conn =
1472 conn
1473 |> assign(:user, user)
1474 |> post("/api/account/update_profile.json", %{
1475 "locked" => "true"
1476 })
1477
1478 user = Repo.get!(User, user.id)
1479 assert user.info.locked == true
1480
1481 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1482 end
1483
1484 test "it unlocks an account", %{conn: conn} do
1485 user = insert(:user)
1486
1487 conn =
1488 conn
1489 |> assign(:user, user)
1490 |> post("/api/account/update_profile.json", %{
1491 "locked" => "false"
1492 })
1493
1494 user = Repo.get!(User, user.id)
1495 assert user.info.locked == false
1496
1497 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1498 end
1499 end
1500
1501 defp valid_user(_context) do
1502 user = insert(:user)
1503 [user: user]
1504 end
1505
1506 defp with_credentials(conn, username, password) do
1507 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1508 put_req_header(conn, "authorization", header_content)
1509 end
1510
1511 describe "GET /api/search.json" do
1512 test "it returns search results", %{conn: conn} do
1513 user = insert(:user)
1514 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1515
1516 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1517 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1518
1519 conn =
1520 conn
1521 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1522
1523 assert [status] = json_response(conn, 200)
1524 assert status["id"] == activity.id
1525 end
1526 end
1527
1528 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1529 test "it returns the tags timeline", %{conn: conn} do
1530 user = insert(:user)
1531 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1532
1533 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1534 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1535
1536 conn =
1537 conn
1538 |> get("/api/statusnet/tags/timeline/2hu.json")
1539
1540 assert [status] = json_response(conn, 200)
1541 assert status["id"] == activity.id
1542 end
1543 end
1544
1545 test "Convert newlines to <br> in bio", %{conn: conn} do
1546 user = insert(:user)
1547
1548 _conn =
1549 conn
1550 |> assign(:user, user)
1551 |> post("/api/account/update_profile.json", %{
1552 "description" => "Hello,\r\nWorld! I\n am a test."
1553 })
1554
1555 user = Repo.get!(User, user.id)
1556 assert user.bio == "Hello,<br>World! I<br> am a test."
1557 end
1558
1559 describe "POST /api/pleroma/change_password" do
1560 setup [:valid_user]
1561
1562 test "without credentials", %{conn: conn} do
1563 conn = post(conn, "/api/pleroma/change_password")
1564 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1565 end
1566
1567 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1568 conn =
1569 conn
1570 |> with_credentials(current_user.nickname, "test")
1571 |> post("/api/pleroma/change_password", %{
1572 "password" => "hi",
1573 "new_password" => "newpass",
1574 "new_password_confirmation" => "newpass"
1575 })
1576
1577 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1578 end
1579
1580 test "with credentials, valid password and new password and confirmation not matching", %{
1581 conn: conn,
1582 user: current_user
1583 } do
1584 conn =
1585 conn
1586 |> with_credentials(current_user.nickname, "test")
1587 |> post("/api/pleroma/change_password", %{
1588 "password" => "test",
1589 "new_password" => "newpass",
1590 "new_password_confirmation" => "notnewpass"
1591 })
1592
1593 assert json_response(conn, 200) == %{
1594 "error" => "New password does not match confirmation."
1595 }
1596 end
1597
1598 test "with credentials, valid password and invalid new password", %{
1599 conn: conn,
1600 user: current_user
1601 } do
1602 conn =
1603 conn
1604 |> with_credentials(current_user.nickname, "test")
1605 |> post("/api/pleroma/change_password", %{
1606 "password" => "test",
1607 "new_password" => "",
1608 "new_password_confirmation" => ""
1609 })
1610
1611 assert json_response(conn, 200) == %{
1612 "error" => "New password can't be blank."
1613 }
1614 end
1615
1616 test "with credentials, valid password and matching new password and confirmation", %{
1617 conn: conn,
1618 user: current_user
1619 } do
1620 conn =
1621 conn
1622 |> with_credentials(current_user.nickname, "test")
1623 |> post("/api/pleroma/change_password", %{
1624 "password" => "test",
1625 "new_password" => "newpass",
1626 "new_password_confirmation" => "newpass"
1627 })
1628
1629 assert json_response(conn, 200) == %{"status" => "success"}
1630 fetched_user = Repo.get(User, current_user.id)
1631 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1632 end
1633 end
1634
1635 describe "POST /api/pleroma/delete_account" do
1636 setup [:valid_user]
1637
1638 test "without credentials", %{conn: conn} do
1639 conn = post(conn, "/api/pleroma/delete_account")
1640 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1641 end
1642
1643 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1644 conn =
1645 conn
1646 |> with_credentials(current_user.nickname, "test")
1647 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1648
1649 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1650 end
1651
1652 test "with credentials and valid password", %{conn: conn, user: current_user} do
1653 conn =
1654 conn
1655 |> with_credentials(current_user.nickname, "test")
1656 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1657
1658 assert json_response(conn, 200) == %{"status" => "success"}
1659 # Wait a second for the started task to end
1660 :timer.sleep(1000)
1661 end
1662 end
1663
1664 describe "GET /api/pleroma/friend_requests" do
1665 test "it lists friend requests" do
1666 user = insert(:user)
1667 other_user = insert(:user)
1668
1669 {:ok, _activity} = ActivityPub.follow(other_user, user)
1670
1671 user = Repo.get(User, user.id)
1672 other_user = Repo.get(User, other_user.id)
1673
1674 assert User.following?(other_user, user) == false
1675
1676 conn =
1677 build_conn()
1678 |> assign(:user, user)
1679 |> get("/api/pleroma/friend_requests")
1680
1681 assert [relationship] = json_response(conn, 200)
1682 assert other_user.id == relationship["id"]
1683 end
1684 end
1685
1686 describe "POST /api/pleroma/friendships/approve" do
1687 test "it approves a friend request" do
1688 user = insert(:user)
1689 other_user = insert(:user)
1690
1691 {:ok, _activity} = ActivityPub.follow(other_user, user)
1692
1693 user = Repo.get(User, user.id)
1694 other_user = Repo.get(User, other_user.id)
1695
1696 assert User.following?(other_user, user) == false
1697 assert user.info.follow_request_count == 1
1698
1699 conn =
1700 build_conn()
1701 |> assign(:user, user)
1702 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1703
1704 user = Repo.get(User, user.id)
1705
1706 assert relationship = json_response(conn, 200)
1707 assert other_user.id == relationship["id"]
1708 assert relationship["follows_you"] == true
1709 assert user.info.follow_request_count == 0
1710 end
1711 end
1712
1713 describe "POST /api/pleroma/friendships/deny" do
1714 test "it denies a friend request" do
1715 user = insert(:user)
1716 other_user = insert(:user)
1717
1718 {:ok, _activity} = ActivityPub.follow(other_user, user)
1719
1720 user = Repo.get(User, user.id)
1721 other_user = Repo.get(User, other_user.id)
1722
1723 assert User.following?(other_user, user) == false
1724 assert user.info.follow_request_count == 1
1725
1726 conn =
1727 build_conn()
1728 |> assign(:user, user)
1729 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1730
1731 user = Repo.get(User, user.id)
1732
1733 assert relationship = json_response(conn, 200)
1734 assert other_user.id == relationship["id"]
1735 assert relationship["follows_you"] == false
1736 assert user.info.follow_request_count == 0
1737 end
1738 end
1739
1740 describe "GET /api/pleroma/search_user" do
1741 test "it returns users, ordered by similarity", %{conn: conn} do
1742 user = insert(:user, %{name: "eal"})
1743 user_two = insert(:user, %{name: "eal me"})
1744 _user_three = insert(:user, %{name: "zzz"})
1745
1746 resp =
1747 conn
1748 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1749 |> json_response(200)
1750
1751 assert length(resp) == 2
1752 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1753 end
1754 end
1755
1756 describe "POST /api/media/upload" do
1757 setup context do
1758 Pleroma.DataCase.ensure_local_uploader(context)
1759 end
1760
1761 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1762 conn: conn
1763 } do
1764 user = insert(:user)
1765
1766 upload_filename = "test/fixtures/image_tmp.jpg"
1767 File.cp!("test/fixtures/image.jpg", upload_filename)
1768
1769 file = %Plug.Upload{
1770 content_type: "image/jpg",
1771 path: Path.absname(upload_filename),
1772 filename: "image.jpg"
1773 }
1774
1775 response =
1776 conn
1777 |> assign(:user, user)
1778 |> put_req_header("content-type", "application/octet-stream")
1779 |> post("/api/media/upload", %{
1780 "media" => file
1781 })
1782 |> json_response(:ok)
1783
1784 assert response["media_id"]
1785 object = Repo.get(Object, response["media_id"])
1786 assert object
1787 assert object.data["actor"] == User.ap_id(user)
1788 end
1789 end
1790
1791 describe "POST /api/media/metadata/create" do
1792 setup do
1793 object = insert(:note)
1794 user = User.get_by_ap_id(object.data["actor"])
1795 %{object: object, user: user}
1796 end
1797
1798 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1799 conn: conn,
1800 object: object
1801 } do
1802 initial_description = object.data["name"]
1803 another_user = insert(:user)
1804
1805 conn
1806 |> assign(:user, another_user)
1807 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1808 |> json_response(:forbidden)
1809
1810 object = Repo.get(Object, object.id)
1811 assert object.data["name"] == initial_description
1812 end
1813
1814 test "it updates `data[name]` of referenced Object with provided value", %{
1815 conn: conn,
1816 object: object,
1817 user: user
1818 } do
1819 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1820
1821 conn
1822 |> assign(:user, user)
1823 |> post("/api/media/metadata/create", %{
1824 "media_id" => object.id,
1825 "alt_text" => %{"text" => description}
1826 })
1827 |> json_response(:no_content)
1828
1829 object = Repo.get(Object, object.id)
1830 assert object.data["name"] == description
1831 end
1832 end
1833
1834 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1835 test "it returns a list of pinned statuses", %{conn: conn} do
1836 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1837
1838 user = insert(:user, %{name: "egor"})
1839 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1840 {:ok, _} = CommonAPI.pin(activity_id, user)
1841
1842 resp =
1843 conn
1844 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1845 |> json_response(200)
1846
1847 assert length(resp) == 1
1848 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1849 end
1850 end
1851
1852 describe "POST /api/statuses/pin/:id" do
1853 setup do
1854 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1855 [user: insert(:user)]
1856 end
1857
1858 test "without valid credentials", %{conn: conn} do
1859 note_activity = insert(:note_activity)
1860 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1861 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1862 end
1863
1864 test "with credentials", %{conn: conn, user: user} do
1865 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1866
1867 request_path = "/api/statuses/pin/#{activity.id}.json"
1868
1869 response =
1870 conn
1871 |> with_credentials(user.nickname, "test")
1872 |> post(request_path)
1873
1874 user = refresh_record(user)
1875
1876 assert json_response(response, 200) ==
1877 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1878 end
1879 end
1880
1881 describe "POST /api/statuses/unpin/:id" do
1882 setup do
1883 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1884 [user: insert(:user)]
1885 end
1886
1887 test "without valid credentials", %{conn: conn} do
1888 note_activity = insert(:note_activity)
1889 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1890 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1891 end
1892
1893 test "with credentials", %{conn: conn, user: user} do
1894 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1895 {:ok, activity} = CommonAPI.pin(activity.id, user)
1896
1897 request_path = "/api/statuses/unpin/#{activity.id}.json"
1898
1899 response =
1900 conn
1901 |> with_credentials(user.nickname, "test")
1902 |> post(request_path)
1903
1904 user = refresh_record(user)
1905
1906 assert json_response(response, 200) ==
1907 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1908 end
1909 end
1910 end