1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
6 use Pleroma.Web.ConnCase
7 use Oban.Testing, repo: Pleroma.Repo
10 alias Pleroma.Tests.ObanHelpers
12 # alias Pleroma.Web.CommonAPI
13 # import ExUnit.CaptureLog
14 import Pleroma.Factory
18 Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
22 clear_config([:instance])
23 clear_config([:frontend_configurations, :pleroma_fe])
24 clear_config([:user, :deny_follow_blocked])
26 describe "POST /api/pleroma/follow_import" do
27 test "it returns HTTP 200", %{conn: conn} do
33 |> assign(:user, user1)
34 |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"})
37 assert response == "job started"
40 test "it imports follow lists from file", %{conn: conn} do
46 read!: fn "follow_list.txt" ->
47 "Account address,Show boosts\n#{user2.ap_id},true"
52 |> assign(:user, user1)
53 |> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}})
56 assert response == "job started"
58 assert ObanHelpers.member?(
60 "op" => "follow_import",
61 "follower_id" => user1.id,
62 "followed_identifiers" => [user2.ap_id]
64 all_enqueued(worker: Pleroma.Workers.BackgroundWorker)
69 test "it imports new-style mastodon follow lists", %{conn: conn} do
75 |> assign(:user, user1)
76 |> post("/api/pleroma/follow_import", %{
77 "list" => "Account address,Show boosts\n#{user2.ap_id},true"
81 assert response == "job started"
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)
90 for token <- [token1, token2, token3] do
93 |> put_req_header("authorization", "Bearer #{token.token}")
94 |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
97 assert %{"error" => "Insufficient permissions: follow | write:follows."} ==
98 json_response(conn, 403)
100 assert json_response(conn, 200)
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)
113 |> assign(:user, user1)
114 |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"})
115 |> json_response(:ok)
117 assert response == "job started"
120 test "it imports blocks users from file", %{conn: conn} do
121 user1 = insert(:user)
122 user2 = insert(:user)
123 user3 = insert(:user)
126 {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end}
130 |> assign(:user, user1)
131 |> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}})
132 |> json_response(:ok)
134 assert response == "job started"
136 assert ObanHelpers.member?(
138 "op" => "blocks_import",
139 "blocker_id" => user1.id,
140 "blocked_identifiers" => [user2.ap_id, user3.ap_id]
142 all_enqueued(worker: Pleroma.Workers.BackgroundWorker)
148 describe "PUT /api/pleroma/notification_settings" do
149 test "it updates notification settings", %{conn: conn} do
153 |> assign(:user, user)
154 |> put("/api/pleroma/notification_settings", %{
155 "followers" => false,
158 |> json_response(:ok)
160 user = Repo.get(User, user.id)
162 assert %Pleroma.User.NotificationSetting{
167 privacy_option: false
168 } == user.notification_settings
171 test "it update notificatin privacy option", %{conn: conn} do
175 |> assign(:user, user)
176 |> put("/api/pleroma/notification_settings", %{"privacy_option" => "1"})
177 |> json_response(:ok)
179 user = refresh_record(user)
181 assert %Pleroma.User.NotificationSetting{
187 } == user.notification_settings
191 describe "GET /api/statusnet/config" do
192 test "it returns config in xml format", %{conn: conn} do
193 instance = Pleroma.Config.get(:instance)
197 |> put_req_header("accept", "application/xml")
198 |> get("/api/statusnet/config")
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"
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"})
219 |> put_req_header("accept", "application/json")
220 |> get("/api/statusnet/config")
221 |> json_response(:ok)
225 "accountActivationRequired" => "0",
227 "description" => Keyword.get(instance, :description),
228 "invitesEnabled" => "1",
229 "name" => Keyword.get(instance, :name),
230 "pleromafe" => %{"theme" => "asuka-hospital"},
232 "safeDMMentionsEnabled" => "0",
233 "server" => Pleroma.Web.base_url(),
234 "textlimit" => to_string(Keyword.get(instance, :limit)),
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))
241 "vapidPublicKey" => Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
245 assert response == expected_data
248 test "returns the state of safe_dm_mentions flag", %{conn: conn} do
249 Pleroma.Config.put([:instance, :safe_dm_mentions], true)
253 |> get("/api/statusnet/config.json")
254 |> json_response(:ok)
256 assert response["site"]["safeDMMentionsEnabled"] == "1"
258 Pleroma.Config.put([:instance, :safe_dm_mentions], false)
262 |> get("/api/statusnet/config.json")
263 |> json_response(:ok)
265 assert response["site"]["safeDMMentionsEnabled"] == "0"
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"})
274 |> get("/api/statusnet/config.json")
275 |> json_response(:ok)
277 refute response["site"]["pleromafe"]
279 Pleroma.Config.put([:instance, :managed_config], true)
283 |> get("/api/statusnet/config.json")
284 |> json_response(:ok)
286 assert response["site"]["pleromafe"] == %{"theme" => "asuka-hospital"}
290 describe "GET /api/pleroma/frontend_configurations" do
291 test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} do
302 Pleroma.Config.put(:frontend_configurations, config)
306 |> get("/api/pleroma/frontend_configurations")
307 |> json_response(:ok)
309 assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!()
313 describe "/api/pleroma/emoji" do
314 test "returns json with custom emoji with tags", %{conn: conn} do
317 |> get("/api/pleroma/emoji")
318 |> json_response(200)
320 assert Enum.all?(emoji, fn
326 is_binary(url) and is_list(tags)
331 describe "GET /api/pleroma/healthcheck" do
332 clear_config([:instance, :healthcheck])
334 test "returns 503 when healthcheck disabled", %{conn: conn} do
335 Pleroma.Config.put([:instance, :healthcheck], false)
339 |> get("/api/pleroma/healthcheck")
340 |> json_response(503)
342 assert response == %{}
345 test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do
346 Pleroma.Config.put([:instance, :healthcheck], true)
348 with_mock Pleroma.Healthcheck,
349 system_info: fn -> %Pleroma.Healthcheck{healthy: true} end do
352 |> get("/api/pleroma/healthcheck")
353 |> json_response(200)
365 test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do
366 Pleroma.Config.put([:instance, :healthcheck], true)
368 with_mock Pleroma.Healthcheck,
369 system_info: fn -> %Pleroma.Healthcheck{healthy: false} end do
372 |> get("/api/pleroma/healthcheck")
373 |> json_response(503)
386 describe "POST /api/pleroma/disable_account" do
387 test "it returns HTTP 200", %{conn: conn} do
392 |> assign(:user, user)
393 |> post("/api/pleroma/disable_account", %{"password" => "test"})
394 |> json_response(:ok)
396 assert response == %{"status" => "success"}
397 ObanHelpers.perform_all()
399 user = User.get_cached_by_id(user.id)
401 assert user.deactivated == true
404 test "it returns returns when password invalid", %{conn: conn} do
409 |> assign(:user, user)
410 |> post("/api/pleroma/disable_account", %{"password" => "test1"})
411 |> json_response(:ok)
413 assert response == %{"error" => "Invalid password."}
414 user = User.get_cached_by_id(user.id)
416 refute user.deactivated
420 describe "GET /api/statusnet/version" do
421 test "it returns version in xml format", %{conn: conn} do
424 |> put_req_header("accept", "application/xml")
425 |> get("/api/statusnet/version")
428 assert response == "<version>#{Pleroma.Application.named_version()}</version>"
431 test "it returns version in json format", %{conn: conn} do
434 |> put_req_header("accept", "application/json")
435 |> get("/api/statusnet/version")
436 |> json_response(:ok)
438 assert response == "#{Pleroma.Application.named_version()}"
442 describe "POST /main/ostatus - remote_subscribe/2" do
443 test "renders subscribe form", %{conn: conn} do
448 |> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
451 refute response =~ "Could not find user"
452 assert response =~ "Remotely follow #{user.nickname}"
455 test "renders subscribe form with error when user not found", %{conn: conn} do
458 |> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
461 assert response =~ "Could not find user"
462 refute response =~ "Remotely follow"
465 test "it redirect to webfinger url", %{conn: conn} do
467 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
471 |> post("/main/ostatus", %{
472 "user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
475 assert redirected_to(conn) ==
476 "https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
479 test "it renders form with error when use not found", %{conn: conn} do
480 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
484 |> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
487 assert response =~ "Something went wrong."
491 test "it returns new captcha", %{conn: conn} do
492 with_mock Pleroma.Captcha,
493 new: fn -> "test_captcha" end do
496 |> get("/api/pleroma/captcha")
499 assert resp == "\"test_captcha\""
500 assert called(Pleroma.Captcha.new())
504 defp with_credentials(conn, username, password) do
505 header_content = "Basic " <> Base.encode64("#{username}:#{password}")
506 put_req_header(conn, "authorization", header_content)
509 defp valid_user(_context) do
514 describe "POST /api/pleroma/change_email" do
517 test "without credentials", %{conn: conn} do
518 conn = post(conn, "/api/pleroma/change_email")
519 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
522 test "with credentials and invalid password", %{conn: conn, user: current_user} do
525 |> with_credentials(current_user.nickname, "test")
526 |> post("/api/pleroma/change_email", %{
528 "email" => "test@test.com"
531 assert json_response(conn, 200) == %{"error" => "Invalid password."}
534 test "with credentials, valid password and invalid email", %{
540 |> with_credentials(current_user.nickname, "test")
541 |> post("/api/pleroma/change_email", %{
542 "password" => "test",
546 assert json_response(conn, 200) == %{"error" => "Email has invalid format."}
549 test "with credentials, valid password and no email", %{
555 |> with_credentials(current_user.nickname, "test")
556 |> post("/api/pleroma/change_email", %{
560 assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
563 test "with credentials, valid password and blank email", %{
569 |> with_credentials(current_user.nickname, "test")
570 |> post("/api/pleroma/change_email", %{
571 "password" => "test",
575 assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
578 test "with credentials, valid password and non unique email", %{
586 |> with_credentials(current_user.nickname, "test")
587 |> post("/api/pleroma/change_email", %{
588 "password" => "test",
589 "email" => user.email
592 assert json_response(conn, 200) == %{"error" => "Email has already been taken."}
595 test "with credentials, valid password and valid email", %{
601 |> with_credentials(current_user.nickname, "test")
602 |> post("/api/pleroma/change_email", %{
603 "password" => "test",
604 "email" => "cofe@foobar.com"
607 assert json_response(conn, 200) == %{"status" => "success"}
611 describe "POST /api/pleroma/change_password" do
614 test "without credentials", %{conn: conn} do
615 conn = post(conn, "/api/pleroma/change_password")
616 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
619 test "with credentials and invalid password", %{conn: conn, user: current_user} do
622 |> with_credentials(current_user.nickname, "test")
623 |> post("/api/pleroma/change_password", %{
625 "new_password" => "newpass",
626 "new_password_confirmation" => "newpass"
629 assert json_response(conn, 200) == %{"error" => "Invalid password."}
632 test "with credentials, valid password and new password and confirmation not matching", %{
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"
645 assert json_response(conn, 200) == %{
646 "error" => "New password does not match confirmation."
650 test "with credentials, valid password and invalid new password", %{
656 |> with_credentials(current_user.nickname, "test")
657 |> post("/api/pleroma/change_password", %{
658 "password" => "test",
659 "new_password" => "",
660 "new_password_confirmation" => ""
663 assert json_response(conn, 200) == %{
664 "error" => "New password can't be blank."
668 test "with credentials, valid password and matching new password and confirmation", %{
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"
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
687 describe "POST /api/pleroma/delete_account" do
690 test "without credentials", %{conn: conn} do
691 conn = post(conn, "/api/pleroma/delete_account")
692 assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
695 test "with credentials and invalid password", %{conn: conn, user: current_user} do
698 |> with_credentials(current_user.nickname, "test")
699 |> post("/api/pleroma/delete_account", %{"password" => "hi"})
701 assert json_response(conn, 200) == %{"error" => "Invalid password."}
704 test "with credentials and valid password", %{conn: conn, user: current_user} do
707 |> with_credentials(current_user.nickname, "test")
708 |> post("/api/pleroma/delete_account", %{"password" => "test"})
710 assert json_response(conn, 200) == %{"status" => "success"}