Merge branch 'capture-test-errors' into 'develop'
[akkoma] / test / web / twitter_api / util_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.UtilControllerTest do
6 use Pleroma.Web.ConnCase
7
8 alias Pleroma.Repo
9 alias Pleroma.User
10 alias Pleroma.Web.CommonAPI
11 import ExUnit.CaptureLog
12 import Pleroma.Factory
13 import Mock
14
15 setup do
16 Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
17 :ok
18 end
19
20 clear_config([:instance])
21 clear_config([:frontend_configurations, :pleroma_fe])
22 clear_config([:user, :deny_follow_blocked])
23
24 describe "POST /api/pleroma/follow_import" do
25 test "it returns HTTP 200", %{conn: conn} do
26 user1 = insert(:user)
27 user2 = insert(:user)
28
29 response =
30 conn
31 |> assign(:user, user1)
32 |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"})
33 |> json_response(:ok)
34
35 assert response == "job started"
36 end
37
38 test "it imports follow lists from file", %{conn: conn} do
39 user1 = insert(:user)
40 user2 = insert(:user)
41
42 with_mocks([
43 {File, [],
44 read!: fn "follow_list.txt" ->
45 "Account address,Show boosts\n#{user2.ap_id},true"
46 end},
47 {PleromaJobQueue, [:passthrough], []}
48 ]) do
49 response =
50 conn
51 |> assign(:user, user1)
52 |> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}})
53 |> json_response(:ok)
54
55 assert called(
56 PleromaJobQueue.enqueue(
57 :background,
58 User,
59 [:follow_import, user1, [user2.ap_id]]
60 )
61 )
62
63 assert response == "job started"
64 end
65 end
66
67 test "it imports new-style mastodon follow lists", %{conn: conn} do
68 user1 = insert(:user)
69 user2 = insert(:user)
70
71 response =
72 conn
73 |> assign(:user, user1)
74 |> post("/api/pleroma/follow_import", %{
75 "list" => "Account address,Show boosts\n#{user2.ap_id},true"
76 })
77 |> json_response(:ok)
78
79 assert response == "job started"
80 end
81
82 test "requires 'follow' permission", %{conn: conn} do
83 token1 = insert(:oauth_token, scopes: ["read", "write"])
84 token2 = insert(:oauth_token, scopes: ["follow"])
85 another_user = insert(:user)
86
87 for token <- [token1, token2] do
88 conn =
89 conn
90 |> put_req_header("authorization", "Bearer #{token.token}")
91 |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
92
93 if token == token1 do
94 assert %{"error" => "Insufficient permissions: follow."} == json_response(conn, 403)
95 else
96 assert json_response(conn, 200)
97 end
98 end
99 end
100 end
101
102 describe "POST /api/pleroma/blocks_import" do
103 test "it returns HTTP 200", %{conn: conn} do
104 user1 = insert(:user)
105 user2 = insert(:user)
106
107 response =
108 conn
109 |> assign(:user, user1)
110 |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"})
111 |> json_response(:ok)
112
113 assert response == "job started"
114 end
115
116 test "it imports blocks users from file", %{conn: conn} do
117 user1 = insert(:user)
118 user2 = insert(:user)
119 user3 = insert(:user)
120
121 with_mocks([
122 {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end},
123 {PleromaJobQueue, [:passthrough], []}
124 ]) do
125 response =
126 conn
127 |> assign(:user, user1)
128 |> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}})
129 |> json_response(:ok)
130
131 assert called(
132 PleromaJobQueue.enqueue(
133 :background,
134 User,
135 [:blocks_import, user1, [user2.ap_id, user3.ap_id]]
136 )
137 )
138
139 assert response == "job started"
140 end
141 end
142 end
143
144 describe "PUT /api/pleroma/notification_settings" do
145 test "it updates notification settings", %{conn: conn} do
146 user = insert(:user)
147
148 conn
149 |> assign(:user, user)
150 |> put("/api/pleroma/notification_settings", %{
151 "followers" => false,
152 "bar" => 1
153 })
154 |> json_response(:ok)
155
156 user = Repo.get(User, user.id)
157
158 assert %{
159 "followers" => false,
160 "follows" => true,
161 "non_follows" => true,
162 "non_followers" => true
163 } == user.info.notification_settings
164 end
165 end
166
167 describe "GET /api/statusnet/config" do
168 test "it returns config in xml format", %{conn: conn} do
169 instance = Pleroma.Config.get(:instance)
170
171 response =
172 conn
173 |> put_req_header("accept", "application/xml")
174 |> get("/api/statusnet/config")
175 |> response(:ok)
176
177 assert response ==
178 "<config>\n<site>\n<name>#{Keyword.get(instance, :name)}</name>\n<site>#{
179 Pleroma.Web.base_url()
180 }</site>\n<textlimit>#{Keyword.get(instance, :limit)}</textlimit>\n<closed>#{
181 !Keyword.get(instance, :registrations_open)
182 }</closed>\n</site>\n</config>\n"
183 end
184
185 test "it returns config in json format", %{conn: conn} do
186 instance = Pleroma.Config.get(:instance)
187 Pleroma.Config.put([:instance, :managed_config], true)
188 Pleroma.Config.put([:instance, :registrations_open], false)
189 Pleroma.Config.put([:instance, :invites_enabled], true)
190 Pleroma.Config.put([:instance, :public], false)
191 Pleroma.Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"})
192
193 response =
194 conn
195 |> put_req_header("accept", "application/json")
196 |> get("/api/statusnet/config")
197 |> json_response(:ok)
198
199 expected_data = %{
200 "site" => %{
201 "accountActivationRequired" => "0",
202 "closed" => "1",
203 "description" => Keyword.get(instance, :description),
204 "invitesEnabled" => "1",
205 "name" => Keyword.get(instance, :name),
206 "pleromafe" => %{"theme" => "asuka-hospital"},
207 "private" => "1",
208 "safeDMMentionsEnabled" => "0",
209 "server" => Pleroma.Web.base_url(),
210 "textlimit" => to_string(Keyword.get(instance, :limit)),
211 "uploadlimit" => %{
212 "avatarlimit" => to_string(Keyword.get(instance, :avatar_upload_limit)),
213 "backgroundlimit" => to_string(Keyword.get(instance, :background_upload_limit)),
214 "bannerlimit" => to_string(Keyword.get(instance, :banner_upload_limit)),
215 "uploadlimit" => to_string(Keyword.get(instance, :upload_limit))
216 },
217 "vapidPublicKey" => Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
218 }
219 }
220
221 assert response == expected_data
222 end
223
224 test "returns the state of safe_dm_mentions flag", %{conn: conn} do
225 Pleroma.Config.put([:instance, :safe_dm_mentions], true)
226
227 response =
228 conn
229 |> get("/api/statusnet/config.json")
230 |> json_response(:ok)
231
232 assert response["site"]["safeDMMentionsEnabled"] == "1"
233
234 Pleroma.Config.put([:instance, :safe_dm_mentions], false)
235
236 response =
237 conn
238 |> get("/api/statusnet/config.json")
239 |> json_response(:ok)
240
241 assert response["site"]["safeDMMentionsEnabled"] == "0"
242 end
243
244 test "it returns the managed config", %{conn: conn} do
245 Pleroma.Config.put([:instance, :managed_config], false)
246 Pleroma.Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"})
247
248 response =
249 conn
250 |> get("/api/statusnet/config.json")
251 |> json_response(:ok)
252
253 refute response["site"]["pleromafe"]
254
255 Pleroma.Config.put([:instance, :managed_config], true)
256
257 response =
258 conn
259 |> get("/api/statusnet/config.json")
260 |> json_response(:ok)
261
262 assert response["site"]["pleromafe"] == %{"theme" => "asuka-hospital"}
263 end
264 end
265
266 describe "GET /api/pleroma/frontend_configurations" do
267 test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} do
268 config = [
269 frontend_a: %{
270 x: 1,
271 y: 2
272 },
273 frontend_b: %{
274 z: 3
275 }
276 ]
277
278 Pleroma.Config.put(:frontend_configurations, config)
279
280 response =
281 conn
282 |> get("/api/pleroma/frontend_configurations")
283 |> json_response(:ok)
284
285 assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!()
286 end
287 end
288
289 describe "/api/pleroma/emoji" do
290 test "returns json with custom emoji with tags", %{conn: conn} do
291 emoji =
292 conn
293 |> get("/api/pleroma/emoji")
294 |> json_response(200)
295
296 assert Enum.all?(emoji, fn
297 {_key,
298 %{
299 "image_url" => url,
300 "tags" => tags
301 }} ->
302 is_binary(url) and is_list(tags)
303 end)
304 end
305 end
306
307 describe "GET /ostatus_subscribe - remote_follow/2" do
308 test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do
309 conn =
310 get(
311 conn,
312 "/ostatus_subscribe?acct=https://mastodon.social/users/emelie/statuses/101849165031453009"
313 )
314
315 assert redirected_to(conn) =~ "/notice/"
316 end
317
318 test "show follow account page if the `acct` is a account link", %{conn: conn} do
319 response =
320 get(
321 conn,
322 "/ostatus_subscribe?acct=https://mastodon.social/users/emelie"
323 )
324
325 assert html_response(response, 200) =~ "Log in to follow"
326 end
327
328 test "show follow page if the `acct` is a account link", %{conn: conn} do
329 user = insert(:user)
330
331 response =
332 conn
333 |> assign(:user, user)
334 |> get("/ostatus_subscribe?acct=https://mastodon.social/users/emelie")
335
336 assert html_response(response, 200) =~ "Remote follow"
337 end
338
339 test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do
340 user = insert(:user)
341
342 assert capture_log(fn ->
343 response =
344 conn
345 |> assign(:user, user)
346 |> get("/ostatus_subscribe?acct=https://mastodon.social/users/not_found")
347
348 assert html_response(response, 200) =~ "Error fetching user"
349 end) =~ "Object has been deleted"
350 end
351 end
352
353 describe "POST /ostatus_subscribe - do_remote_follow/2 with assigned user " do
354 test "follows user", %{conn: conn} do
355 user = insert(:user)
356 user2 = insert(:user)
357
358 response =
359 conn
360 |> assign(:user, user)
361 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
362 |> response(200)
363
364 assert response =~ "Account followed!"
365 assert user2.follower_address in refresh_record(user).following
366 end
367
368 test "returns error when user is deactivated", %{conn: conn} do
369 user = insert(:user, info: %{deactivated: true})
370 user2 = insert(:user)
371
372 response =
373 conn
374 |> assign(:user, user)
375 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
376 |> response(200)
377
378 assert response =~ "Error following account"
379 end
380
381 test "returns error when user is blocked", %{conn: conn} do
382 Pleroma.Config.put([:user, :deny_follow_blocked], true)
383 user = insert(:user)
384 user2 = insert(:user)
385
386 {:ok, _user} = Pleroma.User.block(user2, user)
387
388 response =
389 conn
390 |> assign(:user, user)
391 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
392 |> response(200)
393
394 assert response =~ "Error following account"
395 end
396
397 test "returns error when followee not found", %{conn: conn} do
398 user = insert(:user)
399
400 response =
401 conn
402 |> assign(:user, user)
403 |> post("/ostatus_subscribe", %{"user" => %{"id" => "jimm"}})
404 |> response(200)
405
406 assert response =~ "Error following account"
407 end
408
409 test "returns success result when user already in followers", %{conn: conn} do
410 user = insert(:user)
411 user2 = insert(:user)
412 {:ok, _, _, _} = CommonAPI.follow(user, user2)
413
414 response =
415 conn
416 |> assign(:user, refresh_record(user))
417 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
418 |> response(200)
419
420 assert response =~ "Account followed!"
421 end
422 end
423
424 describe "POST /ostatus_subscribe - do_remote_follow/2 without assigned user " do
425 test "follows", %{conn: conn} do
426 user = insert(:user)
427 user2 = insert(:user)
428
429 response =
430 conn
431 |> post("/ostatus_subscribe", %{
432 "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
433 })
434 |> response(200)
435
436 assert response =~ "Account followed!"
437 assert user2.follower_address in refresh_record(user).following
438 end
439
440 test "returns error when followee not found", %{conn: conn} do
441 user = insert(:user)
442
443 response =
444 conn
445 |> post("/ostatus_subscribe", %{
446 "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"}
447 })
448 |> response(200)
449
450 assert response =~ "Error following account"
451 end
452
453 test "returns error when login invalid", %{conn: conn} do
454 user = insert(:user)
455
456 response =
457 conn
458 |> post("/ostatus_subscribe", %{
459 "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id}
460 })
461 |> response(200)
462
463 assert response =~ "Wrong username or password"
464 end
465
466 test "returns error when password invalid", %{conn: conn} do
467 user = insert(:user)
468 user2 = insert(:user)
469
470 response =
471 conn
472 |> post("/ostatus_subscribe", %{
473 "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id}
474 })
475 |> response(200)
476
477 assert response =~ "Wrong username or password"
478 end
479
480 test "returns error when user is blocked", %{conn: conn} do
481 Pleroma.Config.put([:user, :deny_follow_blocked], true)
482 user = insert(:user)
483 user2 = insert(:user)
484 {:ok, _user} = Pleroma.User.block(user2, user)
485
486 response =
487 conn
488 |> post("/ostatus_subscribe", %{
489 "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
490 })
491 |> response(200)
492
493 assert response =~ "Error following account"
494 end
495 end
496
497 describe "GET /api/pleroma/healthcheck" do
498 clear_config([:instance, :healthcheck])
499
500 test "returns 503 when healthcheck disabled", %{conn: conn} do
501 Pleroma.Config.put([:instance, :healthcheck], false)
502
503 response =
504 conn
505 |> get("/api/pleroma/healthcheck")
506 |> json_response(503)
507
508 assert response == %{}
509 end
510
511 test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do
512 Pleroma.Config.put([:instance, :healthcheck], true)
513
514 with_mock Pleroma.Healthcheck,
515 system_info: fn -> %Pleroma.Healthcheck{healthy: true} end do
516 response =
517 conn
518 |> get("/api/pleroma/healthcheck")
519 |> json_response(200)
520
521 assert %{
522 "active" => _,
523 "healthy" => true,
524 "idle" => _,
525 "memory_used" => _,
526 "pool_size" => _
527 } = response
528 end
529 end
530
531 test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do
532 Pleroma.Config.put([:instance, :healthcheck], true)
533
534 with_mock Pleroma.Healthcheck,
535 system_info: fn -> %Pleroma.Healthcheck{healthy: false} end do
536 response =
537 conn
538 |> get("/api/pleroma/healthcheck")
539 |> json_response(503)
540
541 assert %{
542 "active" => _,
543 "healthy" => false,
544 "idle" => _,
545 "memory_used" => _,
546 "pool_size" => _
547 } = response
548 end
549 end
550 end
551
552 describe "POST /api/pleroma/disable_account" do
553 test "it returns HTTP 200", %{conn: conn} do
554 user = insert(:user)
555
556 response =
557 conn
558 |> assign(:user, user)
559 |> post("/api/pleroma/disable_account", %{"password" => "test"})
560 |> json_response(:ok)
561
562 assert response == %{"status" => "success"}
563
564 user = User.get_cached_by_id(user.id)
565
566 assert user.info.deactivated == true
567 end
568
569 test "it returns returns when password invalid", %{conn: conn} do
570 user = insert(:user)
571
572 response =
573 conn
574 |> assign(:user, user)
575 |> post("/api/pleroma/disable_account", %{"password" => "test1"})
576 |> json_response(:ok)
577
578 assert response == %{"error" => "Invalid password."}
579 user = User.get_cached_by_id(user.id)
580
581 refute user.info.deactivated
582 end
583 end
584
585 describe "GET /api/statusnet/version" do
586 test "it returns version in xml format", %{conn: conn} do
587 response =
588 conn
589 |> put_req_header("accept", "application/xml")
590 |> get("/api/statusnet/version")
591 |> response(:ok)
592
593 assert response == "<version>#{Pleroma.Application.named_version()}</version>"
594 end
595
596 test "it returns version in json format", %{conn: conn} do
597 response =
598 conn
599 |> put_req_header("accept", "application/json")
600 |> get("/api/statusnet/version")
601 |> json_response(:ok)
602
603 assert response == "#{Pleroma.Application.named_version()}"
604 end
605 end
606
607 describe "POST /main/ostatus - remote_subscribe/2" do
608 test "renders subscribe form", %{conn: conn} do
609 user = insert(:user)
610
611 response =
612 conn
613 |> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
614 |> response(:ok)
615
616 refute response =~ "Could not find user"
617 assert response =~ "Remotely follow #{user.nickname}"
618 end
619
620 test "renders subscribe form with error when user not found", %{conn: conn} do
621 response =
622 conn
623 |> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
624 |> response(:ok)
625
626 assert response =~ "Could not find user"
627 refute response =~ "Remotely follow"
628 end
629
630 test "it redirect to webfinger url", %{conn: conn} do
631 user = insert(:user)
632 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
633
634 conn =
635 conn
636 |> post("/main/ostatus", %{
637 "user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
638 })
639
640 assert redirected_to(conn) ==
641 "https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
642 end
643
644 test "it renders form with error when use not found", %{conn: conn} do
645 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
646
647 response =
648 conn
649 |> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
650 |> response(:ok)
651
652 assert response =~ "Something went wrong."
653 end
654 end
655
656 test "it returns new captcha", %{conn: conn} do
657 with_mock Pleroma.Captcha,
658 new: fn -> "test_captcha" end do
659 resp =
660 conn
661 |> get("/api/pleroma/captcha")
662 |> response(200)
663
664 assert resp == "\"test_captcha\""
665 assert called(Pleroma.Captcha.new())
666 end
667 end
668
669 defp with_credentials(conn, username, password) do
670 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
671 put_req_header(conn, "authorization", header_content)
672 end
673
674 defp valid_user(_context) do
675 user = insert(:user)
676 [user: user]
677 end
678
679 describe "POST /api/pleroma/change_email" do
680 setup [:valid_user]
681
682 test "without credentials", %{conn: conn} do
683 conn = post(conn, "/api/pleroma/change_email")
684 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
685 end
686
687 test "with credentials and invalid password", %{conn: conn, user: current_user} do
688 conn =
689 conn
690 |> with_credentials(current_user.nickname, "test")
691 |> post("/api/pleroma/change_email", %{
692 "password" => "hi",
693 "email" => "test@test.com"
694 })
695
696 assert json_response(conn, 200) == %{"error" => "Invalid password."}
697 end
698
699 test "with credentials, valid password and invalid email", %{
700 conn: conn,
701 user: current_user
702 } do
703 conn =
704 conn
705 |> with_credentials(current_user.nickname, "test")
706 |> post("/api/pleroma/change_email", %{
707 "password" => "test",
708 "email" => "foobar"
709 })
710
711 assert json_response(conn, 200) == %{"error" => "Email has invalid format."}
712 end
713
714 test "with credentials, valid password and no email", %{
715 conn: conn,
716 user: current_user
717 } do
718 conn =
719 conn
720 |> with_credentials(current_user.nickname, "test")
721 |> post("/api/pleroma/change_email", %{
722 "password" => "test"
723 })
724
725 assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
726 end
727
728 test "with credentials, valid password and blank email", %{
729 conn: conn,
730 user: current_user
731 } do
732 conn =
733 conn
734 |> with_credentials(current_user.nickname, "test")
735 |> post("/api/pleroma/change_email", %{
736 "password" => "test",
737 "email" => ""
738 })
739
740 assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
741 end
742
743 test "with credentials, valid password and non unique email", %{
744 conn: conn,
745 user: current_user
746 } do
747 user = insert(:user)
748
749 conn =
750 conn
751 |> with_credentials(current_user.nickname, "test")
752 |> post("/api/pleroma/change_email", %{
753 "password" => "test",
754 "email" => user.email
755 })
756
757 assert json_response(conn, 200) == %{"error" => "Email has already been taken."}
758 end
759
760 test "with credentials, valid password and valid email", %{
761 conn: conn,
762 user: current_user
763 } do
764 conn =
765 conn
766 |> with_credentials(current_user.nickname, "test")
767 |> post("/api/pleroma/change_email", %{
768 "password" => "test",
769 "email" => "cofe@foobar.com"
770 })
771
772 assert json_response(conn, 200) == %{"status" => "success"}
773 end
774 end
775 end