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