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