From: Roger Braun <rbraun@Bobble.local>
Date: Thu, 14 Sep 2017 16:30:05 +0000 (+0200)
Subject: MastoAPI: Follower-related changes
X-Git-Url: https://git.squeep.com/?a=commitdiff_plain;h=3ca853fb6165b82c39f23e24783e813015db48d5;p=akkoma

MastoAPI: Follower-related changes
---

diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 4a5bbb7b6..c713c561b 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -87,6 +87,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     |> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity})
   end
 
+  # TODO: Link headers
   def user_statuses(%{assigns: %{user: user}} = conn, params) do
     with %User{ap_id: ap_id} <- Repo.get(User, params["id"]) do
       params = params
@@ -230,6 +231,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
+  # TODO: Link headers
   def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do
     params = params
     |> Map.put("type", "Create")
@@ -242,6 +244,49 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     |> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity})
   end
 
+  # TODO: Pagination
+  def followers(conn, %{"id" => id}) do
+    with %User{} = user <- Repo.get(User, id),
+         {:ok, followers} <- User.get_followers(user) do
+      render conn, AccountView, "accounts.json", %{users: followers, as: :user}
+    end
+  end
+
+  def following(conn, %{"id" => id}) do
+    with %User{} = user <- Repo.get(User, id),
+         {:ok, followers} <- User.get_friends(user) do
+      render conn, AccountView, "accounts.json", %{users: followers, as: :user}
+    end
+  end
+
+  def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
+    with %User{} = followed <- Repo.get(User, id),
+       {:ok, follower} <- User.follow(follower, followed),
+       {:ok, activity} <- ActivityPub.follow(follower, followed) do
+      render conn, AccountView, "relationship.json", %{user: follower, target: followed}
+    end
+  end
+
+  # TODO: Clean up and unify
+  def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
+    with %User{} = followed <- Repo.get(User, id),
+         { :ok, follower, follow_activity } <- User.unfollow(follower, followed),
+         { :ok, _activity } <- ActivityPub.insert(%{
+           "type" => "Undo",
+           "actor" => follower.ap_id,
+           "object" => follow_activity.data["id"] # get latest Follow for these users
+         }) do
+      render conn, AccountView, "relationship.json", %{user: follower, target: followed}
+    end
+  end
+
+  def relationship_noop(%{assigns: %{user: user}} = conn, %{"id" => id}) do
+    Logger.debug("Unimplemented, returning unmodified relationship")
+    with %User{} = target <- Repo.get(User, id) do
+      render conn, AccountView, "relationship.json", %{user: user, target: target}
+    end
+  end
+
   def empty_array(conn, _) do
     Logger.debug("Unimplemented, returning an empty array")
     json(conn, [])
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 5c46d3ca2..0e055a58a 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -44,6 +44,17 @@ defmodule Pleroma.Web.Router do
 
     get "/accounts/verify_credentials", MastodonAPIController, :verify_credentials
     get "/accounts/relationships", MastodonAPIController, :relationships
+    post "/accounts/:id/follow", MastodonAPIController, :follow
+    post "/accounts/:id/unfollow", MastodonAPIController, :unfollow
+    post "/accounts/:id/block", MastodonAPIController, :relationship_noop
+    post "/accounts/:id/unblock", MastodonAPIController, :relationship_noop
+    post "/accounts/:id/mute", MastodonAPIController, :relationship_noop
+    post "/accounts/:id/unmute", MastodonAPIController, :relationship_noop
+
+    get "/blocks", MastodonAPIController, :empty_array
+    get "/domain_blocks", MastodonAPIController, :empty_array
+    get "/follow_requests", MastodonAPIController, :empty_array
+    get "/mutes", MastodonAPIController, :empty_array
 
     get "/timelines/home", MastodonAPIController, :home_timeline
 
@@ -73,6 +84,8 @@ defmodule Pleroma.Web.Router do
     get "/statuses/:id/reblogged_by", MastodonAPIController, :reblogged_by
 
     get "/accounts/:id/statuses", MastodonAPIController, :user_statuses
+    get "/accounts/:id/followers", MastodonAPIController, :followers
+    get "/accounts/:id/following", MastodonAPIController, :following
     get "/accounts/:id", MastodonAPIController, :user
   end
 
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index 25b4f2b37..1b887cc24 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -240,4 +240,74 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
     assert id == activity.id
   end
+
+  test "getting followers", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+    {:ok, user} = User.follow(user, other_user)
+
+    conn = conn
+    |> get("/api/v1/accounts/#{other_user.id}/followers")
+
+    assert [%{"id" => id}] = json_response(conn, 200)
+    assert id = user.id
+  end
+
+  test "getting following", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+    {:ok, user} = User.follow(user, other_user)
+
+    conn = conn
+    |> get("/api/v1/accounts/#{user.id}/following")
+
+    assert [%{"id" => id}] = json_response(conn, 200)
+    assert id = other_user.id
+  end
+
+  test "following / unfollowing a user", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    conn = conn
+    |> assign(:user, user)
+    |> post("/api/v1/accounts/#{other_user.id}/follow")
+
+    assert %{"id" => id, "following" => true} = json_response(conn, 200)
+
+    user = Repo.get(User, user.id)
+    conn = build_conn()
+    |> assign(:user, user)
+    |> post("/api/v1/accounts/#{other_user.id}/unfollow")
+
+    assert %{"id" => id, "following" => false} = json_response(conn, 200)
+  end
+
+  test "unimplemented block/mute endpoints" do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    ["block", "unblock", "mute", "unmute"]
+    |> Enum.each(fn(endpoint) ->
+      conn = build_conn()
+      |> assign(:user, user)
+      |> post("/api/v1/accounts/#{other_user.id}/#{endpoint}")
+
+      assert %{"id" => id} = json_response(conn, 200)
+      assert id == other_user.id
+    end)
+  end
+
+  test "unimplemented mutes, follow_requests, blocks, domain blocks" do
+    user = insert(:user)
+
+    ["blocks", "domain_blocks", "mutes", "follow_requests"]
+    |> Enum.each(fn(endpoint) ->
+      conn = build_conn()
+      |> assign(:user, user)
+      |> get("/api/v1/#{endpoint}")
+
+      assert [] = json_response(conn, 200)
+    end)
+  end
 end