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
8 alias Pleroma.Notification
11 alias Pleroma.Web.CommonAPI
12 import Pleroma.Factory
16 Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
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])
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)
31 describe "POST /api/pleroma/follow_import" do
32 test "it returns HTTP 200", %{conn: conn} do
38 |> assign(:user, user1)
39 |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"})
42 assert response == "job started"
45 test "it imports follow lists from file", %{conn: conn} do
51 read!: fn "follow_list.txt" ->
52 "Account address,Show boosts\n#{user2.ap_id},true"
54 {PleromaJobQueue, [:passthrough], []}
58 |> assign(:user, user1)
59 |> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}})
63 PleromaJobQueue.enqueue(
66 [:follow_import, user1, [user2.ap_id]]
70 assert response == "job started"
74 test "it imports new-style mastodon follow lists", %{conn: conn} do
80 |> assign(:user, user1)
81 |> post("/api/pleroma/follow_import", %{
82 "list" => "Account address,Show boosts\n#{user2.ap_id},true"
86 assert response == "job started"
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)
94 for token <- [token1, token2] do
97 |> put_req_header("authorization", "Bearer #{token.token}")
98 |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
100 if token == token1 do
101 assert %{"error" => "Insufficient permissions: follow."} == json_response(conn, 403)
103 assert json_response(conn, 200)
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)
116 |> assign(:user, user1)
117 |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"})
118 |> json_response(:ok)
120 assert response == "job started"
123 test "it imports blocks users from file", %{conn: conn} do
124 user1 = insert(:user)
125 user2 = insert(:user)
126 user3 = insert(:user)
129 {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end},
130 {PleromaJobQueue, [:passthrough], []}
134 |> assign(:user, user1)
135 |> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}})
136 |> json_response(:ok)
139 PleromaJobQueue.enqueue(
142 [:blocks_import, user1, [user2.ap_id, user3.ap_id]]
146 assert response == "job started"
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)
161 |> assign(:user, user1)
162 |> post("/api/pleroma/notifications/read", %{"id" => "#{notification1.id}"})
163 |> json_response(:ok)
165 assert Repo.get(Notification, notification1.id).seen
166 refute Repo.get(Notification, notification2.id).seen
169 test "it returns error when notification not found", %{conn: conn} do
170 user1 = insert(:user)
174 |> assign(:user, user1)
175 |> post("/api/pleroma/notifications/read", %{"id" => "22222222222222"})
176 |> json_response(403)
178 assert response == %{"error" => "Cannot get notification"}
182 describe "PUT /api/pleroma/notification_settings" do
183 test "it updates notification settings", %{conn: conn} do
187 |> assign(:user, user)
188 |> put("/api/pleroma/notification_settings", %{
189 "followers" => false,
192 |> json_response(:ok)
194 user = Repo.get(User, user.id)
197 "followers" => false,
199 "non_follows" => true,
200 "non_followers" => true
201 } == user.info.notification_settings
205 describe "GET /api/statusnet/config" do
206 test "it returns config in xml format", %{conn: conn} do
207 instance = Pleroma.Config.get(:instance)
211 |> put_req_header("accept", "application/xml")
212 |> get("/api/statusnet/config")
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"
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"})
233 |> put_req_header("accept", "application/json")
234 |> get("/api/statusnet/config")
235 |> json_response(:ok)
239 "accountActivationRequired" => "0",
241 "description" => Keyword.get(instance, :description),
242 "invitesEnabled" => "1",
243 "name" => Keyword.get(instance, :name),
244 "pleromafe" => %{"theme" => "asuka-hospital"},
246 "safeDMMentionsEnabled" => "0",
247 "server" => Pleroma.Web.base_url(),
248 "textlimit" => to_string(Keyword.get(instance, :limit)),
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))
255 "vapidPublicKey" => Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
259 assert response == expected_data
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)
268 |> get("/api/statusnet/config.json")
269 |> json_response(:ok)
271 assert response["site"]["safeDMMentionsEnabled"] == "1"
273 Pleroma.Config.put([:instance, :safe_dm_mentions], false)
277 |> get("/api/statusnet/config.json")
278 |> json_response(:ok)
280 assert response["site"]["safeDMMentionsEnabled"] == "0"
282 Pleroma.Config.put([:instance, :safe_dm_mentions], option)
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"})
291 |> get("/api/statusnet/config.json")
292 |> json_response(:ok)
294 refute response["site"]["pleromafe"]
296 Pleroma.Config.put([:instance, :managed_config], true)
300 |> get("/api/statusnet/config.json")
301 |> json_response(:ok)
303 assert response["site"]["pleromafe"] == %{"theme" => "asuka-hospital"}
307 describe "GET /api/pleroma/frontend_configurations" do
308 test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} do
319 Pleroma.Config.put(:frontend_configurations, config)
323 |> get("/api/pleroma/frontend_configurations")
324 |> json_response(:ok)
326 assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!()
330 describe "/api/pleroma/emoji" do
331 test "returns json with custom emoji with tags", %{conn: conn} do
334 |> get("/api/pleroma/emoji")
335 |> json_response(200)
337 assert Enum.all?(emoji, fn
343 is_binary(url) and is_list(tags)
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
353 "/ostatus_subscribe?acct=https://mastodon.social/users/emelie/statuses/101849165031453009"
356 assert redirected_to(conn) =~ "/notice/"
359 test "show follow account page if the `acct` is a account link", %{conn: conn} do
363 "/ostatus_subscribe?acct=https://mastodon.social/users/emelie"
366 assert html_response(response, 200) =~ "Log in to follow"
369 test "show follow page if the `acct` is a account link", %{conn: conn} do
374 |> assign(:user, user)
375 |> get("/ostatus_subscribe?acct=https://mastodon.social/users/emelie")
377 assert html_response(response, 200) =~ "Remote follow"
380 test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do
385 |> assign(:user, user)
386 |> get("/ostatus_subscribe?acct=https://mastodon.social/users/not_found")
388 assert html_response(response, 200) =~ "Error fetching user"
392 describe "POST /ostatus_subscribe - do_remote_follow/2 with assigned user " do
393 test "follows user", %{conn: conn} do
395 user2 = insert(:user)
399 |> assign(:user, user)
400 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
403 assert response =~ "Account followed!"
404 assert user2.follower_address in refresh_record(user).following
407 test "returns error when user is deactivated", %{conn: conn} do
408 user = insert(:user, info: %{deactivated: true})
409 user2 = insert(:user)
413 |> assign(:user, user)
414 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
417 assert response =~ "Error following account"
420 test "returns error when user is blocked", %{conn: conn} do
421 Pleroma.Config.put([:user, :deny_follow_blocked], true)
423 user2 = insert(:user)
425 {:ok, _user} = Pleroma.User.block(user2, user)
429 |> assign(:user, user)
430 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
433 assert response =~ "Error following account"
436 test "returns error when followee not found", %{conn: conn} do
441 |> assign(:user, user)
442 |> post("/ostatus_subscribe", %{"user" => %{"id" => "jimm"}})
445 assert response =~ "Error following account"
448 test "returns success result when user already in followers", %{conn: conn} do
450 user2 = insert(:user)
451 {:ok, _, _, _} = CommonAPI.follow(user, user2)
455 |> assign(:user, refresh_record(user))
456 |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}})
459 assert response =~ "Account followed!"
463 describe "POST /ostatus_subscribe - do_remote_follow/2 without assigned user " do
464 test "follows", %{conn: conn} do
466 user2 = insert(:user)
470 |> post("/ostatus_subscribe", %{
471 "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
475 assert response =~ "Account followed!"
476 assert user2.follower_address in refresh_record(user).following
479 test "returns error when followee not found", %{conn: conn} do
484 |> post("/ostatus_subscribe", %{
485 "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"}
489 assert response =~ "Error following account"
492 test "returns error when login invalid", %{conn: conn} do
497 |> post("/ostatus_subscribe", %{
498 "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id}
502 assert response =~ "Wrong username or password"
505 test "returns error when password invalid", %{conn: conn} do
507 user2 = insert(:user)
511 |> post("/ostatus_subscribe", %{
512 "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id}
516 assert response =~ "Wrong username or password"
519 test "returns error when user is blocked", %{conn: conn} do
520 Pleroma.Config.put([:user, :deny_follow_blocked], true)
522 user2 = insert(:user)
523 {:ok, _user} = Pleroma.User.block(user2, user)
527 |> post("/ostatus_subscribe", %{
528 "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
532 assert response =~ "Error following account"
536 describe "GET /api/pleroma/healthcheck" do
538 config_healthcheck = Pleroma.Config.get([:instance, :healthcheck])
541 Pleroma.Config.put([:instance, :healthcheck], config_healthcheck)
547 test "returns 503 when healthcheck disabled", %{conn: conn} do
548 Pleroma.Config.put([:instance, :healthcheck], false)
552 |> get("/api/pleroma/healthcheck")
553 |> json_response(503)
555 assert response == %{}
558 test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do
559 Pleroma.Config.put([:instance, :healthcheck], true)
561 with_mock Pleroma.Healthcheck,
562 system_info: fn -> %Pleroma.Healthcheck{healthy: true} end do
565 |> get("/api/pleroma/healthcheck")
566 |> json_response(200)
578 test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do
579 Pleroma.Config.put([:instance, :healthcheck], true)
581 with_mock Pleroma.Healthcheck,
582 system_info: fn -> %Pleroma.Healthcheck{healthy: false} end do
585 |> get("/api/pleroma/healthcheck")
586 |> json_response(503)
599 describe "POST /api/pleroma/disable_account" do
600 test "it returns HTTP 200", %{conn: conn} do
605 |> assign(:user, user)
606 |> post("/api/pleroma/disable_account", %{"password" => "test"})
607 |> json_response(:ok)
609 assert response == %{"status" => "success"}
611 user = User.get_cached_by_id(user.id)
613 assert user.info.deactivated == true
616 test "it returns returns when password invalid", %{conn: conn} do
621 |> assign(:user, user)
622 |> post("/api/pleroma/disable_account", %{"password" => "test1"})
623 |> json_response(:ok)
625 assert response == %{"error" => "Invalid password."}
626 user = User.get_cached_by_id(user.id)
628 refute user.info.deactivated
632 describe "GET /api/statusnet/version" do
633 test "it returns version in xml format", %{conn: conn} do
636 |> put_req_header("accept", "application/xml")
637 |> get("/api/statusnet/version")
640 assert response == "<version>#{Pleroma.Application.named_version()}</version>"
643 test "it returns version in json format", %{conn: conn} do
646 |> put_req_header("accept", "application/json")
647 |> get("/api/statusnet/version")
648 |> json_response(:ok)
650 assert response == "#{Pleroma.Application.named_version()}"
654 describe "POST /main/ostatus - remote_subscribe/2" do
655 test "renders subscribe form", %{conn: conn} do
660 |> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
663 refute response =~ "Could not find user"
664 assert response =~ "Remotely follow #{user.nickname}"
667 test "renders subscribe form with error when user not found", %{conn: conn} do
670 |> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
673 assert response =~ "Could not find user"
674 refute response =~ "Remotely follow"
677 test "it redirect to webfinger url", %{conn: conn} do
679 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
683 |> post("/main/ostatus", %{
684 "user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
687 assert redirected_to(conn) ==
688 "https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
691 test "it renders form with error when use not found", %{conn: conn} do
692 user2 = insert(:user, ap_id: "shp@social.heldscal.la")
696 |> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
699 assert response =~ "Something went wrong."
703 test "it returns new captcha", %{conn: conn} do
704 with_mock Pleroma.Captcha,
705 new: fn -> "test_captcha" end do
708 |> get("/api/pleroma/captcha")
711 assert resp == "\"test_captcha\""
712 assert called(Pleroma.Captcha.new())