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