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