Extract conversation actions from `MastodonAPIController` to ConversationController See merge request pleroma/pleroma!1743object-id-column
@@ -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 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController 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 @@ defmodule Pleroma.Web.MastodonAPI.ConversationView 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) | |||