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