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