Merge branch '210_twitter_api_uploads_alt_text' into 'develop'
[akkoma] / test / web / twitter_api / twitter_api_controller_test.exs
index 788e3a6eb9ec56347dca0eea6b00d5980b867b92..4119d1dd8142b03ffe996f3c072b67b66e27bba9 100644 (file)
@@ -12,30 +12,47 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
 
   import Pleroma.Factory
 
-  describe "POST /api/account/verify_credentials" do
-    setup [:valid_user]
+  describe "POST /api/account/update_profile_banner" do
+    test "it updates the banner", %{conn: conn} do
+      user = insert(:user)
 
-    test "without valid credentials", %{conn: conn} do
-      conn = post(conn, "/api/account/verify_credentials.json")
-      assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+      new_banner =
+        "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
+
+      response =
+        conn
+        |> assign(:user, user)
+        |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => new_banner})
+        |> json_response(200)
+
+      user = Repo.get(User, user.id)
+      assert user.info.banner["type"] == "Image"
     end
+  end
 
-    test "with credentials", %{conn: conn, user: user} do
-      conn =
+  describe "POST /api/qvitter/update_background_image" do
+    test "it updates the background", %{conn: conn} do
+      user = insert(:user)
+
+      new_bg =
+        "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
+
+      response =
         conn
-        |> with_credentials(user.nickname, "test")
-        |> post("/api/account/verify_credentials.json")
+        |> assign(:user, user)
+        |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => new_bg})
+        |> json_response(200)
 
-      assert response = json_response(conn, 200)
-      assert response == UserView.render("show.json", %{user: user, token: response["token"]})
+      user = Repo.get(User, user.id)
+      assert user.info.background["type"] == "Image"
     end
   end
 
-  describe "POST /api/account/most_recent_notification" do
+  describe "POST /api/account/verify_credentials" do
     setup [:valid_user]
 
     test "without valid credentials", %{conn: conn} do
-      conn = post(conn, "/api/account/most_recent_notification.json")
+      conn = post(conn, "/api/account/verify_credentials.json")
       assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
     end
 
@@ -43,11 +60,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       conn =
         conn
         |> with_credentials(user.nickname, "test")
-        |> post("/api/account/most_recent_notification.json", %{id: "200"})
+        |> post("/api/account/verify_credentials.json")
 
-      assert json_response(conn, 200)
-      user = User.get_by_nickname(user.nickname)
-      assert user.info["most_recent_notification"] == 200
+      assert response = json_response(conn, 200)
+      assert response == UserView.render("show.json", %{user: user, token: response["token"]})
     end
   end
 
@@ -87,7 +103,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
 
   describe "GET /statuses/public_timeline.json" do
     test "returns statuses", %{conn: conn} do
-      {:ok, user} = UserBuilder.insert()
+      user = insert(:user)
       activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
       ActivityBuilder.insert_list(10, %{}, %{user: user})
       since_id = List.last(activities).id
@@ -284,6 +300,12 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
           "visibility" => "direct"
         })
 
+      {:ok, direct_two} =
+        CommonAPI.post(user_two, %{
+          "status" => "Hi @#{user_one.nickname}!",
+          "visibility" => "direct"
+        })
+
       {:ok, _follower_only} =
         CommonAPI.post(user_one, %{
           "status" => "Hi @#{user_two.nickname}!",
@@ -296,8 +318,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         |> assign(:user, user_two)
         |> get("/api/statuses/dm_timeline.json")
 
-      [status] = json_response(res_conn, 200)
-      assert status["id"] == direct.id
+      [status, status_two] = json_response(res_conn, 200)
+      assert status["id"] == direct_two.id
+      assert status_two["id"] == direct.id
     end
   end
 
@@ -584,7 +607,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
 
       current_user = Repo.get(User, current_user.id)
-      assert current_user.info["blocks"] == []
+      assert current_user.info.blocks == []
 
       assert json_response(conn, 200) ==
                UserView.render("show.json", %{user: blocked, for: current_user})
@@ -838,6 +861,67 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       result = json_response(conn, 200)
       assert Enum.sort(expected) == Enum.sort(result)
     end
+
+    test "it returns a given user's followers with user_id", %{conn: conn} do
+      user = insert(:user)
+      follower_one = insert(:user)
+      follower_two = insert(:user)
+      not_follower = insert(:user)
+
+      {:ok, follower_one} = User.follow(follower_one, user)
+      {:ok, follower_two} = User.follow(follower_two, user)
+
+      conn =
+        conn
+        |> assign(:user, not_follower)
+        |> get("/api/statuses/followers", %{"user_id" => user.id})
+
+      assert MapSet.equal?(
+               MapSet.new(json_response(conn, 200)),
+               MapSet.new(
+                 UserView.render("index.json", %{
+                   users: [follower_one, follower_two],
+                   for: not_follower
+                 })
+               )
+             )
+    end
+
+    test "it returns empty for a hidden network", %{conn: conn} do
+      user = insert(:user, %{info: %{hide_network: true}})
+      follower_one = insert(:user)
+      follower_two = insert(:user)
+      not_follower = insert(:user)
+
+      {:ok, follower_one} = User.follow(follower_one, user)
+      {:ok, follower_two} = User.follow(follower_two, user)
+
+      conn =
+        conn
+        |> assign(:user, not_follower)
+        |> get("/api/statuses/followers", %{"user_id" => user.id})
+
+      assert [] == json_response(conn, 200)
+    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}})
+      follower_one = insert(:user)
+      follower_two = insert(:user)
+      not_follower = insert(:user)
+
+      {:ok, follower_one} = User.follow(follower_one, user)
+      {:ok, follower_two} = User.follow(follower_two, user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/followers", %{"user_id" => user.id})
+
+      refute [] == json_response(conn, 200)
+    end
   end
 
   describe "GET /api/statuses/friends" do
@@ -882,6 +966,42 @@ 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}})
+      followed_one = insert(:user)
+      followed_two = insert(:user)
+      not_followed = insert(:user)
+
+      {:ok, user} = User.follow(user, followed_one)
+      {:ok, user} = User.follow(user, followed_two)
+
+      conn =
+        conn
+        |> assign(:user, not_followed)
+        |> get("/api/statuses/friends", %{"user_id" => user.id})
+
+      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}})
+      followed_one = insert(:user)
+      followed_two = insert(:user)
+      not_followed = insert(:user)
+
+      {:ok, user} = User.follow(user, followed_one)
+      {:ok, user} = User.follow(user, followed_two)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> get("/api/statuses/friends", %{"user_id" => user.id})
+
+      refute [] == json_response(conn, 200)
+    end
+
     test "it returns a given user's friends with screen_name", %{conn: conn} do
       user = insert(:user)
       followed_one = insert(:user)
@@ -932,19 +1052,48 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   describe "POST /api/account/update_profile.json" do
     test "it updates a user's profile", %{conn: conn} do
       user = insert(:user)
+      user2 = insert(:user)
 
       conn =
         conn
         |> assign(:user, user)
         |> post("/api/account/update_profile.json", %{
           "name" => "new name",
-          "description" => "new description"
+          "description" => "hi @#{user2.nickname}"
         })
 
       user = Repo.get!(User, user.id)
       assert user.name == "new name"
-      assert user.bio == "new description"
 
+      assert user.bio ==
+               "hi <span><a data-user='#{user2.id}' class='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_network", %{conn: conn} do
+      user = insert(:user)
+
+      conn
+      |> assign(:user, user)
+      |> post("/api/account/update_profile.json", %{
+        "hide_network" => "true"
+      })
+
+      user = Repo.get!(User, user.id)
+      assert user.info.hide_network == true
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> post("/api/account/update_profile.json", %{
+          "hide_network" => "false"
+        })
+
+      user = Repo.get!(User, user.id)
+      assert user.info.hide_network == false
       assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
     end
 
@@ -959,7 +1108,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         })
 
       user = Repo.get!(User, user.id)
-      assert user.info["locked"] == true
+      assert user.info.locked == true
 
       assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
     end
@@ -975,7 +1124,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
         })
 
       user = Repo.get!(User, user.id)
-      assert user.info["locked"] == false
+      assert user.info.locked == false
 
       assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
     end
@@ -1146,10 +1295,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
 
   describe "GET /api/pleroma/friend_requests" do
     test "it lists friend requests" do
-      user = insert(:user, %{info: %{"locked" => true}})
+      user = insert(:user)
       other_user = insert(:user)
 
-      {:ok, activity} = ActivityPub.follow(other_user, user)
+      {:ok, _activity} = ActivityPub.follow(other_user, user)
 
       user = Repo.get(User, user.id)
       other_user = Repo.get(User, other_user.id)
@@ -1168,10 +1317,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
 
   describe "POST /api/pleroma/friendships/approve" do
     test "it approves a friend request" do
-      user = insert(:user, %{info: %{"locked" => true}})
+      user = insert(:user)
       other_user = insert(:user)
 
-      {:ok, activity} = ActivityPub.follow(other_user, user)
+      {:ok, _activity} = ActivityPub.follow(other_user, user)
 
       user = Repo.get(User, user.id)
       other_user = Repo.get(User, other_user.id)
@@ -1191,10 +1340,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
 
   describe "POST /api/pleroma/friendships/deny" do
     test "it denies a friend request" do
-      user = insert(:user, %{info: %{"locked" => true}})
+      user = insert(:user)
       other_user = insert(:user)
 
-      {:ok, activity} = ActivityPub.follow(other_user, user)
+      {:ok, _activity} = ActivityPub.follow(other_user, user)
 
       user = Repo.get(User, user.id)
       other_user = Repo.get(User, other_user.id)
@@ -1211,4 +1360,98 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert relationship["follows_you"] == false
     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"})
+
+      resp =
+        conn
+        |> get(twitter_api_search__path(conn, :search_user), query: "eal")
+        |> json_response(200)
+
+      assert length(resp) == 3
+      assert [user.id, user_two.id, user_three.id] == Enum.map(resp, fn %{"id" => id} -> id end)
+    end
+  end
+
+  describe "POST /api/media/upload" do
+    setup context do
+      Pleroma.DataCase.ensure_local_uploader(context)
+    end
+
+    test "it performs the upload and sets `data[actor]` with AP id of uploader user", %{
+      conn: conn
+    } do
+      user = insert(:user)
+
+      upload_filename = "test/fixtures/image_tmp.jpg"
+      File.cp!("test/fixtures/image.jpg", upload_filename)
+
+      file = %Plug.Upload{
+        content_type: "image/jpg",
+        path: Path.absname(upload_filename),
+        filename: "image.jpg"
+      }
+
+      response =
+        conn
+        |> assign(:user, user)
+        |> put_req_header("content-type", "application/octet-stream")
+        |> post("/api/media/upload", %{
+          "media" => file
+        })
+        |> json_response(:ok)
+
+      assert response["media_id"]
+      object = Repo.get(Object, response["media_id"])
+      assert object
+      assert object.data["actor"] == User.ap_id(user)
+    end
+  end
+
+  describe "POST /api/media/metadata/create" do
+    setup do
+      object = insert(:note)
+      user = User.get_by_ap_id(object.data["actor"])
+      %{object: object, user: user}
+    end
+
+    test "it returns :forbidden status on attempt to modify someone else's upload", %{
+      conn: conn,
+      object: object
+    } do
+      initial_description = object.data["name"]
+      another_user = insert(:user)
+
+      conn
+      |> assign(:user, another_user)
+      |> post("/api/media/metadata/create", %{"media_id" => object.id})
+      |> json_response(:forbidden)
+
+      object = Repo.get(Object, object.id)
+      assert object.data["name"] == initial_description
+    end
+
+    test "it updates `data[name]` of referenced Object with provided value", %{
+      conn: conn,
+      object: object,
+      user: user
+    } do
+      description = "Informative description of the image. Initial value: #{object.data["name"]}}"
+
+      conn
+      |> assign(:user, user)
+      |> post("/api/media/metadata/create", %{
+        "media_id" => object.id,
+        "alt_text" => %{"text" => description}
+      })
+      |> json_response(:no_content)
+
+      object = Repo.get(Object, object.id)
+      assert object.data["name"] == description
+    end
+  end
 end