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