Add option to return all friends in twitter api.
[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 end
644
645 describe "POST /friendships/destroy.json" do
646 setup [:valid_user]
647
648 test "without valid credentials", %{conn: conn} do
649 conn = post(conn, "/api/friendships/destroy.json")
650 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
651 end
652
653 test "with credentials", %{conn: conn, user: current_user} do
654 followed = insert(:user)
655
656 {:ok, current_user} = User.follow(current_user, followed)
657 assert User.ap_followers(followed) in current_user.following
658 ActivityPub.follow(current_user, followed)
659
660 conn =
661 conn
662 |> with_credentials(current_user.nickname, "test")
663 |> post("/api/friendships/destroy.json", %{user_id: followed.id})
664
665 current_user = Repo.get(User, current_user.id)
666 assert current_user.following == [current_user.ap_id]
667
668 assert json_response(conn, 200) ==
669 UserView.render("show.json", %{user: followed, for: current_user})
670 end
671 end
672
673 describe "POST /blocks/create.json" do
674 setup [:valid_user]
675
676 test "without valid credentials", %{conn: conn} do
677 conn = post(conn, "/api/blocks/create.json")
678 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
679 end
680
681 test "with credentials", %{conn: conn, user: current_user} do
682 blocked = insert(:user)
683
684 conn =
685 conn
686 |> with_credentials(current_user.nickname, "test")
687 |> post("/api/blocks/create.json", %{user_id: blocked.id})
688
689 current_user = Repo.get(User, current_user.id)
690 assert User.blocks?(current_user, blocked)
691
692 assert json_response(conn, 200) ==
693 UserView.render("show.json", %{user: blocked, for: current_user})
694 end
695 end
696
697 describe "POST /blocks/destroy.json" do
698 setup [:valid_user]
699
700 test "without valid credentials", %{conn: conn} do
701 conn = post(conn, "/api/blocks/destroy.json")
702 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
703 end
704
705 test "with credentials", %{conn: conn, user: current_user} do
706 blocked = insert(:user)
707
708 {:ok, current_user, blocked} = TwitterAPI.block(current_user, %{"user_id" => blocked.id})
709 assert User.blocks?(current_user, blocked)
710
711 conn =
712 conn
713 |> with_credentials(current_user.nickname, "test")
714 |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
715
716 current_user = Repo.get(User, current_user.id)
717 assert current_user.info.blocks == []
718
719 assert json_response(conn, 200) ==
720 UserView.render("show.json", %{user: blocked, for: current_user})
721 end
722 end
723
724 describe "GET /help/test.json" do
725 test "returns \"ok\"", %{conn: conn} do
726 conn = get(conn, "/api/help/test.json")
727 assert json_response(conn, 200) == "ok"
728 end
729 end
730
731 describe "POST /api/qvitter/update_avatar.json" do
732 setup [:valid_user]
733
734 test "without valid credentials", %{conn: conn} do
735 conn = post(conn, "/api/qvitter/update_avatar.json")
736 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
737 end
738
739 test "with credentials", %{conn: conn, user: current_user} do
740 avatar_image = File.read!("test/fixtures/avatar_data_uri")
741
742 conn =
743 conn
744 |> with_credentials(current_user.nickname, "test")
745 |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
746
747 current_user = Repo.get(User, current_user.id)
748 assert is_map(current_user.avatar)
749
750 assert json_response(conn, 200) ==
751 UserView.render("show.json", %{user: current_user, for: current_user})
752 end
753 end
754
755 describe "GET /api/qvitter/mutes.json" do
756 setup [:valid_user]
757
758 test "unimplemented mutes without valid credentials", %{conn: conn} do
759 conn = get(conn, "/api/qvitter/mutes.json")
760 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
761 end
762
763 test "unimplemented mutes with credentials", %{conn: conn, user: current_user} do
764 response =
765 conn
766 |> with_credentials(current_user.nickname, "test")
767 |> get("/api/qvitter/mutes.json")
768 |> json_response(200)
769
770 assert [] = response
771 end
772 end
773
774 describe "POST /api/favorites/create/:id" do
775 setup [:valid_user]
776
777 test "without valid credentials", %{conn: conn} do
778 note_activity = insert(:note_activity)
779 conn = post(conn, "/api/favorites/create/#{note_activity.id}.json")
780 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
781 end
782
783 test "with credentials", %{conn: conn, user: current_user} do
784 note_activity = insert(:note_activity)
785
786 conn =
787 conn
788 |> with_credentials(current_user.nickname, "test")
789 |> post("/api/favorites/create/#{note_activity.id}.json")
790
791 assert json_response(conn, 200)
792 end
793
794 test "with credentials, invalid param", %{conn: conn, user: current_user} do
795 conn =
796 conn
797 |> with_credentials(current_user.nickname, "test")
798 |> post("/api/favorites/create/wrong.json")
799
800 assert json_response(conn, 400)
801 end
802
803 test "with credentials, invalid activity", %{conn: conn, user: current_user} do
804 conn =
805 conn
806 |> with_credentials(current_user.nickname, "test")
807 |> post("/api/favorites/create/1.json")
808
809 assert json_response(conn, 400)
810 end
811 end
812
813 describe "POST /api/favorites/destroy/:id" do
814 setup [:valid_user]
815
816 test "without valid credentials", %{conn: conn} do
817 note_activity = insert(:note_activity)
818 conn = post(conn, "/api/favorites/destroy/#{note_activity.id}.json")
819 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
820 end
821
822 test "with credentials", %{conn: conn, user: current_user} do
823 note_activity = insert(:note_activity)
824 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
825 ActivityPub.like(current_user, object)
826
827 conn =
828 conn
829 |> with_credentials(current_user.nickname, "test")
830 |> post("/api/favorites/destroy/#{note_activity.id}.json")
831
832 assert json_response(conn, 200)
833 end
834 end
835
836 describe "POST /api/statuses/retweet/:id" do
837 setup [:valid_user]
838
839 test "without valid credentials", %{conn: conn} do
840 note_activity = insert(:note_activity)
841 conn = post(conn, "/api/statuses/retweet/#{note_activity.id}.json")
842 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
843 end
844
845 test "with credentials", %{conn: conn, user: current_user} do
846 note_activity = insert(:note_activity)
847
848 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
849
850 response =
851 conn
852 |> with_credentials(current_user.nickname, "test")
853 |> post(request_path)
854
855 activity = Repo.get(Activity, note_activity.id)
856 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
857
858 assert json_response(response, 200) ==
859 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
860 end
861 end
862
863 describe "POST /api/statuses/unretweet/:id" do
864 setup [:valid_user]
865
866 test "without valid credentials", %{conn: conn} do
867 note_activity = insert(:note_activity)
868 conn = post(conn, "/api/statuses/unretweet/#{note_activity.id}.json")
869 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
870 end
871
872 test "with credentials", %{conn: conn, user: current_user} do
873 note_activity = insert(:note_activity)
874
875 request_path = "/api/statuses/retweet/#{note_activity.id}.json"
876
877 _response =
878 conn
879 |> with_credentials(current_user.nickname, "test")
880 |> post(request_path)
881
882 request_path = String.replace(request_path, "retweet", "unretweet")
883
884 response =
885 conn
886 |> with_credentials(current_user.nickname, "test")
887 |> post(request_path)
888
889 activity = Repo.get(Activity, note_activity.id)
890 activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
891
892 assert json_response(response, 200) ==
893 ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
894 end
895 end
896
897 describe "POST /api/account/register" do
898 test "it creates a new user", %{conn: conn} do
899 data = %{
900 "nickname" => "lain",
901 "email" => "lain@wired.jp",
902 "fullname" => "lain iwakura",
903 "bio" => "close the world.",
904 "password" => "bear",
905 "confirm" => "bear"
906 }
907
908 conn =
909 conn
910 |> post("/api/account/register", data)
911
912 user = json_response(conn, 200)
913
914 fetched_user = Repo.get_by(User, nickname: "lain")
915 assert user == UserView.render("show.json", %{user: fetched_user})
916 end
917
918 test "it returns errors on a problem", %{conn: conn} do
919 data = %{
920 "email" => "lain@wired.jp",
921 "fullname" => "lain iwakura",
922 "bio" => "close the world.",
923 "password" => "bear",
924 "confirm" => "bear"
925 }
926
927 conn =
928 conn
929 |> post("/api/account/register", data)
930
931 errors = json_response(conn, 400)
932
933 assert is_binary(errors["error"])
934 end
935 end
936
937 describe "POST /api/account/password_reset, with valid parameters" do
938 setup %{conn: conn} do
939 user = insert(:user)
940 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
941 %{conn: conn, user: user}
942 end
943
944 test "it returns 204", %{conn: conn} do
945 assert json_response(conn, :no_content)
946 end
947
948 test "it creates a PasswordResetToken record for user", %{user: user} do
949 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
950 assert token_record
951 end
952
953 test "it sends an email to user", %{user: user} do
954 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
955
956 Swoosh.TestAssertions.assert_email_sent(
957 Pleroma.UserEmail.password_reset_email(user, token_record.token)
958 )
959 end
960 end
961
962 describe "POST /api/account/password_reset, with invalid parameters" do
963 setup [:valid_user]
964
965 test "it returns 500 when user is not found", %{conn: conn, user: user} do
966 conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
967 assert json_response(conn, :internal_server_error)
968 end
969
970 test "it returns 500 when user is not local", %{conn: conn, user: user} do
971 {:ok, user} = Repo.update(Changeset.change(user, local: false))
972 conn = post(conn, "/api/account/password_reset?email=#{user.email}")
973 assert json_response(conn, :internal_server_error)
974 end
975 end
976
977 describe "GET /api/account/confirm_email/:id/:token" do
978 setup do
979 user = insert(:user)
980 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
981
982 {:ok, user} =
983 user
984 |> Changeset.change()
985 |> Changeset.put_embed(:info, info_change)
986 |> Repo.update()
987
988 assert user.info.confirmation_pending
989
990 [user: user]
991 end
992
993 test "it redirects to root url", %{conn: conn, user: user} do
994 conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
995
996 assert 302 == conn.status
997 end
998
999 test "it confirms the user account", %{conn: conn, user: user} do
1000 get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
1001
1002 user = Repo.get(User, user.id)
1003
1004 refute user.info.confirmation_pending
1005 refute user.info.confirmation_token
1006 end
1007
1008 test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
1009 conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
1010
1011 assert 500 == conn.status
1012 end
1013
1014 test "it returns 500 if token is invalid", %{conn: conn, user: user} do
1015 conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
1016
1017 assert 500 == conn.status
1018 end
1019 end
1020
1021 describe "POST /api/account/resend_confirmation_email" do
1022 setup do
1023 setting = Pleroma.Config.get([:instance, :account_activation_required])
1024
1025 unless setting do
1026 Pleroma.Config.put([:instance, :account_activation_required], true)
1027 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
1028 end
1029
1030 user = insert(:user)
1031 info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
1032
1033 {:ok, user} =
1034 user
1035 |> Changeset.change()
1036 |> Changeset.put_embed(:info, info_change)
1037 |> Repo.update()
1038
1039 assert user.info.confirmation_pending
1040
1041 [user: user]
1042 end
1043
1044 test "it returns 204 No Content", %{conn: conn, user: user} do
1045 conn
1046 |> assign(:user, user)
1047 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1048 |> json_response(:no_content)
1049 end
1050
1051 test "it sends confirmation email", %{conn: conn, user: user} do
1052 conn
1053 |> assign(:user, user)
1054 |> post("/api/account/resend_confirmation_email?email=#{user.email}")
1055
1056 Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
1057 end
1058 end
1059
1060 describe "GET /api/externalprofile/show" do
1061 test "it returns the user", %{conn: conn} do
1062 user = insert(:user)
1063 other_user = insert(:user)
1064
1065 conn =
1066 conn
1067 |> assign(:user, user)
1068 |> get("/api/externalprofile/show", %{profileurl: other_user.ap_id})
1069
1070 assert json_response(conn, 200) == UserView.render("show.json", %{user: other_user})
1071 end
1072 end
1073
1074 describe "GET /api/statuses/followers" do
1075 test "it returns a user's followers", %{conn: conn} do
1076 user = insert(:user)
1077 follower_one = insert(:user)
1078 follower_two = insert(:user)
1079 _not_follower = insert(:user)
1080
1081 {:ok, follower_one} = User.follow(follower_one, user)
1082 {:ok, follower_two} = User.follow(follower_two, user)
1083
1084 conn =
1085 conn
1086 |> assign(:user, user)
1087 |> get("/api/statuses/followers")
1088
1089 expected = UserView.render("index.json", %{users: [follower_one, follower_two], for: user})
1090 result = json_response(conn, 200)
1091 assert Enum.sort(expected) == Enum.sort(result)
1092 end
1093
1094 test "it returns 20 followers per page", %{conn: conn} do
1095 user = insert(:user)
1096 followers = insert_list(21, :user)
1097
1098 Enum.each(followers, fn follower ->
1099 User.follow(follower, user)
1100 end)
1101
1102 res_conn =
1103 conn
1104 |> assign(:user, user)
1105 |> get("/api/statuses/followers")
1106
1107 result = json_response(res_conn, 200)
1108 assert length(result) == 20
1109
1110 res_conn =
1111 conn
1112 |> assign(:user, user)
1113 |> get("/api/statuses/followers?page=2")
1114
1115 result = json_response(res_conn, 200)
1116 assert length(result) == 1
1117 end
1118
1119 test "it returns a given user's followers with user_id", %{conn: conn} do
1120 user = insert(:user)
1121 follower_one = insert(:user)
1122 follower_two = insert(:user)
1123 not_follower = insert(:user)
1124
1125 {:ok, follower_one} = User.follow(follower_one, user)
1126 {:ok, follower_two} = User.follow(follower_two, user)
1127
1128 conn =
1129 conn
1130 |> assign(:user, not_follower)
1131 |> get("/api/statuses/followers", %{"user_id" => user.id})
1132
1133 assert MapSet.equal?(
1134 MapSet.new(json_response(conn, 200)),
1135 MapSet.new(
1136 UserView.render("index.json", %{
1137 users: [follower_one, follower_two],
1138 for: not_follower
1139 })
1140 )
1141 )
1142 end
1143
1144 test "it returns empty when hide_followers is set to true", %{conn: conn} do
1145 user = insert(:user, %{info: %{hide_followers: true}})
1146 follower_one = insert(:user)
1147 follower_two = insert(:user)
1148 not_follower = insert(:user)
1149
1150 {:ok, _follower_one} = User.follow(follower_one, user)
1151 {:ok, _follower_two} = User.follow(follower_two, user)
1152
1153 response =
1154 conn
1155 |> assign(:user, not_follower)
1156 |> get("/api/statuses/followers", %{"user_id" => user.id})
1157 |> json_response(200)
1158
1159 assert [] == response
1160 end
1161
1162 test "it returns the followers when hide_followers is set to true if requested by the user themselves",
1163 %{
1164 conn: conn
1165 } do
1166 user = insert(:user, %{info: %{hide_followers: true}})
1167 follower_one = insert(:user)
1168 follower_two = insert(:user)
1169 _not_follower = insert(:user)
1170
1171 {:ok, _follower_one} = User.follow(follower_one, user)
1172 {:ok, _follower_two} = User.follow(follower_two, user)
1173
1174 conn =
1175 conn
1176 |> assign(:user, user)
1177 |> get("/api/statuses/followers", %{"user_id" => user.id})
1178
1179 refute [] == json_response(conn, 200)
1180 end
1181 end
1182
1183 describe "GET /api/statuses/blocks" do
1184 test "it returns the list of users blocked by requester", %{conn: conn} do
1185 user = insert(:user)
1186 other_user = insert(:user)
1187
1188 {:ok, user} = User.block(user, other_user)
1189
1190 conn =
1191 conn
1192 |> assign(:user, user)
1193 |> get("/api/statuses/blocks")
1194
1195 expected = UserView.render("index.json", %{users: [other_user], for: user})
1196 result = json_response(conn, 200)
1197 assert Enum.sort(expected) == Enum.sort(result)
1198 end
1199 end
1200
1201 describe "GET /api/statuses/friends" do
1202 test "it returns the logged in user's friends", %{conn: conn} do
1203 user = insert(:user)
1204 followed_one = insert(:user)
1205 followed_two = insert(:user)
1206 _not_followed = insert(:user)
1207
1208 {:ok, user} = User.follow(user, followed_one)
1209 {:ok, user} = User.follow(user, followed_two)
1210
1211 conn =
1212 conn
1213 |> assign(:user, user)
1214 |> get("/api/statuses/friends")
1215
1216 expected = UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1217 result = json_response(conn, 200)
1218 assert Enum.sort(expected) == Enum.sort(result)
1219 end
1220
1221 test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
1222 user = insert(:user)
1223 followeds = insert_list(21, :user)
1224
1225 {:ok, user} =
1226 Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
1227 User.follow(user, followed)
1228 end)
1229
1230 res_conn =
1231 conn
1232 |> assign(:user, user)
1233 |> get("/api/statuses/friends")
1234
1235 result = json_response(res_conn, 200)
1236 assert length(result) == 20
1237
1238 res_conn =
1239 conn
1240 |> assign(:user, user)
1241 |> get("/api/statuses/friends", %{page: 2})
1242
1243 result = json_response(res_conn, 200)
1244 assert length(result) == 1
1245
1246 res_conn =
1247 conn
1248 |> assign(:user, user)
1249 |> get("/api/statuses/friends", %{all: true})
1250
1251 result = json_response(res_conn, 200)
1252 assert length(result) == 21
1253 end
1254
1255 test "it returns a given user's friends with user_id", %{conn: conn} do
1256 user = insert(:user)
1257 followed_one = insert(:user)
1258 followed_two = insert(:user)
1259 _not_followed = insert(:user)
1260
1261 {:ok, user} = User.follow(user, followed_one)
1262 {:ok, user} = User.follow(user, followed_two)
1263
1264 conn =
1265 conn
1266 |> assign(:user, user)
1267 |> get("/api/statuses/friends", %{"user_id" => user.id})
1268
1269 assert MapSet.equal?(
1270 MapSet.new(json_response(conn, 200)),
1271 MapSet.new(
1272 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1273 )
1274 )
1275 end
1276
1277 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1278 user = insert(:user, %{info: %{hide_follows: true}})
1279 followed_one = insert(:user)
1280 followed_two = insert(:user)
1281 not_followed = insert(:user)
1282
1283 {:ok, user} = User.follow(user, followed_one)
1284 {:ok, user} = User.follow(user, followed_two)
1285
1286 conn =
1287 conn
1288 |> assign(:user, not_followed)
1289 |> get("/api/statuses/friends", %{"user_id" => user.id})
1290
1291 assert [] == json_response(conn, 200)
1292 end
1293
1294 test "it returns friends when hide_follows is set to true if the user themselves request it",
1295 %{
1296 conn: conn
1297 } do
1298 user = insert(:user, %{info: %{hide_follows: true}})
1299 followed_one = insert(:user)
1300 followed_two = insert(:user)
1301 _not_followed = insert(:user)
1302
1303 {:ok, _user} = User.follow(user, followed_one)
1304 {:ok, _user} = User.follow(user, followed_two)
1305
1306 response =
1307 conn
1308 |> assign(:user, user)
1309 |> get("/api/statuses/friends", %{"user_id" => user.id})
1310 |> json_response(200)
1311
1312 refute [] == response
1313 end
1314
1315 test "it returns a given user's friends with screen_name", %{conn: conn} do
1316 user = insert(:user)
1317 followed_one = insert(:user)
1318 followed_two = insert(:user)
1319 _not_followed = insert(:user)
1320
1321 {:ok, user} = User.follow(user, followed_one)
1322 {:ok, user} = User.follow(user, followed_two)
1323
1324 conn =
1325 conn
1326 |> assign(:user, user)
1327 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1328
1329 assert MapSet.equal?(
1330 MapSet.new(json_response(conn, 200)),
1331 MapSet.new(
1332 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1333 )
1334 )
1335 end
1336 end
1337
1338 describe "GET /friends/ids" do
1339 test "it returns a user's friends", %{conn: conn} do
1340 user = insert(:user)
1341 followed_one = insert(:user)
1342 followed_two = insert(:user)
1343 _not_followed = insert(:user)
1344
1345 {:ok, user} = User.follow(user, followed_one)
1346 {:ok, user} = User.follow(user, followed_two)
1347
1348 conn =
1349 conn
1350 |> assign(:user, user)
1351 |> get("/api/friends/ids")
1352
1353 expected = [followed_one.id, followed_two.id]
1354
1355 assert MapSet.equal?(
1356 MapSet.new(Poison.decode!(json_response(conn, 200))),
1357 MapSet.new(expected)
1358 )
1359 end
1360 end
1361
1362 describe "POST /api/account/update_profile.json" do
1363 test "it updates a user's profile", %{conn: conn} do
1364 user = insert(:user)
1365 user2 = insert(:user)
1366
1367 conn =
1368 conn
1369 |> assign(:user, user)
1370 |> post("/api/account/update_profile.json", %{
1371 "name" => "new name",
1372 "description" => "hi @#{user2.nickname}"
1373 })
1374
1375 user = Repo.get!(User, user.id)
1376 assert user.name == "new name"
1377
1378 assert user.bio ==
1379 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1380 user2.ap_id
1381 }'>@<span>#{user2.nickname}</span></a></span>"
1382
1383 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1384 end
1385
1386 test "it sets and un-sets hide_follows", %{conn: conn} do
1387 user = insert(:user)
1388
1389 conn
1390 |> assign(:user, user)
1391 |> post("/api/account/update_profile.json", %{
1392 "hide_follows" => "true"
1393 })
1394
1395 user = Repo.get!(User, user.id)
1396 assert user.info.hide_follows == true
1397
1398 conn =
1399 conn
1400 |> assign(:user, user)
1401 |> post("/api/account/update_profile.json", %{
1402 "hide_follows" => "false"
1403 })
1404
1405 user = Repo.get!(User, user.id)
1406 assert user.info.hide_follows == false
1407 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1408 end
1409
1410 test "it sets and un-sets hide_followers", %{conn: conn} do
1411 user = insert(:user)
1412
1413 conn
1414 |> assign(:user, user)
1415 |> post("/api/account/update_profile.json", %{
1416 "hide_followers" => "true"
1417 })
1418
1419 user = Repo.get!(User, user.id)
1420 assert user.info.hide_followers == true
1421
1422 conn =
1423 conn
1424 |> assign(:user, user)
1425 |> post("/api/account/update_profile.json", %{
1426 "hide_followers" => "false"
1427 })
1428
1429 user = Repo.get!(User, user.id)
1430 assert user.info.hide_followers == false
1431 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1432 end
1433
1434 test "it sets and un-sets show_role", %{conn: conn} do
1435 user = insert(:user)
1436
1437 conn
1438 |> assign(:user, user)
1439 |> post("/api/account/update_profile.json", %{
1440 "show_role" => "true"
1441 })
1442
1443 user = Repo.get!(User, user.id)
1444 assert user.info.show_role == true
1445
1446 conn =
1447 conn
1448 |> assign(:user, user)
1449 |> post("/api/account/update_profile.json", %{
1450 "show_role" => "false"
1451 })
1452
1453 user = Repo.get!(User, user.id)
1454 assert user.info.show_role == false
1455 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1456 end
1457
1458 test "it locks an account", %{conn: conn} do
1459 user = insert(:user)
1460
1461 conn =
1462 conn
1463 |> assign(:user, user)
1464 |> post("/api/account/update_profile.json", %{
1465 "locked" => "true"
1466 })
1467
1468 user = Repo.get!(User, user.id)
1469 assert user.info.locked == true
1470
1471 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1472 end
1473
1474 test "it unlocks an account", %{conn: conn} do
1475 user = insert(:user)
1476
1477 conn =
1478 conn
1479 |> assign(:user, user)
1480 |> post("/api/account/update_profile.json", %{
1481 "locked" => "false"
1482 })
1483
1484 user = Repo.get!(User, user.id)
1485 assert user.info.locked == false
1486
1487 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1488 end
1489 end
1490
1491 defp valid_user(_context) do
1492 user = insert(:user)
1493 [user: user]
1494 end
1495
1496 defp with_credentials(conn, username, password) do
1497 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1498 put_req_header(conn, "authorization", header_content)
1499 end
1500
1501 describe "GET /api/search.json" do
1502 test "it returns search results", %{conn: conn} do
1503 user = insert(:user)
1504 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1505
1506 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1507 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1508
1509 conn =
1510 conn
1511 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1512
1513 assert [status] = json_response(conn, 200)
1514 assert status["id"] == activity.id
1515 end
1516 end
1517
1518 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1519 test "it returns the tags timeline", %{conn: conn} do
1520 user = insert(:user)
1521 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1522
1523 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1524 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1525
1526 conn =
1527 conn
1528 |> get("/api/statusnet/tags/timeline/2hu.json")
1529
1530 assert [status] = json_response(conn, 200)
1531 assert status["id"] == activity.id
1532 end
1533 end
1534
1535 test "Convert newlines to <br> in bio", %{conn: conn} do
1536 user = insert(:user)
1537
1538 _conn =
1539 conn
1540 |> assign(:user, user)
1541 |> post("/api/account/update_profile.json", %{
1542 "description" => "Hello,\r\nWorld! I\n am a test."
1543 })
1544
1545 user = Repo.get!(User, user.id)
1546 assert user.bio == "Hello,<br>World! I<br> am a test."
1547 end
1548
1549 describe "POST /api/pleroma/change_password" do
1550 setup [:valid_user]
1551
1552 test "without credentials", %{conn: conn} do
1553 conn = post(conn, "/api/pleroma/change_password")
1554 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1555 end
1556
1557 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1558 conn =
1559 conn
1560 |> with_credentials(current_user.nickname, "test")
1561 |> post("/api/pleroma/change_password", %{
1562 "password" => "hi",
1563 "new_password" => "newpass",
1564 "new_password_confirmation" => "newpass"
1565 })
1566
1567 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1568 end
1569
1570 test "with credentials, valid password and new password and confirmation not matching", %{
1571 conn: conn,
1572 user: current_user
1573 } do
1574 conn =
1575 conn
1576 |> with_credentials(current_user.nickname, "test")
1577 |> post("/api/pleroma/change_password", %{
1578 "password" => "test",
1579 "new_password" => "newpass",
1580 "new_password_confirmation" => "notnewpass"
1581 })
1582
1583 assert json_response(conn, 200) == %{
1584 "error" => "New password does not match confirmation."
1585 }
1586 end
1587
1588 test "with credentials, valid password and invalid new password", %{
1589 conn: conn,
1590 user: current_user
1591 } do
1592 conn =
1593 conn
1594 |> with_credentials(current_user.nickname, "test")
1595 |> post("/api/pleroma/change_password", %{
1596 "password" => "test",
1597 "new_password" => "",
1598 "new_password_confirmation" => ""
1599 })
1600
1601 assert json_response(conn, 200) == %{
1602 "error" => "New password can't be blank."
1603 }
1604 end
1605
1606 test "with credentials, valid password and matching new password and confirmation", %{
1607 conn: conn,
1608 user: current_user
1609 } do
1610 conn =
1611 conn
1612 |> with_credentials(current_user.nickname, "test")
1613 |> post("/api/pleroma/change_password", %{
1614 "password" => "test",
1615 "new_password" => "newpass",
1616 "new_password_confirmation" => "newpass"
1617 })
1618
1619 assert json_response(conn, 200) == %{"status" => "success"}
1620 fetched_user = Repo.get(User, current_user.id)
1621 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1622 end
1623 end
1624
1625 describe "POST /api/pleroma/delete_account" do
1626 setup [:valid_user]
1627
1628 test "without credentials", %{conn: conn} do
1629 conn = post(conn, "/api/pleroma/delete_account")
1630 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1631 end
1632
1633 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1634 conn =
1635 conn
1636 |> with_credentials(current_user.nickname, "test")
1637 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1638
1639 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1640 end
1641
1642 test "with credentials and valid password", %{conn: conn, user: current_user} do
1643 conn =
1644 conn
1645 |> with_credentials(current_user.nickname, "test")
1646 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1647
1648 assert json_response(conn, 200) == %{"status" => "success"}
1649 # Wait a second for the started task to end
1650 :timer.sleep(1000)
1651 end
1652 end
1653
1654 describe "GET /api/pleroma/friend_requests" do
1655 test "it lists friend requests" do
1656 user = insert(:user)
1657 other_user = insert(:user)
1658
1659 {:ok, _activity} = ActivityPub.follow(other_user, user)
1660
1661 user = Repo.get(User, user.id)
1662 other_user = Repo.get(User, other_user.id)
1663
1664 assert User.following?(other_user, user) == false
1665
1666 conn =
1667 build_conn()
1668 |> assign(:user, user)
1669 |> get("/api/pleroma/friend_requests")
1670
1671 assert [relationship] = json_response(conn, 200)
1672 assert other_user.id == relationship["id"]
1673 end
1674 end
1675
1676 describe "POST /api/pleroma/friendships/approve" do
1677 test "it approves a friend request" do
1678 user = insert(:user)
1679 other_user = insert(:user)
1680
1681 {:ok, _activity} = ActivityPub.follow(other_user, user)
1682
1683 user = Repo.get(User, user.id)
1684 other_user = Repo.get(User, other_user.id)
1685
1686 assert User.following?(other_user, user) == false
1687
1688 conn =
1689 build_conn()
1690 |> assign(:user, user)
1691 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1692
1693 assert relationship = json_response(conn, 200)
1694 assert other_user.id == relationship["id"]
1695 assert relationship["follows_you"] == true
1696 end
1697 end
1698
1699 describe "POST /api/pleroma/friendships/deny" do
1700 test "it denies a friend request" do
1701 user = insert(:user)
1702 other_user = insert(:user)
1703
1704 {:ok, _activity} = ActivityPub.follow(other_user, user)
1705
1706 user = Repo.get(User, user.id)
1707 other_user = Repo.get(User, other_user.id)
1708
1709 assert User.following?(other_user, user) == false
1710
1711 conn =
1712 build_conn()
1713 |> assign(:user, user)
1714 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1715
1716 assert relationship = json_response(conn, 200)
1717 assert other_user.id == relationship["id"]
1718 assert relationship["follows_you"] == false
1719 end
1720 end
1721
1722 describe "GET /api/pleroma/search_user" do
1723 test "it returns users, ordered by similarity", %{conn: conn} do
1724 user = insert(:user, %{name: "eal"})
1725 user_two = insert(:user, %{name: "eal me"})
1726 _user_three = insert(:user, %{name: "zzz"})
1727
1728 resp =
1729 conn
1730 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1731 |> json_response(200)
1732
1733 assert length(resp) == 2
1734 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1735 end
1736 end
1737
1738 describe "POST /api/media/upload" do
1739 setup context do
1740 Pleroma.DataCase.ensure_local_uploader(context)
1741 end
1742
1743 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1744 conn: conn
1745 } do
1746 user = insert(:user)
1747
1748 upload_filename = "test/fixtures/image_tmp.jpg"
1749 File.cp!("test/fixtures/image.jpg", upload_filename)
1750
1751 file = %Plug.Upload{
1752 content_type: "image/jpg",
1753 path: Path.absname(upload_filename),
1754 filename: "image.jpg"
1755 }
1756
1757 response =
1758 conn
1759 |> assign(:user, user)
1760 |> put_req_header("content-type", "application/octet-stream")
1761 |> post("/api/media/upload", %{
1762 "media" => file
1763 })
1764 |> json_response(:ok)
1765
1766 assert response["media_id"]
1767 object = Repo.get(Object, response["media_id"])
1768 assert object
1769 assert object.data["actor"] == User.ap_id(user)
1770 end
1771 end
1772
1773 describe "POST /api/media/metadata/create" do
1774 setup do
1775 object = insert(:note)
1776 user = User.get_by_ap_id(object.data["actor"])
1777 %{object: object, user: user}
1778 end
1779
1780 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1781 conn: conn,
1782 object: object
1783 } do
1784 initial_description = object.data["name"]
1785 another_user = insert(:user)
1786
1787 conn
1788 |> assign(:user, another_user)
1789 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1790 |> json_response(:forbidden)
1791
1792 object = Repo.get(Object, object.id)
1793 assert object.data["name"] == initial_description
1794 end
1795
1796 test "it updates `data[name]` of referenced Object with provided value", %{
1797 conn: conn,
1798 object: object,
1799 user: user
1800 } do
1801 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1802
1803 conn
1804 |> assign(:user, user)
1805 |> post("/api/media/metadata/create", %{
1806 "media_id" => object.id,
1807 "alt_text" => %{"text" => description}
1808 })
1809 |> json_response(:no_content)
1810
1811 object = Repo.get(Object, object.id)
1812 assert object.data["name"] == description
1813 end
1814 end
1815
1816 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1817 test "it returns a list of pinned statuses", %{conn: conn} do
1818 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1819
1820 user = insert(:user, %{name: "egor"})
1821 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1822 {:ok, _} = CommonAPI.pin(activity_id, user)
1823
1824 resp =
1825 conn
1826 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1827 |> json_response(200)
1828
1829 assert length(resp) == 1
1830 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1831 end
1832 end
1833
1834 describe "POST /api/statuses/pin/:id" do
1835 setup do
1836 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1837 [user: insert(:user)]
1838 end
1839
1840 test "without valid credentials", %{conn: conn} do
1841 note_activity = insert(:note_activity)
1842 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1843 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1844 end
1845
1846 test "with credentials", %{conn: conn, user: user} do
1847 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1848
1849 request_path = "/api/statuses/pin/#{activity.id}.json"
1850
1851 response =
1852 conn
1853 |> with_credentials(user.nickname, "test")
1854 |> post(request_path)
1855
1856 user = refresh_record(user)
1857
1858 assert json_response(response, 200) ==
1859 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1860 end
1861 end
1862
1863 describe "POST /api/statuses/unpin/:id" do
1864 setup do
1865 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1866 [user: insert(:user)]
1867 end
1868
1869 test "without valid credentials", %{conn: conn} do
1870 note_activity = insert(:note_activity)
1871 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1872 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1873 end
1874
1875 test "with credentials", %{conn: conn, user: user} do
1876 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1877 {:ok, activity} = CommonAPI.pin(activity.id, user)
1878
1879 request_path = "/api/statuses/unpin/#{activity.id}.json"
1880
1881 response =
1882 conn
1883 |> with_credentials(user.nickname, "test")
1884 |> post(request_path)
1885
1886 user = refresh_record(user)
1887
1888 assert json_response(response, 200) ==
1889 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1890 end
1891 end
1892 end