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