Merge branch 'feature/add-oauth-tokens-endpoint' into 'develop'
[akkoma] / test / web / twitter_api / twitter_api_controller_test.exs
index a4526eeda84b6a57763f09ac6a04d6c3bbf4c760..1571ab68e5a453360f7a80d96e3a3864d753a8df 100644 (file)
@@ -1,13 +1,19 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   use Pleroma.Web.ConnCase
   alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
-  alias Pleroma.Builders.{ActivityBuilder, UserBuilder}
-  alias Pleroma.{Repo, Activity, User, Object, Notification}
+  alias Pleroma.Builders.ActivityBuilder
+  alias Pleroma.Builders.UserBuilder
+  alias Pleroma.Repo
+  alias Pleroma.Activity
+  alias Pleroma.User
+  alias Pleroma.Object
+  alias Pleroma.Notification
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.OAuth.Token
   alias Pleroma.Web.TwitterAPI.UserView
   alias Pleroma.Web.TwitterAPI.NotificationView
   alias Pleroma.Web.CommonAPI
@@ -62,7 +68,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         |> post("/api/account/verify_credentials.json")
         |> json_response(200)
 
-      assert response == UserView.render("show.json", %{user: user, token: response["token"]})
+      assert response ==
+               UserView.render("show.json", %{user: user, token: response["token"], for: user})
     end
   end
 
@@ -107,7 +114,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         |> post(request_path, %{status: "Nice meme.", visibility: "private"})
 
       assert json_response(conn, 200) ==
-               ActivityRepresenter.to_map(Repo.one(Activity), %{user: user})
+               ActivityRepresenter.to_map(Repo.one(Activity), %{user: user, for: user})
     end
   end
 
@@ -418,6 +425,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert Enum.at(response, 0) ==
                ActivityRepresenter.to_map(activity, %{
                  user: current_user,
+                 for: current_user,
                  mentioned: [current_user]
                })
     end
@@ -547,7 +555,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       response = json_response(conn, 200)
 
       assert length(response) == 1
-      assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
+
+      assert Enum.at(response, 0) ==
+               ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
     end
 
     test "with credentials with user_id", %{conn: conn, user: current_user} do
@@ -631,6 +641,24 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert json_response(conn, 200) ==
                UserView.render("show.json", %{user: followed, for: current_user})
     end
+
+    test "for restricted account", %{conn: conn, user: current_user} do
+      followed = insert(:user, info: %User.Info{locked: true})
+
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> post("/api/friendships/create.json", %{user_id: followed.id})
+
+      current_user = Repo.get(User, current_user.id)
+      followed = Repo.get(User, followed.id)
+
+      refute User.ap_followers(followed) in current_user.following
+      assert followed.info.follow_request_count == 1
+
+      assert json_response(conn, 200) ==
+               UserView.render("show.json", %{user: followed, for: current_user})
+    end
   end
 
   describe "POST /friendships/destroy.json" do
@@ -797,7 +825,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         |> with_credentials(current_user.nickname, "test")
         |> post("/api/favorites/create/1.json")
 
-      assert json_response(conn, 500)
+      assert json_response(conn, 400)
     end
   end
 
@@ -1082,6 +1110,31 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert Enum.sort(expected) == Enum.sort(result)
     end
 
+    test "it returns 20 followers per page", %{conn: conn} do
+      user = insert(:user)
+      followers = insert_list(21, :user)
+
+      Enum.each(followers, fn follower ->
+        User.follow(follower, user)
+      end)
+
+      res_conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/followers")
+
+      result = json_response(res_conn, 200)
+      assert length(result) == 20
+
+      res_conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/followers?page=2")
+
+      result = json_response(res_conn, 200)
+      assert length(result) == 1
+    end
+
     test "it returns a given user's followers with user_id", %{conn: conn} do
       user = insert(:user)
       follower_one = insert(:user)
@@ -1107,8 +1160,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
              )
     end
 
-    test "it returns empty for a hidden network", %{conn: conn} do
-      user = insert(:user, %{info: %{hide_network: true}})
+    test "it returns empty when hide_followers is set to true", %{conn: conn} do
+      user = insert(:user, %{info: %{hide_followers: true}})
       follower_one = insert(:user)
       follower_two = insert(:user)
       not_follower = insert(:user)
@@ -1125,10 +1178,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert [] == response
     end
 
-    test "it returns the followers for a hidden network if requested by the user themselves", %{
-      conn: conn
-    } do
-      user = insert(:user, %{info: %{hide_network: true}})
+    test "it returns the followers when hide_followers is set to true if requested by the user themselves",
+         %{
+           conn: conn
+         } do
+      user = insert(:user, %{info: %{hide_followers: true}})
       follower_one = insert(:user)
       follower_two = insert(:user)
       _not_follower = insert(:user)
@@ -1145,6 +1199,24 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     end
   end
 
+  describe "GET /api/statuses/blocks" do
+    test "it returns the list of users blocked by requester", %{conn: conn} do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, user} = User.block(user, other_user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/blocks")
+
+      expected = UserView.render("index.json", %{users: [other_user], for: user})
+      result = json_response(conn, 200)
+      assert Enum.sort(expected) == Enum.sort(result)
+    end
+  end
+
   describe "GET /api/statuses/friends" do
     test "it returns the logged in user's friends", %{conn: conn} do
       user = insert(:user)
@@ -1165,6 +1237,40 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert Enum.sort(expected) == Enum.sort(result)
     end
 
+    test "it returns 20 friends per page, except if 'export' is set to true", %{conn: conn} do
+      user = insert(:user)
+      followeds = insert_list(21, :user)
+
+      {:ok, user} =
+        Enum.reduce(followeds, {:ok, user}, fn followed, {:ok, user} ->
+          User.follow(user, followed)
+        end)
+
+      res_conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/friends")
+
+      result = json_response(res_conn, 200)
+      assert length(result) == 20
+
+      res_conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/friends", %{page: 2})
+
+      result = json_response(res_conn, 200)
+      assert length(result) == 1
+
+      res_conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/friends", %{all: true})
+
+      result = json_response(res_conn, 200)
+      assert length(result) == 21
+    end
+
     test "it returns a given user's friends with user_id", %{conn: conn} do
       user = insert(:user)
       followed_one = insert(:user)
@@ -1187,8 +1293,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
              )
     end
 
-    test "it returns empty for a hidden network", %{conn: conn} do
-      user = insert(:user, %{info: %{hide_network: true}})
+    test "it returns empty when hide_follows is set to true", %{conn: conn} do
+      user = insert(:user, %{info: %{hide_follows: true}})
       followed_one = insert(:user)
       followed_two = insert(:user)
       not_followed = insert(:user)
@@ -1204,10 +1310,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert [] == json_response(conn, 200)
     end
 
-    test "it returns friends for a hidden network if the user themselves request it", %{
-      conn: conn
-    } do
-      user = insert(:user, %{info: %{hide_network: true}})
+    test "it returns friends when hide_follows is set to true if the user themselves request it",
+         %{
+           conn: conn
+         } do
+      user = insert(:user, %{info: %{hide_follows: true}})
       followed_one = insert(:user)
       followed_two = insert(:user)
       _not_followed = insert(:user)
@@ -1288,34 +1395,82 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert user.name == "new name"
 
       assert user.bio ==
-               "hi <span><a data-user='#{user2.id}' class='mention' href='#{user2.ap_id}'>@<span>#{
-                 user2.nickname
-               }</span></a></span>"
+               "hi <span class='h-card'><a data-user='#{user2.id}' class='u-url mention' href='#{
+                 user2.ap_id
+               }'>@<span>#{user2.nickname}</span></a></span>"
+
+      assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
+    end
+
+    test "it sets and un-sets hide_follows", %{conn: conn} do
+      user = insert(:user)
+
+      conn
+      |> assign(:user, user)
+      |> post("/api/account/update_profile.json", %{
+        "hide_follows" => "true"
+      })
+
+      user = Repo.get!(User, user.id)
+      assert user.info.hide_follows == true
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> post("/api/account/update_profile.json", %{
+          "hide_follows" => "false"
+        })
+
+      user = Repo.get!(User, user.id)
+      assert user.info.hide_follows == false
+      assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
+    end
+
+    test "it sets and un-sets hide_followers", %{conn: conn} do
+      user = insert(:user)
+
+      conn
+      |> assign(:user, user)
+      |> post("/api/account/update_profile.json", %{
+        "hide_followers" => "true"
+      })
+
+      user = Repo.get!(User, user.id)
+      assert user.info.hide_followers == true
 
+      conn =
+        conn
+        |> assign(:user, user)
+        |> post("/api/account/update_profile.json", %{
+          "hide_followers" => "false"
+        })
+
+      user = Repo.get!(User, user.id)
+      assert user.info.hide_followers == false
       assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
     end
 
-    test "it sets and un-sets hide_network", %{conn: conn} do
+    test "it sets and un-sets show_role", %{conn: conn} do
       user = insert(:user)
 
       conn
       |> assign(:user, user)
       |> post("/api/account/update_profile.json", %{
-        "hide_network" => "true"
+        "show_role" => "true"
       })
 
       user = Repo.get!(User, user.id)
-      assert user.info.hide_network == true
+      assert user.info.show_role == true
 
       conn =
         conn
         |> assign(:user, user)
         |> post("/api/account/update_profile.json", %{
-          "hide_network" => "false"
+          "show_role" => "false"
         })
 
       user = Repo.get!(User, user.id)
-      assert user.info.hide_network == false
+      assert user.info.show_role == false
       assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
     end
 
@@ -1548,15 +1703,19 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       other_user = Repo.get(User, other_user.id)
 
       assert User.following?(other_user, user) == false
+      assert user.info.follow_request_count == 1
 
       conn =
         build_conn()
         |> assign(:user, user)
-        |> post("/api/pleroma/friendships/approve", %{"user_id" => to_string(other_user.id)})
+        |> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
+
+      user = Repo.get(User, user.id)
 
       assert relationship = json_response(conn, 200)
       assert other_user.id == relationship["id"]
       assert relationship["follows_you"] == true
+      assert user.info.follow_request_count == 0
     end
   end
 
@@ -1571,31 +1730,35 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       other_user = Repo.get(User, other_user.id)
 
       assert User.following?(other_user, user) == false
+      assert user.info.follow_request_count == 1
 
       conn =
         build_conn()
         |> assign(:user, user)
-        |> post("/api/pleroma/friendships/deny", %{"user_id" => to_string(other_user.id)})
+        |> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
+
+      user = Repo.get(User, user.id)
 
       assert relationship = json_response(conn, 200)
       assert other_user.id == relationship["id"]
       assert relationship["follows_you"] == false
+      assert user.info.follow_request_count == 0
     end
   end
 
   describe "GET /api/pleroma/search_user" do
     test "it returns users, ordered by similarity", %{conn: conn} do
       user = insert(:user, %{name: "eal"})
-      user_two = insert(:user, %{name: "ean"})
-      user_three = insert(:user, %{name: "ebn"})
+      user_two = insert(:user, %{name: "eal me"})
+      _user_three = insert(:user, %{name: "zzz"})
 
       resp =
         conn
-        |> get(twitter_api_search__path(conn, :search_user), query: "eal")
+        |> get(twitter_api_search__path(conn, :search_user), query: "eal me")
         |> json_response(200)
 
-      assert length(resp) == 3
-      assert [user.id, user_two.id, user_three.id] == Enum.map(resp, fn %{"id" => id} -> id end)
+      assert length(resp) == 2
+      assert [user_two.id, user.id] == Enum.map(resp, fn %{"id" => id} -> id end)
     end
   end
 
@@ -1676,4 +1839,115 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert object.data["name"] == description
     end
   end
+
+  describe "POST /api/statuses/user_timeline.json?user_id=:user_id&pinned=true" do
+    test "it returns a list of pinned statuses", %{conn: conn} do
+      Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
+
+      user = insert(:user, %{name: "egor"})
+      {:ok, %{id: activity_id}} = CommonAPI.post(user, %{"status" => "HI!!!"})
+      {:ok, _} = CommonAPI.pin(activity_id, user)
+
+      resp =
+        conn
+        |> get("/api/statuses/user_timeline.json", %{user_id: user.id, pinned: true})
+        |> json_response(200)
+
+      assert length(resp) == 1
+      assert [%{"id" => ^activity_id, "pinned" => true}] = resp
+    end
+  end
+
+  describe "POST /api/statuses/pin/:id" do
+    setup do
+      Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
+      [user: insert(:user)]
+    end
+
+    test "without valid credentials", %{conn: conn} do
+      note_activity = insert(:note_activity)
+      conn = post(conn, "/api/statuses/pin/#{note_activity.id}.json")
+      assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+    end
+
+    test "with credentials", %{conn: conn, user: user} do
+      {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
+
+      request_path = "/api/statuses/pin/#{activity.id}.json"
+
+      response =
+        conn
+        |> with_credentials(user.nickname, "test")
+        |> post(request_path)
+
+      user = refresh_record(user)
+
+      assert json_response(response, 200) ==
+               ActivityRepresenter.to_map(activity, %{user: user, for: user})
+    end
+  end
+
+  describe "POST /api/statuses/unpin/:id" do
+    setup do
+      Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
+      [user: insert(:user)]
+    end
+
+    test "without valid credentials", %{conn: conn} do
+      note_activity = insert(:note_activity)
+      conn = post(conn, "/api/statuses/unpin/#{note_activity.id}.json")
+      assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+    end
+
+    test "with credentials", %{conn: conn, user: user} do
+      {:ok, activity} = CommonAPI.post(user, %{"status" => "test!"})
+      {:ok, activity} = CommonAPI.pin(activity.id, user)
+
+      request_path = "/api/statuses/unpin/#{activity.id}.json"
+
+      response =
+        conn
+        |> with_credentials(user.nickname, "test")
+        |> post(request_path)
+
+      user = refresh_record(user)
+
+      assert json_response(response, 200) ==
+               ActivityRepresenter.to_map(activity, %{user: user, for: user})
+    end
+  end
+
+  describe "GET /api/oauth_tokens" do
+    setup do
+      token = insert(:oauth_token) |> Repo.preload(:user)
+
+      %{token: token}
+    end
+
+    test "renders list", %{token: token} do
+      response =
+        build_conn()
+        |> assign(:user, token.user)
+        |> get("/api/oauth_tokens")
+
+      keys =
+        json_response(response, 200)
+        |> hd()
+        |> Map.keys()
+
+      assert keys -- ["id", "app_name", "valid_until"] == []
+    end
+
+    test "revoke token", %{token: token} do
+      response =
+        build_conn()
+        |> assign(:user, token.user)
+        |> delete("/api/oauth_tokens/#{token.id}")
+
+      tokens = Token.get_user_tokens(token.user)
+
+      assert tokens == []
+      assert response.status == 201
+    end
+  end
 end