Add following TwAPI endpoint.
authorRoger Braun <roger@rogerbraun.net>
Wed, 22 Mar 2017 17:36:08 +0000 (18:36 +0100)
committerRoger Braun <roger@rogerbraun.net>
Thu, 23 Mar 2017 11:09:27 +0000 (12:09 +0100)
lib/pleroma/user.ex
lib/pleroma/web/router.ex
lib/pleroma/web/twitter_api/twitter_api.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
test/user_test.exs
test/web/twitter_api/twitter_api_controller_test.exs
test/web/twitter_api/twitter_api_test.exs

index 6d9fe623d5781505ce5a8d9746f30a2a71f4da7a..29fd1de8b07125529efb55376fde433361cda398 100644 (file)
@@ -1,6 +1,7 @@
 defmodule Pleroma.User do
   use Ecto.Schema
-  alias Pleroma.User
+  import Ecto.Changeset
+  alias Pleroma.{Repo, User}
 
   schema "users" do
     field :bio, :string
@@ -26,4 +27,20 @@ defmodule Pleroma.User do
   def ap_followers(%User{} = user) do
     "#{ap_id(user)}/followers"
   end
+
+  def follow_changeset(struct, params \\ %{}) do
+    struct
+    |> cast(params, [:following])
+    |> validate_required([:following])
+  end
+
+  def follow(%User{} = follower, %User{} = followed) do
+    ap_followers = User.ap_followers(followed)
+    following = [ap_followers | follower.following]
+    |> Enum.uniq
+
+    follower
+    |> follow_changeset(%{following: following})
+    |> Repo.update
+  end
 end
index c34f03cbba02aa1cf9ddd9fc0e6c1b2b61e8be0a..6d854c538faea8cd8db352cc5110ba8ca031bea1 100644 (file)
@@ -31,5 +31,6 @@ defmodule Pleroma.Web.Router do
     post "/account/verify_credentials.json", TwitterAPI.Controller, :verify_credentials
     post "/statuses/update.json", TwitterAPI.Controller, :status_update
     get "/statuses/friends_timeline.json", TwitterAPI.Controller, :friends_timeline
+    post "/friendships/create.json", TwitterAPI.Controller, :follow
   end
 end
index 7e0ca42338a896f3442c86fd9453d1da2fac8725..fb093b22744c7126d014c82ca703247e176a52ea 100644 (file)
@@ -34,6 +34,14 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     |> activities_to_statuses
   end
 
+  def follow(%User{} = follower, followed_id) do
+    with %User{} = followed <- Repo.get(User, followed_id),
+         { :ok, follower } <- User.follow(follower, followed)
+    do
+      { :ok, follower, followed }
+    end
+  end
+
   defp activities_to_statuses(activities) do
     Enum.map(activities, fn(activity) ->
       actor = get_in(activity.data, ["actor"])
index 088439f488fbfca4fee55bb5107a2525790fd40e..ac319b1095309f7015f51d73323362d5cd1b2d8c 100644 (file)
@@ -32,6 +32,15 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
     |> json_reply(200, json)
   end
 
+  def follow(%{assigns: %{user: user}} = conn, %{ "user_id" => followed_id }) do
+    { :ok, _user, follower } = TwitterAPI.follow(user, followed_id)
+
+    response = follower |> UserRepresenter.to_json
+
+    conn
+    |> json_reply(200, response)
+  end
+
   defp json_reply(conn, status, json) do
     conn
     |> put_resp_content_type("application/json")
index 30e414437f1634ef7ce9776fa9d9aa5402cf5e47..e39c0be3152dd331b5ad428e6fbf469b40b4190b 100644 (file)
@@ -23,4 +23,15 @@ defmodule Pleroma.UserTest do
 
     assert expected_followers_collection == User.ap_followers(user)
   end
+
+  test "follow takes a user and an id and tries to follow another user" do
+    { :ok, user } = UserBuilder.insert
+    { :ok, following } = UserBuilder.insert(%{nickname: "guy"})
+
+    {:ok, user } = User.follow(user, following)
+
+    user = Repo.get(User, user.id)
+
+    assert user.following == [User.ap_followers(following)]
+  end
 end
index 86c03c652a89abee13396b81860546ef2d443b70..a504393beea3a4acfa3793101e5dcc56392985ff 100644 (file)
@@ -79,6 +79,26 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     end
   end
 
+  describe "POST /friendships/create.json" do
+    setup [:valid_user]
+    test "without valid credentials", %{conn: conn} do
+      conn = post conn, "/api/friendships/create.json"
+      assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+    end
+
+    test "with credentials", %{conn: conn, user: current_user} do
+      {:ok, followed } = UserBuilder.insert(%{name: "some guy"})
+
+      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)
+      assert current_user.following == [User.ap_followers(followed)]
+      assert json_response(conn, 200) == UserRepresenter.to_map(followed)
+    end
+  end
+
   defp valid_user(_context) do
     { :ok, user } = UserBuilder.insert(%{nickname: "lambda", ap_id: "lambda"})
     [user: user]
index 5c78790af92372079e7708b88f1c3bb12313a6f9..c9f79d2ff97f8ea015e5b9a288e6bb9c413898a3 100644 (file)
@@ -40,4 +40,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
     assert length(statuses) == 1
     assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: activity_user})
   end
+
+  test "Follow another user" do
+    { :ok, user } = UserBuilder.insert
+    { :ok, following } = UserBuilder.insert(%{nickname: "guy"})
+
+    {:ok, user, following } = TwitterAPI.follow(user, following.id)
+
+    user = Repo.get(User, user.id)
+
+    assert user.following == [User.ap_followers(following)]
+  end
 end