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