1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
6 use Pleroma.Web.ConnCase
8 alias Pleroma.Conversation.Participation
10 alias Pleroma.Web.CommonAPI
12 import Pleroma.Factory
14 setup do: oauth_access(["read:statuses"])
16 describe "returns a list of conversations" do
17 setup(%{user: user_one, conn: conn}) do
18 user_two = insert(:user)
19 user_three = insert(:user)
21 {:ok, user_two} = User.follow(user_two, user_one)
23 {:ok, %{user: user_one, user_two: user_two, user_three: user_three, conn: conn}}
26 test "returns correct conversations", %{
29 user_three: user_three,
32 assert Participation.unread_count(user_two) == 0
33 {:ok, direct} = create_direct_message(user_one, [user_two, user_three])
35 assert Participation.unread_count(user_two) == 1
37 {:ok, _follower_only} =
38 CommonAPI.post(user_one, %{
39 status: "Hi @#{user_two.nickname}!",
43 res_conn = get(conn, "/api/v1/conversations")
45 assert response = json_response_and_validate_schema(res_conn, 200)
50 "accounts" => res_accounts,
51 "last_status" => res_last_status,
56 account_ids = Enum.map(res_accounts, & &1["id"])
57 assert length(res_accounts) == 2
58 assert user_one.id not in account_ids
59 assert user_two.id in account_ids
60 assert user_three.id in account_ids
61 assert is_binary(res_id)
62 assert unread == false
63 assert res_last_status["id"] == direct.id
64 assert res_last_status["account"]["id"] == user_one.id
65 assert Participation.unread_count(user_one) == 0
68 test "special behaviour when conversation have only one user", %{
73 {:ok, direct} = create_direct_message(user_one, [])
75 res_conn = get(conn, "/api/v1/conversations")
77 assert response = json_response_and_validate_schema(res_conn, 200)
80 "accounts" => res_accounts,
81 "last_status" => res_last_status
84 assert length(res_accounts) == 1
85 assert res_accounts[0]["id"] == user_one.id
88 test "observes limit params", %{
91 user_three: user_three,
94 {:ok, _} = create_direct_message(user_one, [user_two, user_three])
95 {:ok, _} = create_direct_message(user_two, [user_one, user_three])
96 {:ok, _} = create_direct_message(user_three, [user_two, user_one])
98 res_conn = get(conn, "/api/v1/conversations?limit=1")
100 assert response = json_response_and_validate_schema(res_conn, 200)
102 assert Enum.count(response) == 1
104 res_conn = get(conn, "/api/v1/conversations?limit=2")
106 assert response = json_response_and_validate_schema(res_conn, 200)
108 assert Enum.count(response) == 2
112 test "filters conversations by recipients", %{user: user_one, conn: conn} do
113 user_two = insert(:user)
114 user_three = insert(:user)
115 {:ok, direct1} = create_direct_message(user_one, [user_two])
116 {:ok, _direct2} = create_direct_message(user_one, [user_three])
117 {:ok, direct3} = create_direct_message(user_one, [user_two, user_three])
118 {:ok, _direct4} = create_direct_message(user_two, [user_three])
119 {:ok, direct5} = create_direct_message(user_two, [user_one])
121 assert [conversation1, conversation2] =
123 |> get("/api/v1/conversations?recipients[]=#{user_two.id}")
124 |> json_response_and_validate_schema(200)
126 assert conversation1["last_status"]["id"] == direct5.id
127 assert conversation2["last_status"]["id"] == direct1.id
131 |> get("/api/v1/conversations?recipients[]=#{user_two.id}&recipients[]=#{user_three.id}")
132 |> json_response_and_validate_schema(200)
134 assert conversation1["last_status"]["id"] == direct3.id
137 test "updates the last_status on reply", %{user: user_one, conn: conn} do
138 user_two = insert(:user)
139 {:ok, direct} = create_direct_message(user_one, [user_two])
141 {:ok, direct_reply} =
142 CommonAPI.post(user_two, %{
144 visibility: "direct",
145 in_reply_to_status_id: direct.id
148 [%{"last_status" => res_last_status}] =
150 |> get("/api/v1/conversations")
151 |> json_response_and_validate_schema(200)
153 assert res_last_status["id"] == direct_reply.id
156 test "the user marks a conversation as read", %{user: user_one, conn: conn} do
157 user_two = insert(:user)
158 {:ok, direct} = create_direct_message(user_one, [user_two])
160 assert Participation.unread_count(user_one) == 0
161 assert Participation.unread_count(user_two) == 1
165 |> assign(:user, user_two)
168 insert(:oauth_token, user: user_two, scopes: ["read:statuses", "write:conversations"])
171 [%{"id" => direct_conversation_id, "unread" => true}] =
173 |> get("/api/v1/conversations")
174 |> json_response_and_validate_schema(200)
176 %{"unread" => false} =
178 |> post("/api/v1/conversations/#{direct_conversation_id}/read")
179 |> json_response_and_validate_schema(200)
181 assert Participation.unread_count(user_one) == 0
182 assert Participation.unread_count(user_two) == 0
184 # The conversation is marked as unread on reply
186 CommonAPI.post(user_two, %{
188 visibility: "direct",
189 in_reply_to_status_id: direct.id
192 [%{"unread" => true}] =
194 |> get("/api/v1/conversations")
195 |> json_response_and_validate_schema(200)
197 assert Participation.unread_count(user_one) == 1
198 assert Participation.unread_count(user_two) == 0
200 # A reply doesn't increment the user's unread_conversation_count if the conversation is unread
202 CommonAPI.post(user_two, %{
204 visibility: "direct",
205 in_reply_to_status_id: direct.id
208 assert Participation.unread_count(user_one) == 1
209 assert Participation.unread_count(user_two) == 0
212 test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
213 user_two = insert(:user)
214 {:ok, direct} = create_direct_message(user_one, [user_two])
216 res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
218 assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
221 defp create_direct_message(sender, recips) do
224 |> Enum.map(fn s -> "@#{s.nickname}" end)
227 CommonAPI.post(sender, %{
228 status: "Hi #{hellos}!",