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