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