3e21e6bf178ddab076fbb7f2ebbb40cefbb81be1
[akkoma] / test / web / mastodon_api / controllers / conversation_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
6 use Pleroma.Web.ConnCase
7
8 alias Pleroma.User
9 alias Pleroma.Web.CommonAPI
10
11 import Pleroma.Factory
12
13 setup do: oauth_access(["read:statuses"])
14
15 describe "returns a list of conversations" do
16 setup(%{user: user_one, conn: conn}) do
17 user_two = insert(:user)
18 user_three = insert(:user)
19
20 {:ok, user_two} = User.follow(user_two, user_one)
21
22 {:ok, %{user: user_one, user_two: user_two, user_three: user_three, conn: conn}}
23 end
24
25 test "returns correct conversations", %{
26 user: user_one,
27 user_two: user_two,
28 user_three: user_three,
29 conn: conn
30 } do
31 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
32 {:ok, direct} = create_direct_message(user_one, [user_two, user_three])
33
34 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
35
36 {:ok, _follower_only} =
37 CommonAPI.post(user_one, %{
38 status: "Hi @#{user_two.nickname}!",
39 visibility: "private"
40 })
41
42 res_conn = get(conn, "/api/v1/conversations")
43
44 assert response = json_response_and_validate_schema(res_conn, 200)
45
46 assert [
47 %{
48 "id" => res_id,
49 "accounts" => res_accounts,
50 "last_status" => res_last_status,
51 "unread" => unread
52 }
53 ] = response
54
55 account_ids = Enum.map(res_accounts, & &1["id"])
56 assert length(res_accounts) == 2
57 assert user_two.id in account_ids
58 assert user_three.id in account_ids
59 assert is_binary(res_id)
60 assert unread == false
61 assert res_last_status["id"] == direct.id
62 assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
63 end
64
65 test "observes limit params", %{
66 user: user_one,
67 user_two: user_two,
68 user_three: user_three,
69 conn: conn
70 } do
71 {:ok, _} = create_direct_message(user_one, [user_two, user_three])
72 {:ok, _} = create_direct_message(user_two, [user_one, user_three])
73 {:ok, _} = create_direct_message(user_three, [user_two, user_one])
74
75 res_conn = get(conn, "/api/v1/conversations?limit=1")
76
77 assert response = json_response_and_validate_schema(res_conn, 200)
78
79 assert Enum.count(response) == 1
80
81 res_conn = get(conn, "/api/v1/conversations?limit=2")
82
83 assert response = json_response_and_validate_schema(res_conn, 200)
84
85 assert Enum.count(response) == 2
86 end
87 end
88
89 test "filters conversations by recipients", %{user: user_one, conn: conn} do
90 user_two = insert(:user)
91 user_three = insert(:user)
92 {:ok, direct1} = create_direct_message(user_one, [user_two])
93 {:ok, _direct2} = create_direct_message(user_one, [user_three])
94 {:ok, direct3} = create_direct_message(user_one, [user_two, user_three])
95 {:ok, _direct4} = create_direct_message(user_two, [user_three])
96 {:ok, direct5} = create_direct_message(user_two, [user_one])
97
98 assert [conversation1, conversation2] =
99 conn
100 |> get("/api/v1/conversations?recipients[]=#{user_two.id}")
101 |> json_response_and_validate_schema(200)
102
103 assert conversation1["last_status"]["id"] == direct5.id
104 assert conversation2["last_status"]["id"] == direct1.id
105
106 [conversation1] =
107 conn
108 |> get("/api/v1/conversations?recipients[]=#{user_two.id}&recipients[]=#{user_three.id}")
109 |> json_response_and_validate_schema(200)
110
111 assert conversation1["last_status"]["id"] == direct3.id
112 end
113
114 test "updates the last_status on reply", %{user: user_one, conn: conn} do
115 user_two = insert(:user)
116 {:ok, direct} = create_direct_message(user_one, [user_two])
117
118 {:ok, direct_reply} =
119 CommonAPI.post(user_two, %{
120 status: "reply",
121 visibility: "direct",
122 in_reply_to_status_id: direct.id
123 })
124
125 [%{"last_status" => res_last_status}] =
126 conn
127 |> get("/api/v1/conversations")
128 |> json_response_and_validate_schema(200)
129
130 assert res_last_status["id"] == direct_reply.id
131 end
132
133 test "the user marks a conversation as read", %{user: user_one, conn: conn} do
134 user_two = insert(:user)
135 {:ok, direct} = create_direct_message(user_one, [user_two])
136
137 assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
138 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
139
140 user_two_conn =
141 build_conn()
142 |> assign(:user, user_two)
143 |> assign(
144 :token,
145 insert(:oauth_token, user: user_two, scopes: ["read:statuses", "write:conversations"])
146 )
147
148 [%{"id" => direct_conversation_id, "unread" => true}] =
149 user_two_conn
150 |> get("/api/v1/conversations")
151 |> json_response_and_validate_schema(200)
152
153 %{"unread" => false} =
154 user_two_conn
155 |> post("/api/v1/conversations/#{direct_conversation_id}/read")
156 |> json_response_and_validate_schema(200)
157
158 assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
159 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
160
161 # The conversation is marked as unread on reply
162 {:ok, _} =
163 CommonAPI.post(user_two, %{
164 status: "reply",
165 visibility: "direct",
166 in_reply_to_status_id: direct.id
167 })
168
169 [%{"unread" => true}] =
170 conn
171 |> get("/api/v1/conversations")
172 |> json_response_and_validate_schema(200)
173
174 assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1
175 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
176
177 # A reply doesn't increment the user's unread_conversation_count if the conversation is unread
178 {:ok, _} =
179 CommonAPI.post(user_two, %{
180 status: "reply",
181 visibility: "direct",
182 in_reply_to_status_id: direct.id
183 })
184
185 assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1
186 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
187 end
188
189 test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
190 user_two = insert(:user)
191 {:ok, direct} = create_direct_message(user_one, [user_two])
192
193 res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
194
195 assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
196 end
197
198 defp create_direct_message(sender, recips) do
199 hellos =
200 recips
201 |> Enum.map(fn s -> "@#{s.nickname}" end)
202 |> Enum.join(", ")
203
204 CommonAPI.post(sender, %{
205 status: "Hi #{hellos}!",
206 visibility: "direct"
207 })
208 end
209 end