Merge branch 'feature/confirm-user-acc-resend-confirmation' into 'develop'
[akkoma] / test / web / mastodon_api / controllers / account_controller_test.exs
index 32ccc5351eb50a1a27ae190b0bd9e8dcba3993d8..585cb8a9e95d54b00572a949530d61e8416b9b25 100644 (file)
@@ -5,9 +5,12 @@
 defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
   use Pleroma.Web.ConnCase
 
+  alias Pleroma.Repo
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.InternalFetchActor
   alias Pleroma.Web.CommonAPI
+  alias Pleroma.Web.OAuth.Token
 
   import Pleroma.Factory
 
@@ -116,6 +119,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
       refute acc_one == acc_two
       assert acc_two == acc_three
     end
+
+    test "returns 404 when user is invisible", %{conn: conn} do
+      user = insert(:user, %{invisible: true})
+
+      resp =
+        conn
+        |> get("/api/v1/accounts/#{user.nickname}")
+        |> json_response(404)
+
+      assert %{"error" => "Can't find user"} = resp
+    end
+
+    test "returns 404 for internal.fetch actor", %{conn: conn} do
+      %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor()
+
+      resp =
+        conn
+        |> get("/api/v1/accounts/internal.fetch")
+        |> json_response(404)
+
+      assert %{"error" => "Can't find user"} = resp
+    end
   end
 
   describe "user timelines" do
@@ -235,6 +260,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
       assert [%{"id" => id}] = json_response(conn, 200)
       assert id == to_string(post.id)
     end
+
+    test "the user views their own timelines and excludes direct messages", %{conn: conn} do
+      user = insert(:user)
+      {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"})
+      {:ok, _direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"})
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_visibilities" => ["direct"]})
+
+      assert [%{"id" => id}] = json_response(conn, 200)
+      assert id == to_string(public_activity.id)
+    end
   end
 
   describe "followers" do
@@ -253,7 +292,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     test "getting followers, hide_followers", %{conn: conn} do
       user = insert(:user)
-      other_user = insert(:user, %{info: %{hide_followers: true}})
+      other_user = insert(:user, hide_followers: true)
       {:ok, _user} = User.follow(user, other_user)
 
       conn =
@@ -265,7 +304,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     test "getting followers, hide_followers, same user requesting", %{conn: conn} do
       user = insert(:user)
-      other_user = insert(:user, %{info: %{hide_followers: true}})
+      other_user = insert(:user, hide_followers: true)
       {:ok, _user} = User.follow(user, other_user)
 
       conn =
@@ -333,7 +372,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
     end
 
     test "getting following, hide_follows", %{conn: conn} do
-      user = insert(:user, %{info: %{hide_follows: true}})
+      user = insert(:user, hide_follows: true)
       other_user = insert(:user)
       {:ok, user} = User.follow(user, other_user)
 
@@ -345,7 +384,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
     end
 
     test "getting following, hide_follows, same user requesting", %{conn: conn} do
-      user = insert(:user, %{info: %{hide_follows: true}})
+      user = insert(:user, hide_follows: true)
       other_user = insert(:user)
       {:ok, user} = User.follow(user, other_user)
 
@@ -455,7 +494,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
       conn =
         build_conn()
-        |> assign(:user, follower)
+        |> assign(:user, User.get_cached_by_id(follower.id))
         |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true")
 
       assert %{"showing_reblogs" => true} = json_response(conn, 200)
@@ -595,4 +634,286 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
   end
+
+  describe "create account by app" do
+    setup do
+      valid_params = %{
+        username: "lain",
+        email: "lain@example.org",
+        password: "PlzDontHackLain",
+        agreement: true
+      }
+
+      [valid_params: valid_params]
+    end
+
+    test "Account registration via Application", %{conn: conn} do
+      conn =
+        conn
+        |> post("/api/v1/apps", %{
+          client_name: "client_name",
+          redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
+          scopes: "read, write, follow"
+        })
+
+      %{
+        "client_id" => client_id,
+        "client_secret" => client_secret,
+        "id" => _,
+        "name" => "client_name",
+        "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
+        "vapid_key" => _,
+        "website" => nil
+      } = json_response(conn, 200)
+
+      conn =
+        conn
+        |> post("/oauth/token", %{
+          grant_type: "client_credentials",
+          client_id: client_id,
+          client_secret: client_secret
+        })
+
+      assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
+               json_response(conn, 200)
+
+      assert token
+      token_from_db = Repo.get_by(Token, token: token)
+      assert token_from_db
+      assert refresh
+      assert scope == "read write follow"
+
+      conn =
+        build_conn()
+        |> put_req_header("authorization", "Bearer " <> token)
+        |> post("/api/v1/accounts", %{
+          username: "lain",
+          email: "lain@example.org",
+          password: "PlzDontHackLain",
+          bio: "Test Bio",
+          agreement: true
+        })
+
+      %{
+        "access_token" => token,
+        "created_at" => _created_at,
+        "scope" => _scope,
+        "token_type" => "Bearer"
+      } = json_response(conn, 200)
+
+      token_from_db = Repo.get_by(Token, token: token)
+      assert token_from_db
+      token_from_db = Repo.preload(token_from_db, :user)
+      assert token_from_db.user
+
+      assert token_from_db.user.confirmation_pending
+    end
+
+    test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
+      _user = insert(:user, email: "lain@example.org")
+      app_token = insert(:oauth_token, user: nil)
+
+      conn =
+        conn
+        |> put_req_header("authorization", "Bearer " <> app_token.token)
+
+      res = post(conn, "/api/v1/accounts", valid_params)
+      assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"}
+    end
+
+    test "rate limit", %{conn: conn} do
+      app_token = insert(:oauth_token, user: nil)
+
+      conn =
+        put_req_header(conn, "authorization", "Bearer " <> app_token.token)
+        |> Map.put(:remote_ip, {15, 15, 15, 15})
+
+      for i <- 1..5 do
+        conn =
+          conn
+          |> post("/api/v1/accounts", %{
+            username: "#{i}lain",
+            email: "#{i}lain@example.org",
+            password: "PlzDontHackLain",
+            agreement: true
+          })
+
+        %{
+          "access_token" => token,
+          "created_at" => _created_at,
+          "scope" => _scope,
+          "token_type" => "Bearer"
+        } = json_response(conn, 200)
+
+        token_from_db = Repo.get_by(Token, token: token)
+        assert token_from_db
+        token_from_db = Repo.preload(token_from_db, :user)
+        assert token_from_db.user
+
+        assert token_from_db.user.confirmation_pending
+      end
+
+      conn =
+        conn
+        |> post("/api/v1/accounts", %{
+          username: "6lain",
+          email: "6lain@example.org",
+          password: "PlzDontHackLain",
+          agreement: true
+        })
+
+      assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
+    end
+
+    test "returns bad_request if missing required params", %{
+      conn: conn,
+      valid_params: valid_params
+    } do
+      app_token = insert(:oauth_token, user: nil)
+
+      conn =
+        conn
+        |> put_req_header("authorization", "Bearer " <> app_token.token)
+
+      res = post(conn, "/api/v1/accounts", valid_params)
+      assert json_response(res, 200)
+
+      [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
+      |> Stream.zip(valid_params)
+      |> Enum.each(fn {ip, {attr, _}} ->
+        res =
+          conn
+          |> Map.put(:remote_ip, ip)
+          |> post("/api/v1/accounts", Map.delete(valid_params, attr))
+          |> json_response(400)
+
+        assert res == %{"error" => "Missing parameters"}
+      end)
+    end
+
+    test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
+      conn =
+        conn
+        |> put_req_header("authorization", "Bearer " <> "invalid-token")
+
+      res = post(conn, "/api/v1/accounts", valid_params)
+      assert json_response(res, 403) == %{"error" => "Invalid credentials"}
+    end
+  end
+
+  describe "GET /api/v1/accounts/:id/lists - account_lists" do
+    test "returns lists to which the account belongs", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+      assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user)
+      {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user)
+
+      res =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/#{other_user.id}/lists")
+        |> json_response(200)
+
+      assert res == [%{"id" => to_string(list.id), "title" => "Test List"}]
+    end
+  end
+
+  describe "verify_credentials" do
+    test "verify_credentials", %{conn: conn} do
+      user = insert(:user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/verify_credentials")
+
+      response = json_response(conn, 200)
+
+      assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
+      assert response["pleroma"]["chat_token"]
+      assert id == to_string(user.id)
+    end
+
+    test "verify_credentials default scope unlisted", %{conn: conn} do
+      user = insert(:user, default_scope: "unlisted")
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/verify_credentials")
+
+      assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
+      assert id == to_string(user.id)
+    end
+
+    test "locked accounts", %{conn: conn} do
+      user = insert(:user, default_scope: "private")
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/verify_credentials")
+
+      assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
+      assert id == to_string(user.id)
+    end
+  end
+
+  describe "user relationships" do
+    test "returns the relationships for the current user", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+      {:ok, user} = User.follow(user, other_user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
+
+      assert [relationship] = json_response(conn, 200)
+
+      assert to_string(other_user.id) == relationship["id"]
+    end
+
+    test "returns an empty list on a bad request", %{conn: conn} do
+      user = insert(:user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/v1/accounts/relationships", %{})
+
+      assert [] = json_response(conn, 200)
+    end
+  end
+
+  test "getting a list of mutes", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    {:ok, user} = User.mute(user, other_user)
+
+    conn =
+      conn
+      |> assign(:user, user)
+      |> get("/api/v1/mutes")
+
+    other_user_id = to_string(other_user.id)
+    assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
+  end
+
+  test "getting a list of blocks", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    {:ok, user} = User.block(user, other_user)
+
+    conn =
+      conn
+      |> assign(:user, user)
+      |> get("/api/v1/blocks")
+
+    other_user_id = to_string(other_user.id)
+    assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
+  end
 end