Merge branch 'develop' into refactor/notification_settings
[akkoma] / test / web / twitter_api / util_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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.Config
10 alias Pleroma.Tests.ObanHelpers
11 alias Pleroma.User
12
13 import Pleroma.Factory
14 import Mock
15
16 setup do
17 Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
18 :ok
19 end
20
21 setup do: clear_config([:instance])
22 setup do: clear_config([:frontend_configurations, :pleroma_fe])
23
24 describe "POST /api/pleroma/follow_import" do
25 setup do: oauth_access(["follow"])
26
27 test "it returns HTTP 200", %{conn: conn} do
28 user2 = insert(:user)
29
30 response =
31 conn
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", %{user: user1, conn: conn} do
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 ]) do
47 response =
48 conn
49 |> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}})
50 |> json_response(:ok)
51
52 assert response == "job started"
53
54 assert ObanHelpers.member?(
55 %{
56 "op" => "follow_import",
57 "follower_id" => user1.id,
58 "followed_identifiers" => [user2.ap_id]
59 },
60 all_enqueued(worker: Pleroma.Workers.BackgroundWorker)
61 )
62 end
63 end
64
65 test "it imports new-style mastodon follow lists", %{conn: conn} do
66 user2 = insert(:user)
67
68 response =
69 conn
70 |> post("/api/pleroma/follow_import", %{
71 "list" => "Account address,Show boosts\n#{user2.ap_id},true"
72 })
73 |> json_response(:ok)
74
75 assert response == "job started"
76 end
77
78 test "requires 'follow' or 'write:follows' permissions" do
79 token1 = insert(:oauth_token, scopes: ["read", "write"])
80 token2 = insert(:oauth_token, scopes: ["follow"])
81 token3 = insert(:oauth_token, scopes: ["something"])
82 another_user = insert(:user)
83
84 for token <- [token1, token2, token3] do
85 conn =
86 build_conn()
87 |> put_req_header("authorization", "Bearer #{token.token}")
88 |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
89
90 if token == token3 do
91 assert %{"error" => "Insufficient permissions: follow | write:follows."} ==
92 json_response(conn, 403)
93 else
94 assert json_response(conn, 200)
95 end
96 end
97 end
98
99 test "it imports follows with different nickname variations", %{conn: conn} do
100 [user2, user3, user4, user5, user6] = insert_list(5, :user)
101
102 identifiers =
103 [
104 user2.ap_id,
105 user3.nickname,
106 " ",
107 "@" <> user4.nickname,
108 user5.nickname <> "@localhost",
109 "@" <> user6.nickname <> "@localhost"
110 ]
111 |> Enum.join("\n")
112
113 response =
114 conn
115 |> post("/api/pleroma/follow_import", %{"list" => identifiers})
116 |> json_response(:ok)
117
118 assert response == "job started"
119 assert [{:ok, job_result}] = ObanHelpers.perform_all()
120 assert job_result == [user2, user3, user4, user5, user6]
121 end
122 end
123
124 describe "POST /api/pleroma/blocks_import" do
125 # Note: "follow" or "write:blocks" permission is required
126 setup do: oauth_access(["write:blocks"])
127
128 test "it returns HTTP 200", %{conn: conn} do
129 user2 = insert(:user)
130
131 response =
132 conn
133 |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"})
134 |> json_response(:ok)
135
136 assert response == "job started"
137 end
138
139 test "it imports blocks users from file", %{user: user1, conn: conn} do
140 user2 = insert(:user)
141 user3 = insert(:user)
142
143 with_mocks([
144 {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end}
145 ]) do
146 response =
147 conn
148 |> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}})
149 |> json_response(:ok)
150
151 assert response == "job started"
152
153 assert ObanHelpers.member?(
154 %{
155 "op" => "blocks_import",
156 "blocker_id" => user1.id,
157 "blocked_identifiers" => [user2.ap_id, user3.ap_id]
158 },
159 all_enqueued(worker: Pleroma.Workers.BackgroundWorker)
160 )
161 end
162 end
163
164 test "it imports blocks with different nickname variations", %{conn: conn} do
165 [user2, user3, user4, user5, user6] = insert_list(5, :user)
166
167 identifiers =
168 [
169 user2.ap_id,
170 user3.nickname,
171 "@" <> user4.nickname,
172 user5.nickname <> "@localhost",
173 "@" <> user6.nickname <> "@localhost"
174 ]
175 |> Enum.join(" ")
176
177 response =
178 conn
179 |> post("/api/pleroma/blocks_import", %{"list" => identifiers})
180 |> json_response(:ok)
181
182 assert response == "job started"
183 assert [{:ok, job_result}] = ObanHelpers.perform_all()
184 assert job_result == [user2, user3, user4, user5, user6]
185 end
186 end
187
188 describe "PUT /api/pleroma/notification_settings" do
189 setup do: oauth_access(["write:accounts"])
190
191 test "it updates notification settings", %{user: user, conn: conn} do
192 conn
193 |> put("/api/pleroma/notification_settings", %{
194 "block_from_strangers" => true,
195 "bar" => 1
196 })
197 |> json_response(:ok)
198
199 user = refresh_record(user)
200
201 assert %Pleroma.User.NotificationSetting{
202 block_from_strangers: true,
203 hide_notification_contents: false
204 } == user.notification_settings
205 end
206
207 test "it updates notification settings to enable hiding contents", %{user: user, conn: conn} do
208 conn
209 |> put("/api/pleroma/notification_settings", %{"hide_notification_contents" => "1"})
210 |> json_response(:ok)
211
212 user = refresh_record(user)
213
214 assert %Pleroma.User.NotificationSetting{
215 block_from_strangers: false,
216 hide_notification_contents: true
217 } == user.notification_settings
218 end
219 end
220
221 describe "GET /api/pleroma/frontend_configurations" do
222 test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} do
223 config = [
224 frontend_a: %{
225 x: 1,
226 y: 2
227 },
228 frontend_b: %{
229 z: 3
230 }
231 ]
232
233 Config.put(:frontend_configurations, config)
234
235 response =
236 conn
237 |> get("/api/pleroma/frontend_configurations")
238 |> json_response(:ok)
239
240 assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!()
241 end
242 end
243
244 describe "/api/pleroma/emoji" do
245 test "returns json with custom emoji with tags", %{conn: conn} do
246 emoji =
247 conn
248 |> get("/api/pleroma/emoji")
249 |> json_response(200)
250
251 assert Enum.all?(emoji, fn
252 {_key,
253 %{
254 "image_url" => url,
255 "tags" => tags
256 }} ->
257 is_binary(url) and is_list(tags)
258 end)
259 end
260 end
261
262 describe "GET /api/pleroma/healthcheck" do
263 setup do: clear_config([:instance, :healthcheck])
264
265 test "returns 503 when healthcheck disabled", %{conn: conn} do
266 Config.put([:instance, :healthcheck], false)
267
268 response =
269 conn
270 |> get("/api/pleroma/healthcheck")
271 |> json_response(503)
272
273 assert response == %{}
274 end
275
276 test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do
277 Config.put([:instance, :healthcheck], true)
278
279 with_mock Pleroma.Healthcheck,
280 system_info: fn -> %Pleroma.Healthcheck{healthy: true} end do
281 response =
282 conn
283 |> get("/api/pleroma/healthcheck")
284 |> json_response(200)
285
286 assert %{
287 "active" => _,
288 "healthy" => true,
289 "idle" => _,
290 "memory_used" => _,
291 "pool_size" => _
292 } = response
293 end
294 end
295
296 test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do
297 Config.put([:instance, :healthcheck], true)
298
299 with_mock Pleroma.Healthcheck,
300 system_info: fn -> %Pleroma.Healthcheck{healthy: false} end do
301 response =
302 conn
303 |> get("/api/pleroma/healthcheck")
304 |> json_response(503)
305
306 assert %{
307 "active" => _,
308 "healthy" => false,
309 "idle" => _,
310 "memory_used" => _,
311 "pool_size" => _
312 } = response
313 end
314 end
315 end
316
317 describe "POST /api/pleroma/disable_account" do
318 setup do: oauth_access(["write:accounts"])
319
320 test "with valid permissions and password, it disables the account", %{conn: conn, user: user} do
321 response =
322 conn
323 |> post("/api/pleroma/disable_account", %{"password" => "test"})
324 |> json_response(:ok)
325
326 assert response == %{"status" => "success"}
327 ObanHelpers.perform_all()
328
329 user = User.get_cached_by_id(user.id)
330
331 assert user.deactivated == true
332 end
333
334 test "with valid permissions and invalid password, it returns an error", %{conn: conn} do
335 user = insert(:user)
336
337 response =
338 conn
339 |> post("/api/pleroma/disable_account", %{"password" => "test1"})
340 |> json_response(:ok)
341
342 assert response == %{"error" => "Invalid password."}
343 user = User.get_cached_by_id(user.id)
344
345 refute user.deactivated
346 end
347 end
348
349 describe "POST /main/ostatus - remote_subscribe/2" do
350 setup do: clear_config([:instance, :federating], true)
351
352 test "renders subscribe form", %{conn: conn} do
353 user = insert(:user)
354
355 response =
356 conn
357 |> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
358 |> response(:ok)
359
360 refute response =~ "Could not find user"
361 assert response =~ "Remotely follow #{user.nickname}"
362 end
363
364 test "renders subscribe form with error when user not found", %{conn: conn} do
365 response =
366 conn
367 |> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
368 |> response(:ok)
369
370 assert response =~ "Could not find user"
371 refute response =~ "Remotely follow"
372 end
373
374 test "it redirect to webfinger url", %{conn: conn} do
375 user = insert(:user)
376 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
377
378 conn =
379 conn
380 |> post("/main/ostatus", %{
381 "user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
382 })
383
384 assert redirected_to(conn) ==
385 "https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
386 end
387
388 test "it renders form with error when user not found", %{conn: conn} do
389 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
390
391 response =
392 conn
393 |> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
394 |> response(:ok)
395
396 assert response =~ "Something went wrong."
397 end
398 end
399
400 test "it returns new captcha", %{conn: conn} do
401 with_mock Pleroma.Captcha,
402 new: fn -> "test_captcha" end do
403 resp =
404 conn
405 |> get("/api/pleroma/captcha")
406 |> response(200)
407
408 assert resp == "\"test_captcha\""
409 assert called(Pleroma.Captcha.new())
410 end
411 end
412
413 describe "POST /api/pleroma/change_email" do
414 setup do: oauth_access(["write:accounts"])
415
416 test "without permissions", %{conn: conn} do
417 conn =
418 conn
419 |> assign(:token, nil)
420 |> post("/api/pleroma/change_email")
421
422 assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."}
423 end
424
425 test "with proper permissions and invalid password", %{conn: conn} do
426 conn =
427 post(conn, "/api/pleroma/change_email", %{
428 "password" => "hi",
429 "email" => "test@test.com"
430 })
431
432 assert json_response(conn, 200) == %{"error" => "Invalid password."}
433 end
434
435 test "with proper permissions, valid password and invalid email", %{
436 conn: conn
437 } do
438 conn =
439 post(conn, "/api/pleroma/change_email", %{
440 "password" => "test",
441 "email" => "foobar"
442 })
443
444 assert json_response(conn, 200) == %{"error" => "Email has invalid format."}
445 end
446
447 test "with proper permissions, valid password and no email", %{
448 conn: conn
449 } do
450 conn =
451 post(conn, "/api/pleroma/change_email", %{
452 "password" => "test"
453 })
454
455 assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
456 end
457
458 test "with proper permissions, valid password and blank email", %{
459 conn: conn
460 } do
461 conn =
462 post(conn, "/api/pleroma/change_email", %{
463 "password" => "test",
464 "email" => ""
465 })
466
467 assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
468 end
469
470 test "with proper permissions, valid password and non unique email", %{
471 conn: conn
472 } do
473 user = insert(:user)
474
475 conn =
476 post(conn, "/api/pleroma/change_email", %{
477 "password" => "test",
478 "email" => user.email
479 })
480
481 assert json_response(conn, 200) == %{"error" => "Email has already been taken."}
482 end
483
484 test "with proper permissions, valid password and valid email", %{
485 conn: conn
486 } do
487 conn =
488 post(conn, "/api/pleroma/change_email", %{
489 "password" => "test",
490 "email" => "cofe@foobar.com"
491 })
492
493 assert json_response(conn, 200) == %{"status" => "success"}
494 end
495 end
496
497 describe "POST /api/pleroma/change_password" do
498 setup do: oauth_access(["write:accounts"])
499
500 test "without permissions", %{conn: conn} do
501 conn =
502 conn
503 |> assign(:token, nil)
504 |> post("/api/pleroma/change_password")
505
506 assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."}
507 end
508
509 test "with proper permissions and invalid password", %{conn: conn} do
510 conn =
511 post(conn, "/api/pleroma/change_password", %{
512 "password" => "hi",
513 "new_password" => "newpass",
514 "new_password_confirmation" => "newpass"
515 })
516
517 assert json_response(conn, 200) == %{"error" => "Invalid password."}
518 end
519
520 test "with proper permissions, valid password and new password and confirmation not matching",
521 %{
522 conn: conn
523 } do
524 conn =
525 post(conn, "/api/pleroma/change_password", %{
526 "password" => "test",
527 "new_password" => "newpass",
528 "new_password_confirmation" => "notnewpass"
529 })
530
531 assert json_response(conn, 200) == %{
532 "error" => "New password does not match confirmation."
533 }
534 end
535
536 test "with proper permissions, valid password and invalid new password", %{
537 conn: conn
538 } do
539 conn =
540 post(conn, "/api/pleroma/change_password", %{
541 "password" => "test",
542 "new_password" => "",
543 "new_password_confirmation" => ""
544 })
545
546 assert json_response(conn, 200) == %{
547 "error" => "New password can't be blank."
548 }
549 end
550
551 test "with proper permissions, valid password and matching new password and confirmation", %{
552 conn: conn,
553 user: user
554 } do
555 conn =
556 post(conn, "/api/pleroma/change_password", %{
557 "password" => "test",
558 "new_password" => "newpass",
559 "new_password_confirmation" => "newpass"
560 })
561
562 assert json_response(conn, 200) == %{"status" => "success"}
563 fetched_user = User.get_cached_by_id(user.id)
564 assert Pbkdf2.verify_pass("newpass", fetched_user.password_hash) == true
565 end
566 end
567
568 describe "POST /api/pleroma/delete_account" do
569 setup do: oauth_access(["write:accounts"])
570
571 test "without permissions", %{conn: conn} do
572 conn =
573 conn
574 |> assign(:token, nil)
575 |> post("/api/pleroma/delete_account")
576
577 assert json_response(conn, 403) ==
578 %{"error" => "Insufficient permissions: write:accounts."}
579 end
580
581 test "with proper permissions and wrong or missing password", %{conn: conn} do
582 for params <- [%{"password" => "hi"}, %{}] do
583 ret_conn = post(conn, "/api/pleroma/delete_account", params)
584
585 assert json_response(ret_conn, 200) == %{"error" => "Invalid password."}
586 end
587 end
588
589 test "with proper permissions and valid password", %{conn: conn} do
590 conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"})
591
592 assert json_response(conn, 200) == %{"status" => "success"}
593 end
594 end
595 end