Merge branch 'split-masto-api/conversations' into 'develop'
Extract conversation actions from `MastodonAPIController` to ConversationController See merge request pleroma/pleroma!1743
This commit is contained in:
		
						commit
						74d8fadf37
					
				
					 6 changed files with 116 additions and 106 deletions
				
			
		| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.MastodonAPI.ConversationController do
 | 
			
		||||
  use Pleroma.Web, :controller
 | 
			
		||||
 | 
			
		||||
  import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.Conversation.Participation
 | 
			
		||||
  alias Pleroma.Repo
 | 
			
		||||
 | 
			
		||||
  action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
 | 
			
		||||
 | 
			
		||||
  @doc "GET /api/v1/conversations"
 | 
			
		||||
  def index(%{assigns: %{user: user}} = conn, params) do
 | 
			
		||||
    participations = Participation.for_user_with_last_activity_id(user, params)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(participations)
 | 
			
		||||
    |> render("participations.json", participations: participations, for: user)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @doc "POST /api/v1/conversations/:id/read"
 | 
			
		||||
  def read(%{assigns: %{user: user}} = conn, %{"id" => participation_id}) do
 | 
			
		||||
    with %Participation{} = participation <-
 | 
			
		||||
           Repo.get_by(Participation, id: participation_id, user_id: user.id),
 | 
			
		||||
         {:ok, participation} <- Participation.mark_as_read(participation) do
 | 
			
		||||
      render(conn, "participation.json", participation: participation, for: user)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +12,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 | 
			
		|||
  alias Pleroma.Activity
 | 
			
		||||
  alias Pleroma.Bookmark
 | 
			
		||||
  alias Pleroma.Config
 | 
			
		||||
  alias Pleroma.Conversation.Participation
 | 
			
		||||
  alias Pleroma.Emoji
 | 
			
		||||
  alias Pleroma.HTTP
 | 
			
		||||
  alias Pleroma.Object
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +26,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 | 
			
		|||
  alias Pleroma.Web.CommonAPI
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.AccountView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.AppView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.ConversationView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.ListView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.MastodonAPI
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.MastodonView
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,31 +1001,6 @@ def account_register(conn, _) do
 | 
			
		|||
    render_error(conn, :forbidden, "Invalid credentials")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def conversations(%{assigns: %{user: user}} = conn, params) do
 | 
			
		||||
    participations = Participation.for_user_with_last_activity_id(user, params)
 | 
			
		||||
 | 
			
		||||
    conversations =
 | 
			
		||||
      Enum.map(participations, fn participation ->
 | 
			
		||||
        ConversationView.render("participation.json", %{participation: participation, for: user})
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(participations)
 | 
			
		||||
    |> json(conversations)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def conversation_read(%{assigns: %{user: user}} = conn, %{"id" => participation_id}) do
 | 
			
		||||
    with %Participation{} = participation <-
 | 
			
		||||
           Repo.get_by(Participation, id: participation_id, user_id: user.id),
 | 
			
		||||
         {:ok, participation} <- Participation.mark_as_read(participation) do
 | 
			
		||||
      participation_view =
 | 
			
		||||
        ConversationView.render("participation.json", %{participation: participation, for: user})
 | 
			
		||||
 | 
			
		||||
      conn
 | 
			
		||||
      |> json(participation_view)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def password_reset(conn, params) do
 | 
			
		||||
    nickname_or_email = params["email"] || params["nickname"]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,10 @@ defmodule Pleroma.Web.MastodonAPI.ConversationView do
 | 
			
		|||
  alias Pleroma.Web.MastodonAPI.AccountView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.StatusView
 | 
			
		||||
 | 
			
		||||
  def render("participations.json", %{participations: participations, for: user}) do
 | 
			
		||||
    render_many(participations, __MODULE__, "participation.json", as: :participation, for: user)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def render("participation.json", %{participation: participation, for: user}) do
 | 
			
		||||
    participation = Repo.preload(participation, conversation: [], recipients: [])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,25 +27,14 @@ def render("participation.json", %{participation: participation, for: user}) do
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
    activity = Activity.get_by_id_with_object(last_activity_id)
 | 
			
		||||
 | 
			
		||||
    last_status = StatusView.render("show.json", %{activity: activity, for: user})
 | 
			
		||||
 | 
			
		||||
    # Conversations return all users except the current user.
 | 
			
		||||
    users =
 | 
			
		||||
      participation.recipients
 | 
			
		||||
      |> Enum.reject(&(&1.id == user.id))
 | 
			
		||||
 | 
			
		||||
    accounts =
 | 
			
		||||
      AccountView.render("accounts.json", %{
 | 
			
		||||
        users: users,
 | 
			
		||||
        as: :user
 | 
			
		||||
      })
 | 
			
		||||
    users = Enum.reject(participation.recipients, &(&1.id == user.id))
 | 
			
		||||
 | 
			
		||||
    %{
 | 
			
		||||
      id: participation.id |> to_string(),
 | 
			
		||||
      accounts: accounts,
 | 
			
		||||
      accounts: render(AccountView, "accounts.json", users: users, as: :user),
 | 
			
		||||
      unread: !participation.read,
 | 
			
		||||
      last_status: last_status
 | 
			
		||||
      last_status: render(StatusView, "show.json", activity: activity, for: user)
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -355,8 +355,8 @@ defmodule Pleroma.Web.Router do
 | 
			
		|||
 | 
			
		||||
      get("/suggestions", MastodonAPIController, :suggestions)
 | 
			
		||||
 | 
			
		||||
      get("/conversations", MastodonAPIController, :conversations)
 | 
			
		||||
      post("/conversations/:id/read", MastodonAPIController, :conversation_read)
 | 
			
		||||
      get("/conversations", ConversationController, :index)
 | 
			
		||||
      post("/conversations/:id/read", ConversationController, :read)
 | 
			
		||||
 | 
			
		||||
      get("/endorsements", MastodonAPIController, :empty_array)
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
 | 
			
		||||
  use Pleroma.Web.ConnCase
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Web.CommonAPI
 | 
			
		||||
 | 
			
		||||
  import Pleroma.Factory
 | 
			
		||||
 | 
			
		||||
  test "Conversations", %{conn: conn} do
 | 
			
		||||
    user_one = insert(:user)
 | 
			
		||||
    user_two = insert(:user)
 | 
			
		||||
    user_three = insert(:user)
 | 
			
		||||
 | 
			
		||||
    {:ok, user_two} = User.follow(user_two, user_one)
 | 
			
		||||
 | 
			
		||||
    {:ok, direct} =
 | 
			
		||||
      CommonAPI.post(user_one, %{
 | 
			
		||||
        "status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
 | 
			
		||||
        "visibility" => "direct"
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
    {:ok, _follower_only} =
 | 
			
		||||
      CommonAPI.post(user_one, %{
 | 
			
		||||
        "status" => "Hi @#{user_two.nickname}!",
 | 
			
		||||
        "visibility" => "private"
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
    res_conn =
 | 
			
		||||
      conn
 | 
			
		||||
      |> assign(:user, user_one)
 | 
			
		||||
      |> get("/api/v1/conversations")
 | 
			
		||||
 | 
			
		||||
    assert response = json_response(res_conn, 200)
 | 
			
		||||
 | 
			
		||||
    assert [
 | 
			
		||||
             %{
 | 
			
		||||
               "id" => res_id,
 | 
			
		||||
               "accounts" => res_accounts,
 | 
			
		||||
               "last_status" => res_last_status,
 | 
			
		||||
               "unread" => unread
 | 
			
		||||
             }
 | 
			
		||||
           ] = response
 | 
			
		||||
 | 
			
		||||
    account_ids = Enum.map(res_accounts, & &1["id"])
 | 
			
		||||
    assert length(res_accounts) == 2
 | 
			
		||||
    assert user_two.id in account_ids
 | 
			
		||||
    assert user_three.id in account_ids
 | 
			
		||||
    assert is_binary(res_id)
 | 
			
		||||
    assert unread == true
 | 
			
		||||
    assert res_last_status["id"] == direct.id
 | 
			
		||||
 | 
			
		||||
    # Apparently undocumented API endpoint
 | 
			
		||||
    res_conn =
 | 
			
		||||
      conn
 | 
			
		||||
      |> assign(:user, user_one)
 | 
			
		||||
      |> post("/api/v1/conversations/#{res_id}/read")
 | 
			
		||||
 | 
			
		||||
    assert response = json_response(res_conn, 200)
 | 
			
		||||
    assert length(response["accounts"]) == 2
 | 
			
		||||
    assert response["last_status"]["id"] == direct.id
 | 
			
		||||
    assert response["unread"] == false
 | 
			
		||||
 | 
			
		||||
    # (vanilla) Mastodon frontend behaviour
 | 
			
		||||
    res_conn =
 | 
			
		||||
      conn
 | 
			
		||||
      |> assign(:user, user_one)
 | 
			
		||||
      |> get("/api/v1/statuses/#{res_last_status["id"]}/context")
 | 
			
		||||
 | 
			
		||||
    assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -33,69 +33,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 | 
			
		|||
  clear_config([:instance, :public])
 | 
			
		||||
  clear_config([:rich_media, :enabled])
 | 
			
		||||
 | 
			
		||||
  test "Conversations", %{conn: conn} do
 | 
			
		||||
    user_one = insert(:user)
 | 
			
		||||
    user_two = insert(:user)
 | 
			
		||||
    user_three = insert(:user)
 | 
			
		||||
 | 
			
		||||
    {:ok, user_two} = User.follow(user_two, user_one)
 | 
			
		||||
 | 
			
		||||
    {:ok, direct} =
 | 
			
		||||
      CommonAPI.post(user_one, %{
 | 
			
		||||
        "status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
 | 
			
		||||
        "visibility" => "direct"
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
    {:ok, _follower_only} =
 | 
			
		||||
      CommonAPI.post(user_one, %{
 | 
			
		||||
        "status" => "Hi @#{user_two.nickname}!",
 | 
			
		||||
        "visibility" => "private"
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
    res_conn =
 | 
			
		||||
      conn
 | 
			
		||||
      |> assign(:user, user_one)
 | 
			
		||||
      |> get("/api/v1/conversations")
 | 
			
		||||
 | 
			
		||||
    assert response = json_response(res_conn, 200)
 | 
			
		||||
 | 
			
		||||
    assert [
 | 
			
		||||
             %{
 | 
			
		||||
               "id" => res_id,
 | 
			
		||||
               "accounts" => res_accounts,
 | 
			
		||||
               "last_status" => res_last_status,
 | 
			
		||||
               "unread" => unread
 | 
			
		||||
             }
 | 
			
		||||
           ] = response
 | 
			
		||||
 | 
			
		||||
    account_ids = Enum.map(res_accounts, & &1["id"])
 | 
			
		||||
    assert length(res_accounts) == 2
 | 
			
		||||
    assert user_two.id in account_ids
 | 
			
		||||
    assert user_three.id in account_ids
 | 
			
		||||
    assert is_binary(res_id)
 | 
			
		||||
    assert unread == true
 | 
			
		||||
    assert res_last_status["id"] == direct.id
 | 
			
		||||
 | 
			
		||||
    # Apparently undocumented API endpoint
 | 
			
		||||
    res_conn =
 | 
			
		||||
      conn
 | 
			
		||||
      |> assign(:user, user_one)
 | 
			
		||||
      |> post("/api/v1/conversations/#{res_id}/read")
 | 
			
		||||
 | 
			
		||||
    assert response = json_response(res_conn, 200)
 | 
			
		||||
    assert length(response["accounts"]) == 2
 | 
			
		||||
    assert response["last_status"]["id"] == direct.id
 | 
			
		||||
    assert response["unread"] == false
 | 
			
		||||
 | 
			
		||||
    # (vanilla) Mastodon frontend behaviour
 | 
			
		||||
    res_conn =
 | 
			
		||||
      conn
 | 
			
		||||
      |> assign(:user, user_one)
 | 
			
		||||
      |> get("/api/v1/statuses/#{res_last_status["id"]}/context")
 | 
			
		||||
 | 
			
		||||
    assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "verify_credentials", %{conn: conn} do
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue