Merge branch 'i1t/pleroma-477_user_search_improvements' into 'develop'
[akkoma] / test / web / twitter_api / twitter_api_controller_test.exs
index cbb5f77962b0d0a9cc7d1087d0da5ffa2700ae38..f22cdd870761c1c8228561562a2d77ac8f6009df 100644 (file)
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# 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
@@ -108,6 +112,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   end
 
   describe "GET /statuses/public_timeline.json" do
+    setup [:valid_user]
+
     test "returns statuses", %{conn: conn} do
       user = insert(:user)
       activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
@@ -141,14 +147,44 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       Application.put_env(:pleroma, :instance, instance)
     end
 
+    test "returns 200 to authenticated request when the instance is not public",
+         %{conn: conn, user: user} do
+      instance =
+        Application.get_env(:pleroma, :instance)
+        |> Keyword.put(:public, false)
+
+      Application.put_env(:pleroma, :instance, instance)
+
+      conn
+      |> with_credentials(user.nickname, "test")
+      |> get("/api/statuses/public_timeline.json")
+      |> json_response(200)
+
+      instance =
+        Application.get_env(:pleroma, :instance)
+        |> Keyword.put(:public, true)
+
+      Application.put_env(:pleroma, :instance, instance)
+    end
+
     test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
       conn
       |> get("/api/statuses/public_timeline.json")
       |> json_response(200)
     end
+
+    test "returns 200 to authenticated request when the instance is public",
+         %{conn: conn, user: user} do
+      conn
+      |> with_credentials(user.nickname, "test")
+      |> get("/api/statuses/public_timeline.json")
+      |> json_response(200)
+    end
   end
 
   describe "GET /statuses/public_and_external_timeline.json" do
+    setup [:valid_user]
+
     test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
       instance =
         Application.get_env(:pleroma, :instance)
@@ -167,11 +203,39 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       Application.put_env(:pleroma, :instance, instance)
     end
 
+    test "returns 200 to authenticated request when the instance is not public",
+         %{conn: conn, user: user} do
+      instance =
+        Application.get_env(:pleroma, :instance)
+        |> Keyword.put(:public, false)
+
+      Application.put_env(:pleroma, :instance, instance)
+
+      conn
+      |> with_credentials(user.nickname, "test")
+      |> get("/api/statuses/public_and_external_timeline.json")
+      |> json_response(200)
+
+      instance =
+        Application.get_env(:pleroma, :instance)
+        |> Keyword.put(:public, true)
+
+      Application.put_env(:pleroma, :instance, instance)
+    end
+
     test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
       conn
       |> get("/api/statuses/public_and_external_timeline.json")
       |> json_response(200)
     end
+
+    test "returns 200 to authenticated request when the instance is public",
+         %{conn: conn, user: user} do
+      conn
+      |> with_credentials(user.nickname, "test")
+      |> get("/api/statuses/public_and_external_timeline.json")
+      |> json_response(200)
+    end
   end
 
   describe "GET /statuses/show/:id.json" do
@@ -515,6 +579,34 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert length(response) == 1
       assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
     end
+
+    test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
+      user = insert(:user)
+      {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
+      {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
+
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> get("/api/statuses/user_timeline.json", %{
+          "user_id" => user.id,
+          "include_rts" => "false"
+        })
+
+      response = json_response(conn, 200)
+
+      assert length(response) == 1
+      assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+      conn =
+        conn
+        |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
+
+      response = json_response(conn, 200)
+
+      assert length(response) == 1
+      assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+    end
   end
 
   describe "POST /friendships/create.json" do
@@ -873,35 +965,86 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     end
   end
 
-  describe "POST /api/email_invite, with valid parameters" do
-    setup [:valid_user]
-
+  describe "GET /api/account/confirm_email/:id/:token" do
     setup do
-      invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
-      Pleroma.Config.put([:instance, :invites_enabled], true)
+      user = insert(:user)
+      info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
 
-      on_exit(fn ->
-        Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
-        :ok
-      end)
+      {:ok, user} =
+        user
+        |> Changeset.change()
+        |> Changeset.put_embed(:info, info_change)
+        |> Repo.update()
+
+      assert user.info.confirmation_pending
 
-      :ok
+      [user: user]
     end
 
-    test "it returns 204", %{conn: conn, user: user} do
-      recipient_email = "foo@bar.com"
-      recipient_name = "J. D."
+    test "it redirects to root url", %{conn: conn, user: user} do
+      conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
 
-      conn =
-        conn
-        |> assign(:user, user)
-        |> post("/api/email_invite?email=#{recipient_email}&name=#{recipient_name}")
+      assert 302 == conn.status
+    end
 
-      assert json_response(conn, :no_content)
+    test "it confirms the user account", %{conn: conn, user: user} do
+      get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
 
-      Swoosh.TestAssertions.assert_email_sent(
-        Pleroma.UserEmail.user_invitation_email(user, recipient_email, recipient_name)
-      )
+      user = Repo.get(User, user.id)
+
+      refute user.info.confirmation_pending
+      refute user.info.confirmation_token
+    end
+
+    test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
+      conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
+
+      assert 500 == conn.status
+    end
+
+    test "it returns 500 if token is invalid", %{conn: conn, user: user} do
+      conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
+
+      assert 500 == conn.status
+    end
+  end
+
+  describe "POST /api/account/resend_confirmation_email" do
+    setup do
+      setting = Pleroma.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)
+      end
+
+      user = insert(:user)
+      info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
+
+      {:ok, user} =
+        user
+        |> Changeset.change()
+        |> Changeset.put_embed(:info, info_change)
+        |> Repo.update()
+
+      assert user.info.confirmation_pending
+
+      [user: user]
+    end
+
+    test "it returns 204 No Content", %{conn: conn, user: user} do
+      conn
+      |> assign(:user, user)
+      |> post("/api/account/resend_confirmation_email?email=#{user.email}")
+      |> json_response(:no_content)
+    end
+
+    test "it sends confirmation email", %{conn: conn, user: user} do
+      conn
+      |> assign(:user, user)
+      |> post("/api/account/resend_confirmation_email?email=#{user.email}")
+
+      Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
     end
   end
 
@@ -939,6 +1082,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)
@@ -1002,6 +1170,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)
@@ -1022,6 +1208,32 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert Enum.sort(expected) == Enum.sort(result)
     end
 
+    test "it returns 20 friends per page", %{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
+    end
+
     test "it returns a given user's friends with user_id", %{conn: conn} do
       user = insert(:user)
       followed_one = insert(:user)
@@ -1145,9 +1357,9 @@ 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
@@ -1443,16 +1655,16 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   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
 
@@ -1533,4 +1745,79 @@ 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})
+    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})
+    end
+  end
 end