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