Merge branch 'hellthread-filter-fix' into 'develop'
[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", %{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 end
1246
1247 test "it returns a given user's friends with user_id", %{conn: conn} do
1248 user = insert(:user)
1249 followed_one = insert(:user)
1250 followed_two = insert(:user)
1251 _not_followed = insert(:user)
1252
1253 {:ok, user} = User.follow(user, followed_one)
1254 {:ok, user} = User.follow(user, followed_two)
1255
1256 conn =
1257 conn
1258 |> assign(:user, user)
1259 |> get("/api/statuses/friends", %{"user_id" => user.id})
1260
1261 assert MapSet.equal?(
1262 MapSet.new(json_response(conn, 200)),
1263 MapSet.new(
1264 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1265 )
1266 )
1267 end
1268
1269 test "it returns empty when hide_follows is set to true", %{conn: conn} do
1270 user = insert(:user, %{info: %{hide_follows: true}})
1271 followed_one = insert(:user)
1272 followed_two = insert(:user)
1273 not_followed = insert(:user)
1274
1275 {:ok, user} = User.follow(user, followed_one)
1276 {:ok, user} = User.follow(user, followed_two)
1277
1278 conn =
1279 conn
1280 |> assign(:user, not_followed)
1281 |> get("/api/statuses/friends", %{"user_id" => user.id})
1282
1283 assert [] == json_response(conn, 200)
1284 end
1285
1286 test "it returns friends when hide_follows is set to true if the user themselves request it",
1287 %{
1288 conn: conn
1289 } do
1290 user = insert(:user, %{info: %{hide_follows: true}})
1291 followed_one = insert(:user)
1292 followed_two = insert(:user)
1293 _not_followed = insert(:user)
1294
1295 {:ok, _user} = User.follow(user, followed_one)
1296 {:ok, _user} = User.follow(user, followed_two)
1297
1298 response =
1299 conn
1300 |> assign(:user, user)
1301 |> get("/api/statuses/friends", %{"user_id" => user.id})
1302 |> json_response(200)
1303
1304 refute [] == response
1305 end
1306
1307 test "it returns a given user's friends with screen_name", %{conn: conn} do
1308 user = insert(:user)
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 conn =
1317 conn
1318 |> assign(:user, user)
1319 |> get("/api/statuses/friends", %{"screen_name" => user.nickname})
1320
1321 assert MapSet.equal?(
1322 MapSet.new(json_response(conn, 200)),
1323 MapSet.new(
1324 UserView.render("index.json", %{users: [followed_one, followed_two], for: user})
1325 )
1326 )
1327 end
1328 end
1329
1330 describe "GET /friends/ids" do
1331 test "it returns a user's friends", %{conn: conn} do
1332 user = insert(:user)
1333 followed_one = insert(:user)
1334 followed_two = insert(:user)
1335 _not_followed = insert(:user)
1336
1337 {:ok, user} = User.follow(user, followed_one)
1338 {:ok, user} = User.follow(user, followed_two)
1339
1340 conn =
1341 conn
1342 |> assign(:user, user)
1343 |> get("/api/friends/ids")
1344
1345 expected = [followed_one.id, followed_two.id]
1346
1347 assert MapSet.equal?(
1348 MapSet.new(Poison.decode!(json_response(conn, 200))),
1349 MapSet.new(expected)
1350 )
1351 end
1352 end
1353
1354 describe "POST /api/account/update_profile.json" do
1355 test "it updates a user's profile", %{conn: conn} do
1356 user = insert(:user)
1357 user2 = insert(:user)
1358
1359 conn =
1360 conn
1361 |> assign(:user, user)
1362 |> post("/api/account/update_profile.json", %{
1363 "name" => "new name",
1364 "description" => "hi @#{user2.nickname}"
1365 })
1366
1367 user = Repo.get!(User, user.id)
1368 assert user.name == "new name"
1369
1370 assert user.bio ==
1371 "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
1372 user2.ap_id
1373 }'>@<span>#{user2.nickname}</span></a></span>"
1374
1375 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1376 end
1377
1378 test "it sets and un-sets hide_follows", %{conn: conn} do
1379 user = insert(:user)
1380
1381 conn
1382 |> assign(:user, user)
1383 |> post("/api/account/update_profile.json", %{
1384 "hide_follows" => "true"
1385 })
1386
1387 user = Repo.get!(User, user.id)
1388 assert user.info.hide_follows == true
1389
1390 conn =
1391 conn
1392 |> assign(:user, user)
1393 |> post("/api/account/update_profile.json", %{
1394 "hide_follows" => "false"
1395 })
1396
1397 user = Repo.get!(User, user.id)
1398 assert user.info.hide_follows == false
1399 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1400 end
1401
1402 test "it sets and un-sets hide_followers", %{conn: conn} do
1403 user = insert(:user)
1404
1405 conn
1406 |> assign(:user, user)
1407 |> post("/api/account/update_profile.json", %{
1408 "hide_followers" => "true"
1409 })
1410
1411 user = Repo.get!(User, user.id)
1412 assert user.info.hide_followers == true
1413
1414 conn =
1415 conn
1416 |> assign(:user, user)
1417 |> post("/api/account/update_profile.json", %{
1418 "hide_followers" => "false"
1419 })
1420
1421 user = Repo.get!(User, user.id)
1422 assert user.info.hide_followers == false
1423 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1424 end
1425
1426 test "it sets and un-sets show_role", %{conn: conn} do
1427 user = insert(:user)
1428
1429 conn
1430 |> assign(:user, user)
1431 |> post("/api/account/update_profile.json", %{
1432 "show_role" => "true"
1433 })
1434
1435 user = Repo.get!(User, user.id)
1436 assert user.info.show_role == true
1437
1438 conn =
1439 conn
1440 |> assign(:user, user)
1441 |> post("/api/account/update_profile.json", %{
1442 "show_role" => "false"
1443 })
1444
1445 user = Repo.get!(User, user.id)
1446 assert user.info.show_role == false
1447 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1448 end
1449
1450 test "it locks an account", %{conn: conn} do
1451 user = insert(:user)
1452
1453 conn =
1454 conn
1455 |> assign(:user, user)
1456 |> post("/api/account/update_profile.json", %{
1457 "locked" => "true"
1458 })
1459
1460 user = Repo.get!(User, user.id)
1461 assert user.info.locked == true
1462
1463 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1464 end
1465
1466 test "it unlocks an account", %{conn: conn} do
1467 user = insert(:user)
1468
1469 conn =
1470 conn
1471 |> assign(:user, user)
1472 |> post("/api/account/update_profile.json", %{
1473 "locked" => "false"
1474 })
1475
1476 user = Repo.get!(User, user.id)
1477 assert user.info.locked == false
1478
1479 assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
1480 end
1481 end
1482
1483 defp valid_user(_context) do
1484 user = insert(:user)
1485 [user: user]
1486 end
1487
1488 defp with_credentials(conn, username, password) do
1489 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
1490 put_req_header(conn, "authorization", header_content)
1491 end
1492
1493 describe "GET /api/search.json" do
1494 test "it returns search results", %{conn: conn} do
1495 user = insert(:user)
1496 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1497
1498 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1499 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1500
1501 conn =
1502 conn
1503 |> get("/api/search.json", %{"q" => "2hu", "page" => "1", "rpp" => "1"})
1504
1505 assert [status] = json_response(conn, 200)
1506 assert status["id"] == activity.id
1507 end
1508 end
1509
1510 describe "GET /api/statusnet/tags/timeline/:tag.json" do
1511 test "it returns the tags timeline", %{conn: conn} do
1512 user = insert(:user)
1513 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1514
1515 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about #2hu"})
1516 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1517
1518 conn =
1519 conn
1520 |> get("/api/statusnet/tags/timeline/2hu.json")
1521
1522 assert [status] = json_response(conn, 200)
1523 assert status["id"] == activity.id
1524 end
1525 end
1526
1527 test "Convert newlines to <br> in bio", %{conn: conn} do
1528 user = insert(:user)
1529
1530 _conn =
1531 conn
1532 |> assign(:user, user)
1533 |> post("/api/account/update_profile.json", %{
1534 "description" => "Hello,\r\nWorld! I\n am a test."
1535 })
1536
1537 user = Repo.get!(User, user.id)
1538 assert user.bio == "Hello,<br>World! I<br> am a test."
1539 end
1540
1541 describe "POST /api/pleroma/change_password" do
1542 setup [:valid_user]
1543
1544 test "without credentials", %{conn: conn} do
1545 conn = post(conn, "/api/pleroma/change_password")
1546 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1547 end
1548
1549 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1550 conn =
1551 conn
1552 |> with_credentials(current_user.nickname, "test")
1553 |> post("/api/pleroma/change_password", %{
1554 "password" => "hi",
1555 "new_password" => "newpass",
1556 "new_password_confirmation" => "newpass"
1557 })
1558
1559 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1560 end
1561
1562 test "with credentials, valid password and new password and confirmation not matching", %{
1563 conn: conn,
1564 user: current_user
1565 } do
1566 conn =
1567 conn
1568 |> with_credentials(current_user.nickname, "test")
1569 |> post("/api/pleroma/change_password", %{
1570 "password" => "test",
1571 "new_password" => "newpass",
1572 "new_password_confirmation" => "notnewpass"
1573 })
1574
1575 assert json_response(conn, 200) == %{
1576 "error" => "New password does not match confirmation."
1577 }
1578 end
1579
1580 test "with credentials, valid password and invalid new password", %{
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" => "",
1590 "new_password_confirmation" => ""
1591 })
1592
1593 assert json_response(conn, 200) == %{
1594 "error" => "New password can't be blank."
1595 }
1596 end
1597
1598 test "with credentials, valid password and matching new password and confirmation", %{
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" => "newpass",
1608 "new_password_confirmation" => "newpass"
1609 })
1610
1611 assert json_response(conn, 200) == %{"status" => "success"}
1612 fetched_user = Repo.get(User, current_user.id)
1613 assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
1614 end
1615 end
1616
1617 describe "POST /api/pleroma/delete_account" do
1618 setup [:valid_user]
1619
1620 test "without credentials", %{conn: conn} do
1621 conn = post(conn, "/api/pleroma/delete_account")
1622 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1623 end
1624
1625 test "with credentials and invalid password", %{conn: conn, user: current_user} do
1626 conn =
1627 conn
1628 |> with_credentials(current_user.nickname, "test")
1629 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
1630
1631 assert json_response(conn, 200) == %{"error" => "Invalid password."}
1632 end
1633
1634 test "with credentials and valid password", %{conn: conn, user: current_user} do
1635 conn =
1636 conn
1637 |> with_credentials(current_user.nickname, "test")
1638 |> post("/api/pleroma/delete_account", %{"password" => "test"})
1639
1640 assert json_response(conn, 200) == %{"status" => "success"}
1641 # Wait a second for the started task to end
1642 :timer.sleep(1000)
1643 end
1644 end
1645
1646 describe "GET /api/pleroma/friend_requests" do
1647 test "it lists friend requests" do
1648 user = insert(:user)
1649 other_user = insert(:user)
1650
1651 {:ok, _activity} = ActivityPub.follow(other_user, user)
1652
1653 user = Repo.get(User, user.id)
1654 other_user = Repo.get(User, other_user.id)
1655
1656 assert User.following?(other_user, user) == false
1657
1658 conn =
1659 build_conn()
1660 |> assign(:user, user)
1661 |> get("/api/pleroma/friend_requests")
1662
1663 assert [relationship] = json_response(conn, 200)
1664 assert other_user.id == relationship["id"]
1665 end
1666 end
1667
1668 describe "POST /api/pleroma/friendships/approve" do
1669 test "it approves a friend request" do
1670 user = insert(:user)
1671 other_user = insert(:user)
1672
1673 {:ok, _activity} = ActivityPub.follow(other_user, user)
1674
1675 user = Repo.get(User, user.id)
1676 other_user = Repo.get(User, other_user.id)
1677
1678 assert User.following?(other_user, user) == false
1679
1680 conn =
1681 build_conn()
1682 |> assign(:user, user)
1683 |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
1684
1685 assert relationship = json_response(conn, 200)
1686 assert other_user.id == relationship["id"]
1687 assert relationship["follows_you"] == true
1688 end
1689 end
1690
1691 describe "POST /api/pleroma/friendships/deny" do
1692 test "it denies a friend request" do
1693 user = insert(:user)
1694 other_user = insert(:user)
1695
1696 {:ok, _activity} = ActivityPub.follow(other_user, user)
1697
1698 user = Repo.get(User, user.id)
1699 other_user = Repo.get(User, other_user.id)
1700
1701 assert User.following?(other_user, user) == false
1702
1703 conn =
1704 build_conn()
1705 |> assign(:user, user)
1706 |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
1707
1708 assert relationship = json_response(conn, 200)
1709 assert other_user.id == relationship["id"]
1710 assert relationship["follows_you"] == false
1711 end
1712 end
1713
1714 describe "GET /api/pleroma/search_user" do
1715 test "it returns users, ordered by similarity", %{conn: conn} do
1716 user = insert(:user, %{name: "eal"})
1717 user_two = insert(:user, %{name: "eal me"})
1718 _user_three = insert(:user, %{name: "zzz"})
1719
1720 resp =
1721 conn
1722 |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
1723 |> json_response(200)
1724
1725 assert length(resp) == 2
1726 assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
1727 end
1728 end
1729
1730 describe "POST /api/media/upload" do
1731 setup context do
1732 Pleroma.DataCase.ensure_local_uploader(context)
1733 end
1734
1735 test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
1736 conn: conn
1737 } do
1738 user = insert(:user)
1739
1740 upload_filename = "test/fixtures/image_tmp.jpg"
1741 File.cp!("test/fixtures/image.jpg", upload_filename)
1742
1743 file = %Plug.Upload{
1744 content_type: "image/jpg",
1745 path: Path.absname(upload_filename),
1746 filename: "image.jpg"
1747 }
1748
1749 response =
1750 conn
1751 |> assign(:user, user)
1752 |> put_req_header("content-type", "application/octet-stream")
1753 |> post("/api/media/upload", %{
1754 "media" => file
1755 })
1756 |> json_response(:ok)
1757
1758 assert response["media_id"]
1759 object = Repo.get(Object, response["media_id"])
1760 assert object
1761 assert object.data["actor"] == User.ap_id(user)
1762 end
1763 end
1764
1765 describe "POST /api/media/metadata/create" do
1766 setup do
1767 object = insert(:note)
1768 user = User.get_by_ap_id(object.data["actor"])
1769 %{object: object, user: user}
1770 end
1771
1772 test "it returns :forbidden status on attempt to modify someone else's upload", %{
1773 conn: conn,
1774 object: object
1775 } do
1776 initial_description = object.data["name"]
1777 another_user = insert(:user)
1778
1779 conn
1780 |> assign(:user, another_user)
1781 |> post("/api/media/metadata/create", %{"media_id" => object.id})
1782 |> json_response(:forbidden)
1783
1784 object = Repo.get(Object, object.id)
1785 assert object.data["name"] == initial_description
1786 end
1787
1788 test "it updates `data[name]` of referenced Object with provided value", %{
1789 conn: conn,
1790 object: object,
1791 user: user
1792 } do
1793 description = "Informative description of the image. Initial value: #{object.data["name"]}}"
1794
1795 conn
1796 |> assign(:user, user)
1797 |> post("/api/media/metadata/create", %{
1798 "media_id" => object.id,
1799 "alt_text" => %{"text" => description}
1800 })
1801 |> json_response(:no_content)
1802
1803 object = Repo.get(Object, object.id)
1804 assert object.data["name"] == description
1805 end
1806 end
1807
1808 describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
1809 test "it returns a list of pinned statuses", %{conn: conn} do
1810 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1811
1812 user = insert(:user, %{name: "egor"})
1813 {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
1814 {:ok, _} = CommonAPI.pin(activity_id, user)
1815
1816 resp =
1817 conn
1818 |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
1819 |> json_response(200)
1820
1821 assert length(resp) == 1
1822 assert [%{"id" => ^activity_id, "pinned" => true}] = resp
1823 end
1824 end
1825
1826 describe "POST /api/statuses/pin/:id" do
1827 setup do
1828 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1829 [user: insert(:user)]
1830 end
1831
1832 test "without valid credentials", %{conn: conn} do
1833 note_activity = insert(:note_activity)
1834 conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
1835 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1836 end
1837
1838 test "with credentials", %{conn: conn, user: user} do
1839 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1840
1841 request_path = "/api/statuses/pin/#{activity.id}.json"
1842
1843 response =
1844 conn
1845 |> with_credentials(user.nickname, "test")
1846 |> post(request_path)
1847
1848 user = refresh_record(user)
1849
1850 assert json_response(response, 200) ==
1851 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1852 end
1853 end
1854
1855 describe "POST /api/statuses/unpin/:id" do
1856 setup do
1857 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1858 [user: insert(:user)]
1859 end
1860
1861 test "without valid credentials", %{conn: conn} do
1862 note_activity = insert(:note_activity)
1863 conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
1864 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
1865 end
1866
1867 test "with credentials", %{conn: conn, user: user} do
1868 {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
1869 {:ok, activity} = CommonAPI.pin(activity.id, user)
1870
1871 request_path = "/api/statuses/unpin/#{activity.id}.json"
1872
1873 response =
1874 conn
1875 |> with_credentials(user.nickname, "test")
1876 |> post(request_path)
1877
1878 user = refresh_record(user)
1879
1880 assert json_response(response, 200) ==
1881 ActivityRepresenter.to_map(activity, %{user: user, for: user})
1882 end
1883 end
1884 end