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