tests for /web/mastodon_api/mastodon_api.ex
authorMaksim <parallel588@gmail.com>
Tue, 13 Aug 2019 21:12:37 +0000 (21:12 +0000)
committerkaniini <ariadne@dereferenced.org>
Tue, 13 Aug 2019 21:12:37 +0000 (21:12 +0000)
lib/pleroma/web/mastodon_api/mastodon_api.ex
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
test/web/mastodon_api/mastodon_api_controller_test.exs
test/web/mastodon_api/mastodon_api_test.exs [new file with mode: 0644]

index 46944dcbc1381390eda5fbb48d45f401236f4b1b..ac01d1ff39a42639f4b457b780b5893e0429c3e5 100644 (file)
@@ -13,10 +13,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
   alias Pleroma.User
   alias Pleroma.Web.CommonAPI
 
+  @spec follow(User.t(), User.t(), map) :: {:ok, User.t()} | {:error, String.t()}
   def follow(follower, followed, params \\ %{}) do
-    options = cast_params(params)
-    reblogs = options[:reblogs]
-
     result =
       if not User.following?(follower, followed) do
         CommonAPI.follow(follower, followed)
@@ -24,19 +22,25 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
         {:ok, follower, followed, nil}
       end
 
-    with {:ok, follower, followed, _} <- result do
-      reblogs
-      |> case do
-        false -> CommonAPI.hide_reblogs(follower, followed)
-        _ -> CommonAPI.show_reblogs(follower, followed)
-      end
-      |> case do
+    with {:ok, follower, _followed, _} <- result do
+      options = cast_params(params)
+
+      case reblogs_visibility(options[:reblogs], result) do
         {:ok, follower} -> {:ok, follower}
         _ -> {:ok, follower}
       end
     end
   end
 
+  defp reblogs_visibility(false, {:ok, follower, followed, _}) do
+    CommonAPI.hide_reblogs(follower, followed)
+  end
+
+  defp reblogs_visibility(_, {:ok, follower, followed, _}) do
+    CommonAPI.show_reblogs(follower, followed)
+  end
+
+  @spec get_followers(User.t(), map()) :: list(User.t())
   def get_followers(user, params \\ %{}) do
     user
     |> User.get_followers_query()
index 174e93468be711608b67b2306efdac8219ef8777..47e263aaee0bfa9567246b4f6abad086109674ed 100644 (file)
@@ -536,8 +536,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
       |> put_view(StatusView)
       |> try_render("poll.json", %{object: object, for: user})
     else
-      nil -> render_error(conn, :not_found, "Record not found")
-      false -> render_error(conn, :not_found, "Record not found")
+      error when is_nil(error) or error == false ->
+        render_error(conn, :not_found, "Record not found")
     end
   end
 
@@ -1690,45 +1690,35 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
         |> String.replace("{{user}}", user)
 
       with {:ok, %{status: 200, body: body}} <-
-             HTTP.get(
-               url,
-               [],
-               adapter: [
-                 recv_timeout: timeout,
-                 pool: :default
-               ]
-             ),
+             HTTP.get(url, [], adapter: [recv_timeout: timeout, pool: :default]),
            {:ok, data} <- Jason.decode(body) do
         data =
           data
           |> Enum.slice(0, limit)
           |> Enum.map(fn x ->
-            Map.put(
-              x,
-              "id",
-              case User.get_or_fetch(x["acct"]) do
-                {:ok, %User{id: id}} -> id
-                _ -> 0
-              end
-            )
-          end)
-          |> Enum.map(fn x ->
-            Map.put(x, "avatar", MediaProxy.url(x["avatar"]))
-          end)
-          |> Enum.map(fn x ->
-            Map.put(x, "avatar_static", MediaProxy.url(x["avatar_static"]))
+            x
+            |> Map.put("id", fetch_suggestion_id(x))
+            |> Map.put("avatar", MediaProxy.url(x["avatar"]))
+            |> Map.put("avatar_static", MediaProxy.url(x["avatar_static"]))
           end)
 
-        conn
-        |> json(data)
+        json(conn, data)
       else
-        e -> Logger.error("Could not retrieve suggestions at fetch #{url}, #{inspect(e)}")
+        e ->
+          Logger.error("Could not retrieve suggestions at fetch #{url}, #{inspect(e)}")
       end
     else
       json(conn, [])
     end
   end
 
+  defp fetch_suggestion_id(attrs) do
+    case User.get_or_fetch(attrs["acct"]) do
+      {:ok, %User{id: id}} -> id
+      _ -> 0
+    end
+  end
+
   def status_card(%{assigns: %{user: user}} = conn, %{"id" => status_id}) do
     with %Activity{} = activity <- Activity.get_by_id(status_id),
          true <- Visibility.visible_for_user?(activity, user) do
index b023d1e4f32be715c6ca611f10606d2d83ab3d68..2febe8b3a395591b1ef6e5ee4cec71b90c7147fb 100644 (file)
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
   alias Ecto.Changeset
   alias Pleroma.Activity
+  alias Pleroma.Config
   alias Pleroma.Notification
   alias Pleroma.Object
   alias Pleroma.Repo
@@ -85,11 +86,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
   end
 
   test "the public timeline when public is set to false", %{conn: conn} do
-    public = Pleroma.Config.get([:instance, :public])
-    Pleroma.Config.put([:instance, :public], false)
+    public = Config.get([:instance, :public])
+    Config.put([:instance, :public], false)
 
     on_exit(fn ->
-      Pleroma.Config.put([:instance, :public], public)
+      Config.put([:instance, :public], public)
     end)
 
     assert conn
@@ -250,7 +251,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
     end
 
     test "posting a status with OGP link preview", %{conn: conn} do
-      Pleroma.Config.put([:rich_media, :enabled], true)
+      Config.put([:rich_media, :enabled], true)
 
       conn =
         conn
@@ -260,7 +261,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
       assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200)
       assert Activity.get_by_id(id)
-      Pleroma.Config.put([:rich_media, :enabled], false)
+      Config.put([:rich_media, :enabled], false)
     end
 
     test "posting a direct status", %{conn: conn} do
@@ -304,7 +305,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
     test "option limit is enforced", %{conn: conn} do
       user = insert(:user)
-      limit = Pleroma.Config.get([:instance, :poll_limits, :max_options])
+      limit = Config.get([:instance, :poll_limits, :max_options])
 
       conn =
         conn
@@ -320,7 +321,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
     test "option character limit is enforced", %{conn: conn} do
       user = insert(:user)
-      limit = Pleroma.Config.get([:instance, :poll_limits, :max_option_chars])
+      limit = Config.get([:instance, :poll_limits, :max_option_chars])
 
       conn =
         conn
@@ -339,7 +340,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
     test "minimal date limit is enforced", %{conn: conn} do
       user = insert(:user)
-      limit = Pleroma.Config.get([:instance, :poll_limits, :min_expiration])
+      limit = Config.get([:instance, :poll_limits, :min_expiration])
 
       conn =
         conn
@@ -358,7 +359,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
     test "maximum date limit is enforced", %{conn: conn} do
       user = insert(:user)
-      limit = Pleroma.Config.get([:instance, :poll_limits, :max_expiration])
+      limit = Config.get([:instance, :poll_limits, :max_expiration])
 
       conn =
         conn
@@ -1633,12 +1634,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
   describe "media upload" do
     setup do
-      upload_config = Pleroma.Config.get([Pleroma.Upload])
-      proxy_config = Pleroma.Config.get([:media_proxy])
+      upload_config = Config.get([Pleroma.Upload])
+      proxy_config = Config.get([:media_proxy])
 
       on_exit(fn ->
-        Pleroma.Config.put([Pleroma.Upload], upload_config)
-        Pleroma.Config.put([:media_proxy], proxy_config)
+        Config.put([Pleroma.Upload], upload_config)
+        Config.put([:media_proxy], proxy_config)
       end)
 
       user = insert(:user)
@@ -2581,7 +2582,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
     conn = get(conn, "/api/v1/instance")
     assert result = json_response(conn, 200)
 
-    email = Pleroma.Config.get([:instance, :email])
+    email = Config.get([:instance, :email])
     # Note: not checking for "max_toot_chars" since it's optional
     assert %{
              "uri" => _,
@@ -2666,7 +2667,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
   describe "pinned statuses" do
     setup do
-      Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
+      Config.put([:instance, :max_pinned_statuses], 1)
 
       user = insert(:user)
       {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
@@ -2766,10 +2767,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
   describe "cards" do
     setup do
-      Pleroma.Config.put([:rich_media, :enabled], true)
+      Config.put([:rich_media, :enabled], true)
 
       on_exit(fn ->
-        Pleroma.Config.put([:rich_media, :enabled], false)
+        Config.put([:rich_media, :enabled], false)
       end)
 
       user = insert(:user)
@@ -2997,7 +2998,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       reporter: reporter,
       target_user: target_user
     } do
-      max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
+      max_size = Config.get([:instance, :max_report_comment_size], 1000)
       comment = String.pad_trailing("a", max_size + 1, "a")
 
       error = %{"error" => "Comment must be up to #{max_size} characters"}
@@ -3126,15 +3127,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       conn: conn,
       path: path
     } do
-      is_public = Pleroma.Config.get([:instance, :public])
-      Pleroma.Config.put([:instance, :public], false)
+      is_public = Config.get([:instance, :public])
+      Config.put([:instance, :public], false)
 
       conn = get(conn, path)
 
       assert conn.status == 302
       assert redirected_to(conn) == "/web/login"
 
-      Pleroma.Config.put([:instance, :public], is_public)
+      Config.put([:instance, :public], is_public)
     end
 
     test "does not redirect logged in users to the login page", %{conn: conn, path: path} do
@@ -3876,8 +3877,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
 
       email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
-      notify_email = Pleroma.Config.get([:instance, :notify_email])
-      instance_name = Pleroma.Config.get([:instance, :name])
+      notify_email = Config.get([:instance, :notify_email])
+      instance_name = Config.get([:instance, :name])
 
       assert_email_sent(
         from: {instance_name, notify_email},
@@ -3909,11 +3910,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
   describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
     setup do
-      setting = Pleroma.Config.get([:instance, :account_activation_required])
+      setting = Config.get([:instance, :account_activation_required])
 
       unless setting do
-        Pleroma.Config.put([:instance, :account_activation_required], true)
-        on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
+        Config.put([:instance, :account_activation_required], true)
+        on_exit(fn -> Config.put([:instance, :account_activation_required], setting) end)
       end
 
       user = insert(:user)
@@ -3937,8 +3938,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       |> json_response(:no_content)
 
       email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
-      notify_email = Pleroma.Config.get([:instance, :notify_email])
-      instance_name = Pleroma.Config.get([:instance, :name])
+      notify_email = Config.get([:instance, :notify_email])
+      instance_name = Config.get([:instance, :name])
 
       assert_email_sent(
         from: {instance_name, notify_email},
@@ -3947,4 +3948,84 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       )
     end
   end
+
+  describe "GET /api/v1/suggestions" do
+    setup do
+      user = insert(:user)
+      other_user = insert(:user)
+      config = Config.get(:suggestions)
+      on_exit(fn -> Config.put(:suggestions, config) end)
+
+      host = Config.get([Pleroma.Web.Endpoint, :url, :host])
+      url500 = "http://test500?#{host}&#{user.nickname}"
+      url200 = "http://test200?#{host}&#{user.nickname}"
+
+      mock(fn
+        %{method: :get, url: ^url500} ->
+          %Tesla.Env{status: 500, body: "bad request"}
+
+        %{method: :get, url: ^url200} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              ~s([{"acct":"yj455","avatar":"https://social.heldscal.la/avatar/201.jpeg","avatar_static":"https://social.heldscal.la/avatar/s/201.jpeg"}, {"acct":"#{
+                other_user.ap_id
+              }","avatar":"https://social.heldscal.la/avatar/202.jpeg","avatar_static":"https://social.heldscal.la/avatar/s/202.jpeg"}])
+          }
+      end)
+
+      [user: user, other_user: other_user]
+    end
+
+    test "returns empty result when suggestions disabled", %{conn: conn, user: user} do
+      Config.put([:suggestions, :enabled], false)
+
+      res =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/suggestions")
+        |> json_response(200)
+
+      assert res == []
+    end
+
+    test "returns error", %{conn: conn, user: user} do
+      Config.put([:suggestions, :enabled], true)
+      Config.put([:suggestions, :third_party_engine], "http://test500?{{host}}&{{user}}")
+
+      res =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/suggestions")
+        |> json_response(500)
+
+      assert res == "Something went wrong"
+    end
+
+    test "returns suggestions", %{conn: conn, user: user, other_user: other_user} do
+      Config.put([:suggestions, :enabled], true)
+      Config.put([:suggestions, :third_party_engine], "http://test200?{{host}}&{{user}}")
+
+      res =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/suggestions")
+        |> json_response(200)
+
+      assert res == [
+               %{
+                 "acct" => "yj455",
+                 "avatar" => "https://social.heldscal.la/avatar/201.jpeg",
+                 "avatar_static" => "https://social.heldscal.la/avatar/s/201.jpeg",
+                 "id" => 0
+               },
+               %{
+                 "acct" => other_user.ap_id,
+                 "avatar" => "https://social.heldscal.la/avatar/202.jpeg",
+                 "avatar_static" => "https://social.heldscal.la/avatar/s/202.jpeg",
+                 "id" => other_user.id
+               }
+             ]
+    end
+  end
 end
diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/web/mastodon_api/mastodon_api_test.exs
new file mode 100644 (file)
index 0000000..b4c0427
--- /dev/null
@@ -0,0 +1,103 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
+  use Pleroma.Web.ConnCase
+
+  alias Pleroma.Notification
+  alias Pleroma.ScheduledActivity
+  alias Pleroma.User
+  alias Pleroma.Web.MastodonAPI.MastodonAPI
+  alias Pleroma.Web.TwitterAPI.TwitterAPI
+
+  import Pleroma.Factory
+
+  describe "follow/3" do
+    test "returns error when user deactivated" do
+      follower = insert(:user)
+      user = insert(:user, local: true, info: %{deactivated: true})
+      {:error, error} = MastodonAPI.follow(follower, user)
+      assert error == "Could not follow user: You are deactivated."
+    end
+
+    test "following for user" do
+      follower = insert(:user)
+      user = insert(:user)
+      {:ok, follower} = MastodonAPI.follow(follower, user)
+      assert User.following?(follower, user)
+    end
+
+    test "returns ok if user already followed" do
+      follower = insert(:user)
+      user = insert(:user)
+      {:ok, follower} = User.follow(follower, user)
+      {:ok, follower} = MastodonAPI.follow(follower, refresh_record(user))
+      assert User.following?(follower, user)
+    end
+  end
+
+  describe "get_followers/2" do
+    test "returns user followers" do
+      follower1_user = insert(:user)
+      follower2_user = insert(:user)
+      user = insert(:user)
+      {:ok, _follower1_user} = User.follow(follower1_user, user)
+      {:ok, follower2_user} = User.follow(follower2_user, user)
+
+      assert MastodonAPI.get_followers(user, %{"limit" => 1}) == [follower2_user]
+    end
+  end
+
+  describe "get_friends/2" do
+    test "returns user friends" do
+      user = insert(:user)
+      followed_one = insert(:user)
+      followed_two = insert(:user)
+      followed_three = insert(:user)
+
+      {:ok, user} = User.follow(user, followed_one)
+      {:ok, user} = User.follow(user, followed_two)
+      {:ok, user} = User.follow(user, followed_three)
+      res = MastodonAPI.get_friends(user)
+
+      assert length(res) == 3
+      assert Enum.member?(res, refresh_record(followed_three))
+      assert Enum.member?(res, refresh_record(followed_two))
+      assert Enum.member?(res, refresh_record(followed_one))
+    end
+  end
+
+  describe "get_notifications/2" do
+    test "returns notifications for user" do
+      user = insert(:user)
+      subscriber = insert(:user)
+
+      User.subscribe(subscriber, user)
+
+      {:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
+      {:ok, status1} = TwitterAPI.create_status(user, %{"status" => "Magi"})
+      {:ok, [notification]} = Notification.create_notifications(status)
+      {:ok, [notification1]} = Notification.create_notifications(status1)
+      res = MastodonAPI.get_notifications(subscriber)
+
+      assert Enum.member?(Enum.map(res, & &1.id), notification.id)
+      assert Enum.member?(Enum.map(res, & &1.id), notification1.id)
+    end
+  end
+
+  describe "get_scheduled_activities/2" do
+    test "returns user scheduled activities" do
+      user = insert(:user)
+
+      today =
+        NaiveDateTime.utc_now()
+        |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
+        |> NaiveDateTime.to_iso8601()
+
+      attrs = %{params: %{}, scheduled_at: today}
+      {:ok, schedule} = ScheduledActivity.create(user, attrs)
+      assert MastodonAPI.get_scheduled_activities(user) == [schedule]
+    end
+  end
+end