Quote posting (#113)
[akkoma] / test / pleroma / web / mastodon_api / controllers / filter_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
6 use Pleroma.Web.ConnCase, async: true
7 use Oban.Testing, repo: Pleroma.Repo
8
9 import Pleroma.Factory
10
11 alias Pleroma.Filter
12 alias Pleroma.Repo
13 alias Pleroma.Workers.PurgeExpiredFilter
14
15 test "non authenticated creation request", %{conn: conn} do
16 response =
17 conn
18 |> put_req_header("content-type", "application/json")
19 |> post("/api/v1/filters", %{"phrase" => "knights", context: ["home"]})
20 |> json_response(403)
21
22 assert response["error"] == "Invalid credentials."
23 end
24
25 describe "creating" do
26 setup do: oauth_access(["write:filters"])
27
28 test "a common filter", %{conn: conn, user: user} do
29 params = %{
30 phrase: "knights",
31 context: ["home"],
32 irreversible: true
33 }
34
35 response =
36 conn
37 |> put_req_header("content-type", "application/json")
38 |> post("/api/v1/filters", params)
39 |> json_response_and_validate_schema(200)
40
41 assert response["phrase"] == params.phrase
42 assert response["context"] == params.context
43 assert response["irreversible"] == true
44 assert response["id"] != nil
45 assert response["id"] != ""
46 assert response["expires_at"] == nil
47
48 filter = Filter.get(response["id"], user)
49 assert filter.hide == true
50 end
51
52 test "a filter with expires_in", %{conn: conn, user: user} do
53 in_seconds = 600
54
55 response =
56 conn
57 |> put_req_header("content-type", "application/json")
58 |> post("/api/v1/filters", %{
59 "phrase" => "knights",
60 context: ["home"],
61 expires_in: in_seconds
62 })
63 |> json_response_and_validate_schema(200)
64
65 assert response["irreversible"] == false
66
67 expires_at =
68 NaiveDateTime.utc_now()
69 |> NaiveDateTime.add(in_seconds)
70 |> Pleroma.Web.CommonAPI.Utils.to_masto_date()
71
72 assert response["expires_at"] == expires_at
73
74 filter = Filter.get(response["id"], user)
75
76 id = filter.id
77
78 assert_enqueued(
79 worker: PurgeExpiredFilter,
80 args: %{filter_id: filter.id}
81 )
82
83 assert {:ok, %{id: ^id}} =
84 perform_job(PurgeExpiredFilter, %{
85 filter_id: filter.id
86 })
87
88 assert Repo.aggregate(Filter, :count, :id) == 0
89 end
90 end
91
92 test "fetching a list of filters" do
93 %{user: user, conn: conn} = oauth_access(["read:filters"])
94
95 %{filter_id: id1} = insert(:filter, user: user)
96 %{filter_id: id2} = insert(:filter, user: user)
97
98 id1 = to_string(id1)
99 id2 = to_string(id2)
100
101 assert [%{"id" => ^id2}, %{"id" => ^id1}] =
102 conn
103 |> get("/api/v1/filters")
104 |> json_response_and_validate_schema(200)
105 end
106
107 test "fetching a list of filters without token", %{conn: conn} do
108 insert(:filter)
109
110 response =
111 conn
112 |> get("/api/v1/filters")
113 |> json_response(403)
114
115 assert response["error"] == "Invalid credentials."
116 end
117
118 test "get a filter" do
119 %{user: user, conn: conn} = oauth_access(["read:filters"])
120
121 # check whole_word false
122 filter = insert(:filter, user: user, whole_word: false)
123
124 resp1 =
125 conn |> get("/api/v1/filters/#{filter.filter_id}") |> json_response_and_validate_schema(200)
126
127 assert resp1["whole_word"] == false
128
129 # check whole_word true
130 filter = insert(:filter, user: user, whole_word: true)
131
132 resp2 =
133 conn |> get("/api/v1/filters/#{filter.filter_id}") |> json_response_and_validate_schema(200)
134
135 assert resp2["whole_word"] == true
136 end
137
138 test "get a filter not_found error" do
139 filter = insert(:filter)
140 %{conn: conn} = oauth_access(["read:filters"])
141
142 response =
143 conn |> get("/api/v1/filters/#{filter.filter_id}") |> json_response_and_validate_schema(404)
144
145 assert response["error"] == "Record not found"
146 end
147
148 describe "updating a filter" do
149 setup do: oauth_access(["write:filters"])
150
151 test "common" do
152 %{conn: conn, user: user} = oauth_access(["write:filters"])
153
154 filter =
155 insert(:filter,
156 user: user,
157 hide: true,
158 whole_word: true
159 )
160
161 params = %{
162 phrase: "nii",
163 context: ["public"],
164 irreversible: false
165 }
166
167 response =
168 conn
169 |> put_req_header("content-type", "application/json")
170 |> put("/api/v1/filters/#{filter.filter_id}", params)
171 |> json_response_and_validate_schema(200)
172
173 assert response["phrase"] == params.phrase
174 assert response["context"] == params.context
175 assert response["irreversible"] == false
176 assert response["whole_word"] == true
177 end
178
179 test "with adding expires_at", %{conn: conn, user: user} do
180 filter = insert(:filter, user: user)
181 in_seconds = 600
182
183 response =
184 conn
185 |> put_req_header("content-type", "application/json")
186 |> put("/api/v1/filters/#{filter.filter_id}", %{
187 phrase: "nii",
188 context: ["public"],
189 expires_in: in_seconds,
190 irreversible: true
191 })
192 |> json_response_and_validate_schema(200)
193
194 assert response["irreversible"] == true
195
196 expected_time =
197 NaiveDateTime.utc_now()
198 |> NaiveDateTime.add(in_seconds)
199
200 assert NaiveDateTime.diff(
201 NaiveDateTime.from_iso8601!(response["expires_at"]),
202 expected_time
203 ) < 5
204
205 filter = Filter.get(response["id"], user)
206
207 id = filter.id
208
209 assert_enqueued(
210 worker: PurgeExpiredFilter,
211 args: %{filter_id: id}
212 )
213
214 assert {:ok, %{id: ^id}} =
215 perform_job(PurgeExpiredFilter, %{
216 filter_id: id
217 })
218
219 assert Repo.aggregate(Filter, :count, :id) == 0
220 end
221
222 test "with removing expires_at", %{conn: conn, user: user} do
223 response =
224 conn
225 |> put_req_header("content-type", "application/json")
226 |> post("/api/v1/filters", %{
227 phrase: "cofe",
228 context: ["home"],
229 expires_in: 600
230 })
231 |> json_response_and_validate_schema(200)
232
233 filter = Filter.get(response["id"], user)
234
235 assert_enqueued(
236 worker: PurgeExpiredFilter,
237 args: %{filter_id: filter.id}
238 )
239
240 response =
241 conn
242 |> put_req_header("content-type", "application/json")
243 |> put("/api/v1/filters/#{filter.filter_id}", %{
244 phrase: "nii",
245 context: ["public"],
246 expires_in: nil,
247 whole_word: true
248 })
249 |> json_response_and_validate_schema(200)
250
251 refute_enqueued(
252 worker: PurgeExpiredFilter,
253 args: %{filter_id: filter.id}
254 )
255
256 assert response["irreversible"] == false
257 assert response["whole_word"] == true
258 assert response["expires_at"] == nil
259 end
260
261 test "expires_at is the same in create and update so job is in db", %{conn: conn, user: user} do
262 resp1 =
263 conn
264 |> put_req_header("content-type", "application/json")
265 |> post("/api/v1/filters", %{
266 phrase: "cofe",
267 context: ["home"],
268 expires_in: 600
269 })
270 |> json_response_and_validate_schema(200)
271
272 filter = Filter.get(resp1["id"], user)
273
274 assert_enqueued(
275 worker: PurgeExpiredFilter,
276 args: %{filter_id: filter.id}
277 )
278
279 job = PurgeExpiredFilter.get_expiration(filter.id)
280
281 resp2 =
282 conn
283 |> put_req_header("content-type", "application/json")
284 |> put("/api/v1/filters/#{filter.filter_id}", %{
285 phrase: "nii",
286 context: ["public"]
287 })
288 |> json_response_and_validate_schema(200)
289
290 updated_filter = Filter.get(resp2["id"], user)
291
292 assert_enqueued(
293 worker: PurgeExpiredFilter,
294 args: %{filter_id: updated_filter.id}
295 )
296
297 after_update = PurgeExpiredFilter.get_expiration(updated_filter.id)
298
299 assert resp1["expires_at"] == resp2["expires_at"]
300
301 assert job.scheduled_at == after_update.scheduled_at
302 end
303
304 test "updating expires_at updates oban job too", %{conn: conn, user: user} do
305 resp1 =
306 conn
307 |> put_req_header("content-type", "application/json")
308 |> post("/api/v1/filters", %{
309 phrase: "cofe",
310 context: ["home"],
311 expires_in: 600
312 })
313 |> json_response_and_validate_schema(200)
314
315 filter = Filter.get(resp1["id"], user)
316
317 assert_enqueued(
318 worker: PurgeExpiredFilter,
319 args: %{filter_id: filter.id}
320 )
321
322 job = PurgeExpiredFilter.get_expiration(filter.id)
323
324 resp2 =
325 conn
326 |> put_req_header("content-type", "application/json")
327 |> put("/api/v1/filters/#{filter.filter_id}", %{
328 phrase: "nii",
329 context: ["public"],
330 expires_in: 300
331 })
332 |> json_response_and_validate_schema(200)
333
334 updated_filter = Filter.get(resp2["id"], user)
335
336 assert_enqueued(
337 worker: PurgeExpiredFilter,
338 args: %{filter_id: updated_filter.id}
339 )
340
341 after_update = PurgeExpiredFilter.get_expiration(updated_filter.id)
342
343 refute resp1["expires_at"] == resp2["expires_at"]
344
345 refute job.scheduled_at == after_update.scheduled_at
346 end
347 end
348
349 test "update filter without token", %{conn: conn} do
350 filter = insert(:filter)
351
352 response =
353 conn
354 |> put_req_header("content-type", "application/json")
355 |> put("/api/v1/filters/#{filter.filter_id}", %{
356 phrase: "nii",
357 context: ["public"]
358 })
359 |> json_response(403)
360
361 assert response["error"] == "Invalid credentials."
362 end
363
364 describe "delete a filter" do
365 setup do: oauth_access(["write:filters"])
366
367 test "common", %{conn: conn, user: user} do
368 filter = insert(:filter, user: user)
369
370 assert conn
371 |> delete("/api/v1/filters/#{filter.filter_id}")
372 |> json_response_and_validate_schema(200) == %{}
373
374 assert Repo.all(Filter) == []
375 end
376
377 test "with expires_at", %{conn: conn, user: user} do
378 response =
379 conn
380 |> put_req_header("content-type", "application/json")
381 |> post("/api/v1/filters", %{
382 phrase: "cofe",
383 context: ["home"],
384 expires_in: 600
385 })
386 |> json_response_and_validate_schema(200)
387
388 filter = Filter.get(response["id"], user)
389
390 assert_enqueued(
391 worker: PurgeExpiredFilter,
392 args: %{filter_id: filter.id}
393 )
394
395 assert conn
396 |> delete("/api/v1/filters/#{filter.filter_id}")
397 |> json_response_and_validate_schema(200) == %{}
398
399 refute_enqueued(
400 worker: PurgeExpiredFilter,
401 args: %{filter_id: filter.id}
402 )
403
404 assert Repo.all(Filter) == []
405 assert Repo.all(Oban.Job) == []
406 end
407 end
408
409 test "delete a filter without token", %{conn: conn} do
410 filter = insert(:filter)
411
412 response =
413 conn
414 |> delete("/api/v1/filters/#{filter.filter_id}")
415 |> json_response(403)
416
417 assert response["error"] == "Invalid credentials."
418 end
419 end