MastoAPI: Follower-related changes
authorRoger Braun <rbraun@Bobble.local>
Thu, 14 Sep 2017 16:30:05 +0000 (18:30 +0200)
committerRoger Braun <rbraun@Bobble.local>
Thu, 14 Sep 2017 16:30:05 +0000 (18:30 +0200)
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
lib/pleroma/web/router.ex
test/web/mastodon_api/mastodon_api_controller_test.exs

index 4a5bbb7b6d282a8d76b527b122912cdf7dfc815b..c713c561bca81bab208d62feacfd555d27403714 100644 (file)
@@ -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, [])
index 5c46d3ca20a2c71322e57f3e71b589e9fd745fc5..0e055a58ae439207d4671bbbecdb0a5e4f6f4490 100644 (file)
@@ -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
 
index 25b4f2b37796972bd3a511b30897ad5a77176d7c..1b887cc24e518de6ed197f8f34e993a8665b41a0 100644 (file)
@@ -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