258 lines
7.9 KiB
Elixir
258 lines
7.9 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
|
|
use Pleroma.Web.ConnCase, async: true
|
|
|
|
alias Pleroma.Conversation.Participation
|
|
alias Pleroma.User
|
|
alias Pleroma.Web.CommonAPI
|
|
|
|
import Pleroma.Factory
|
|
|
|
setup do: oauth_access(["read:statuses"])
|
|
|
|
describe "returns a list of conversations" do
|
|
setup(%{user: user_one, conn: conn}) do
|
|
user_two = insert(:user)
|
|
user_three = insert(:user)
|
|
|
|
{:ok, user_two, user_one} = User.follow(user_two, user_one)
|
|
|
|
{:ok, %{user: user_one, user_two: user_two, user_three: user_three, conn: conn}}
|
|
end
|
|
|
|
test "returns correct conversations", %{
|
|
user: user_one,
|
|
user_two: user_two,
|
|
user_three: user_three,
|
|
conn: conn
|
|
} do
|
|
assert Participation.unread_count(user_two) == 0
|
|
{:ok, direct} = create_direct_message(user_one, [user_two, user_three])
|
|
|
|
assert Participation.unread_count(user_two) == 1
|
|
|
|
{:ok, _follower_only} =
|
|
CommonAPI.post(user_one, %{
|
|
status: "Hi @#{user_two.nickname}!",
|
|
visibility: "private"
|
|
})
|
|
|
|
res_conn = get(conn, "/api/v1/conversations")
|
|
|
|
assert response = json_response_and_validate_schema(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_one.id not in account_ids
|
|
assert user_two.id in account_ids
|
|
assert user_three.id in account_ids
|
|
assert is_binary(res_id)
|
|
assert unread == false
|
|
assert res_last_status["id"] == direct.id
|
|
assert res_last_status["account"]["id"] == user_one.id
|
|
assert Participation.unread_count(user_one) == 0
|
|
end
|
|
|
|
test "includes the user if the user is the only participant", %{
|
|
user: user_one,
|
|
conn: conn
|
|
} do
|
|
{:ok, _direct} = create_direct_message(user_one, [])
|
|
|
|
res_conn = get(conn, "/api/v1/conversations")
|
|
|
|
assert response = json_response_and_validate_schema(res_conn, 200)
|
|
|
|
assert [
|
|
%{
|
|
"accounts" => [account]
|
|
}
|
|
] = response
|
|
|
|
assert user_one.id == account["id"]
|
|
end
|
|
|
|
test "observes limit params", %{
|
|
user: user_one,
|
|
user_two: user_two,
|
|
user_three: user_three,
|
|
conn: conn
|
|
} do
|
|
{:ok, _} = create_direct_message(user_one, [user_two, user_three])
|
|
{:ok, _} = create_direct_message(user_two, [user_one, user_three])
|
|
{:ok, _} = create_direct_message(user_three, [user_two, user_one])
|
|
|
|
res_conn = get(conn, "/api/v1/conversations?limit=1")
|
|
|
|
assert response = json_response_and_validate_schema(res_conn, 200)
|
|
|
|
assert Enum.count(response) == 1
|
|
|
|
res_conn = get(conn, "/api/v1/conversations?limit=2")
|
|
|
|
assert response = json_response_and_validate_schema(res_conn, 200)
|
|
|
|
assert Enum.count(response) == 2
|
|
end
|
|
end
|
|
|
|
test "filters conversations by recipients", %{user: user_one, conn: conn} do
|
|
user_two = insert(:user)
|
|
user_three = insert(:user)
|
|
{:ok, direct1} = create_direct_message(user_one, [user_two])
|
|
{:ok, _direct2} = create_direct_message(user_one, [user_three])
|
|
{:ok, direct3} = create_direct_message(user_one, [user_two, user_three])
|
|
{:ok, _direct4} = create_direct_message(user_two, [user_three])
|
|
{:ok, direct5} = create_direct_message(user_two, [user_one])
|
|
|
|
assert [conversation1, conversation2] =
|
|
conn
|
|
|> get("/api/v1/conversations?recipients[]=#{user_two.id}")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert conversation1["last_status"]["id"] == direct5.id
|
|
assert conversation2["last_status"]["id"] == direct1.id
|
|
|
|
[conversation1] =
|
|
conn
|
|
|> get("/api/v1/conversations?recipients[]=#{user_two.id}&recipients[]=#{user_three.id}")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert conversation1["last_status"]["id"] == direct3.id
|
|
end
|
|
|
|
test "updates the last_status on reply", %{user: user_one, conn: conn} do
|
|
user_two = insert(:user)
|
|
{:ok, direct} = create_direct_message(user_one, [user_two])
|
|
|
|
{:ok, direct_reply} =
|
|
CommonAPI.post(user_two, %{
|
|
status: "reply",
|
|
visibility: "direct",
|
|
in_reply_to_status_id: direct.id
|
|
})
|
|
|
|
[%{"last_status" => res_last_status}] =
|
|
conn
|
|
|> get("/api/v1/conversations")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert res_last_status["id"] == direct_reply.id
|
|
end
|
|
|
|
test "the user marks a conversation as read", %{user: user_one, conn: conn} do
|
|
user_two = insert(:user)
|
|
{:ok, direct} = create_direct_message(user_one, [user_two])
|
|
|
|
assert Participation.unread_count(user_one) == 0
|
|
assert Participation.unread_count(user_two) == 1
|
|
|
|
user_two_conn =
|
|
build_conn()
|
|
|> assign(:user, user_two)
|
|
|> assign(
|
|
:token,
|
|
insert(:oauth_token, user: user_two, scopes: ["read:statuses", "write:conversations"])
|
|
)
|
|
|
|
[%{"id" => direct_conversation_id, "unread" => true}] =
|
|
user_two_conn
|
|
|> get("/api/v1/conversations")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
%{"unread" => false} =
|
|
user_two_conn
|
|
|> post("/api/v1/conversations/#{direct_conversation_id}/read")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert Participation.unread_count(user_one) == 0
|
|
assert Participation.unread_count(user_two) == 0
|
|
|
|
# The conversation is marked as unread on reply
|
|
{:ok, _} =
|
|
CommonAPI.post(user_two, %{
|
|
status: "reply",
|
|
visibility: "direct",
|
|
in_reply_to_status_id: direct.id
|
|
})
|
|
|
|
[%{"unread" => true}] =
|
|
conn
|
|
|> get("/api/v1/conversations")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert Participation.unread_count(user_one) == 1
|
|
assert Participation.unread_count(user_two) == 0
|
|
|
|
# A reply doesn't increment the user's unread_conversation_count if the conversation is unread
|
|
{:ok, _} =
|
|
CommonAPI.post(user_two, %{
|
|
status: "reply",
|
|
visibility: "direct",
|
|
in_reply_to_status_id: direct.id
|
|
})
|
|
|
|
assert Participation.unread_count(user_one) == 1
|
|
assert Participation.unread_count(user_two) == 0
|
|
end
|
|
|
|
test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
|
|
user_two = insert(:user)
|
|
{:ok, direct} = create_direct_message(user_one, [user_two])
|
|
|
|
res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
|
|
|
|
assert %{"ancestors" => [], "descendants" => []} ==
|
|
json_response_and_validate_schema(res_conn, 200)
|
|
end
|
|
|
|
test "Removes a conversation", %{user: user_one, conn: conn} do
|
|
user_two = insert(:user)
|
|
token = insert(:oauth_token, user: user_one, scopes: ["read:statuses", "write:conversations"])
|
|
|
|
{:ok, _direct} = create_direct_message(user_one, [user_two])
|
|
{:ok, _direct} = create_direct_message(user_one, [user_two])
|
|
|
|
assert [%{"id" => conv1_id}, %{"id" => conv2_id}] =
|
|
conn
|
|
|> assign(:token, token)
|
|
|> get("/api/v1/conversations")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert %{} =
|
|
conn
|
|
|> assign(:token, token)
|
|
|> delete("/api/v1/conversations/#{conv1_id}")
|
|
|> json_response_and_validate_schema(200)
|
|
|
|
assert [%{"id" => ^conv2_id}] =
|
|
conn
|
|
|> assign(:token, token)
|
|
|> get("/api/v1/conversations")
|
|
|> json_response_and_validate_schema(200)
|
|
end
|
|
|
|
defp create_direct_message(sender, recips) do
|
|
hellos =
|
|
recips
|
|
|> Enum.map(fn s -> "@#{s.nickname}" end)
|
|
|> Enum.join(", ")
|
|
|
|
CommonAPI.post(sender, %{
|
|
status: "Hi #{hellos}!",
|
|
visibility: "direct"
|
|
})
|
|
end
|
|
end
|