First
[anni] / test / pleroma / web / admin_api / controllers / announcement_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
6   use Pleroma.Web.ConnCase, async: false
7
8   import Pleroma.Factory
9
10   setup do
11     clear_config([:instance, :admin_privileges], [:announcements_manage_announcements])
12     admin = insert(:user, is_admin: true)
13     token = insert(:oauth_admin_token, user: admin)
14
15     conn =
16       build_conn()
17       |> assign(:user, admin)
18       |> assign(:token, token)
19
20     {:ok, %{admin: admin, token: token, conn: conn}}
21   end
22
23   describe "GET /api/v1/pleroma/admin/announcements" do
24     test "it lists all announcements", %{conn: conn} do
25       %{id: id} = insert(:announcement)
26
27       response =
28         conn
29         |> get("/api/v1/pleroma/admin/announcements")
30         |> json_response_and_validate_schema(:ok)
31
32       assert [%{"id" => ^id}] = response
33     end
34
35     test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
36       conn
37       |> get("/api/v1/pleroma/admin/announcements")
38       |> json_response_and_validate_schema(:ok)
39
40       clear_config([:instance, :admin_privileges], [])
41
42       conn
43       |> get("/api/v1/pleroma/admin/announcements")
44       |> json_response(:forbidden)
45     end
46
47     test "it paginates announcements", %{conn: conn} do
48       _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
49
50       response =
51         conn
52         |> get("/api/v1/pleroma/admin/announcements")
53         |> json_response_and_validate_schema(:ok)
54
55       assert length(response) == 20
56     end
57
58     test "it paginates announcements with custom params", %{conn: conn} do
59       announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
60
61       response =
62         conn
63         |> get("/api/v1/pleroma/admin/announcements", limit: 5, offset: 7)
64         |> json_response_and_validate_schema(:ok)
65
66       assert length(response) == 5
67       assert Enum.at(response, 0)["id"] == Enum.at(announcements, 7).id
68     end
69
70     test "it returns empty list with out-of-bounds offset", %{conn: conn} do
71       _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
72
73       response =
74         conn
75         |> get("/api/v1/pleroma/admin/announcements", offset: 21)
76         |> json_response_and_validate_schema(:ok)
77
78       assert [] = response
79     end
80
81     test "it rejects invalid pagination params", %{conn: conn} do
82       conn
83       |> get("/api/v1/pleroma/admin/announcements", limit: 0)
84       |> json_response_and_validate_schema(400)
85
86       conn
87       |> get("/api/v1/pleroma/admin/announcements", limit: -1)
88       |> json_response_and_validate_schema(400)
89
90       conn
91       |> get("/api/v1/pleroma/admin/announcements", offset: -1)
92       |> json_response_and_validate_schema(400)
93     end
94   end
95
96   describe "GET /api/v1/pleroma/admin/announcements/:id" do
97     test "it displays one announcement", %{conn: conn} do
98       %{id: id} = insert(:announcement)
99
100       response =
101         conn
102         |> get("/api/v1/pleroma/admin/announcements/#{id}")
103         |> json_response_and_validate_schema(:ok)
104
105       assert %{"id" => ^id} = response
106     end
107
108     test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
109       %{id: id} = insert(:announcement)
110
111       conn
112       |> get("/api/v1/pleroma/admin/announcements/#{id}")
113       |> json_response_and_validate_schema(:ok)
114
115       clear_config([:instance, :admin_privileges], [])
116
117       conn
118       |> get("/api/v1/pleroma/admin/announcements/#{id}")
119       |> json_response(:forbidden)
120     end
121
122     test "it returns not found for non-existent id", %{conn: conn} do
123       %{id: id} = insert(:announcement)
124
125       _response =
126         conn
127         |> get("/api/v1/pleroma/admin/announcements/#{id}xxx")
128         |> json_response_and_validate_schema(:not_found)
129     end
130   end
131
132   describe "DELETE /api/v1/pleroma/admin/announcements/:id" do
133     test "it deletes specified announcement", %{conn: conn} do
134       %{id: id} = insert(:announcement)
135
136       _response =
137         conn
138         |> delete("/api/v1/pleroma/admin/announcements/#{id}")
139         |> json_response_and_validate_schema(:ok)
140     end
141
142     test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
143       %{id: id} = insert(:announcement)
144
145       conn
146       |> delete("/api/v1/pleroma/admin/announcements/#{id}")
147       |> json_response_and_validate_schema(:ok)
148
149       clear_config([:instance, :admin_privileges], [])
150
151       conn
152       |> delete("/api/v1/pleroma/admin/announcements/#{id}")
153       |> json_response(:forbidden)
154     end
155
156     test "it returns not found for non-existent id", %{conn: conn} do
157       %{id: id} = insert(:announcement)
158
159       _response =
160         conn
161         |> delete("/api/v1/pleroma/admin/announcements/#{id}xxx")
162         |> json_response_and_validate_schema(:not_found)
163
164       assert %{id: ^id} = Pleroma.Announcement.get_by_id(id)
165     end
166   end
167
168   describe "PATCH /api/v1/pleroma/admin/announcements/:id" do
169     test "it returns not found for non-existent id", %{conn: conn} do
170       %{id: id} = insert(:announcement)
171
172       _response =
173         conn
174         |> put_req_header("content-type", "application/json")
175         |> patch("/api/v1/pleroma/admin/announcements/#{id}xxx", %{})
176         |> json_response_and_validate_schema(:not_found)
177
178       assert %{id: ^id} = Pleroma.Announcement.get_by_id(id)
179     end
180
181     test "it updates a field", %{conn: conn} do
182       %{id: id} = insert(:announcement)
183
184       now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
185       starts_at = NaiveDateTime.add(now, -10, :second)
186
187       _response =
188         conn
189         |> put_req_header("content-type", "application/json")
190         |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
191           starts_at: NaiveDateTime.to_iso8601(starts_at)
192         })
193         |> json_response_and_validate_schema(:ok)
194
195       new = Pleroma.Announcement.get_by_id(id)
196
197       assert NaiveDateTime.compare(new.starts_at, starts_at) == :eq
198     end
199
200     test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
201       %{id: id} = insert(:announcement)
202
203       now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
204       starts_at = NaiveDateTime.add(now, -10, :second)
205
206       conn
207       |> put_req_header("content-type", "application/json")
208       |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
209         starts_at: NaiveDateTime.to_iso8601(starts_at)
210       })
211       |> json_response_and_validate_schema(:ok)
212
213       clear_config([:instance, :admin_privileges], [])
214
215       conn
216       |> put_req_header("content-type", "application/json")
217       |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
218         starts_at: NaiveDateTime.to_iso8601(starts_at)
219       })
220       |> json_response(:forbidden)
221     end
222
223     test "it updates with time with utc timezone", %{conn: conn} do
224       %{id: id} = insert(:announcement)
225
226       now = DateTime.now("Etc/UTC") |> elem(1) |> DateTime.truncate(:second)
227       starts_at = DateTime.add(now, -10, :second)
228
229       _response =
230         conn
231         |> put_req_header("content-type", "application/json")
232         |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
233           starts_at: DateTime.to_iso8601(starts_at)
234         })
235         |> json_response_and_validate_schema(:ok)
236
237       new = Pleroma.Announcement.get_by_id(id)
238
239       assert DateTime.compare(new.starts_at, starts_at) == :eq
240     end
241
242     test "it updates a data field", %{conn: conn} do
243       %{id: id} = announcement = insert(:announcement, data: %{"all_day" => true})
244
245       assert announcement.data["all_day"] == true
246
247       new_content = "new content"
248
249       response =
250         conn
251         |> put_req_header("content-type", "application/json")
252         |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
253           content: new_content
254         })
255         |> json_response_and_validate_schema(:ok)
256
257       assert response["content"] == new_content
258       assert response["all_day"] == true
259
260       new = Pleroma.Announcement.get_by_id(id)
261
262       assert new.data["content"] == new_content
263       assert new.data["all_day"] == true
264     end
265
266     test "it nullifies a nullable field", %{conn: conn} do
267       now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
268       starts_at = NaiveDateTime.add(now, -10, :second)
269
270       %{id: id} = insert(:announcement, starts_at: starts_at)
271
272       response =
273         conn
274         |> put_req_header("content-type", "application/json")
275         |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
276           starts_at: nil
277         })
278         |> json_response_and_validate_schema(:ok)
279
280       assert response["starts_at"] == nil
281
282       new = Pleroma.Announcement.get_by_id(id)
283
284       assert new.starts_at == nil
285     end
286   end
287
288   describe "POST /api/v1/pleroma/admin/announcements" do
289     test "it creates an announcement", %{conn: conn} do
290       content = "test post announcement api"
291
292       now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
293       starts_at = NaiveDateTime.add(now, -10, :second)
294       ends_at = NaiveDateTime.add(now, 10, :second)
295
296       response =
297         conn
298         |> put_req_header("content-type", "application/json")
299         |> post("/api/v1/pleroma/admin/announcements", %{
300           "content" => content,
301           "starts_at" => NaiveDateTime.to_iso8601(starts_at),
302           "ends_at" => NaiveDateTime.to_iso8601(ends_at),
303           "all_day" => true
304         })
305         |> json_response_and_validate_schema(:ok)
306
307       assert %{"content" => ^content, "all_day" => true} = response
308
309       announcement = Pleroma.Announcement.get_by_id(response["id"])
310
311       assert not is_nil(announcement)
312
313       assert NaiveDateTime.compare(announcement.starts_at, starts_at) == :eq
314       assert NaiveDateTime.compare(announcement.ends_at, ends_at) == :eq
315     end
316
317     test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do
318       content = "test post announcement api"
319
320       now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
321       starts_at = NaiveDateTime.add(now, -10, :second)
322       ends_at = NaiveDateTime.add(now, 10, :second)
323
324       conn
325       |> put_req_header("content-type", "application/json")
326       |> post("/api/v1/pleroma/admin/announcements", %{
327         "content" => content,
328         "starts_at" => NaiveDateTime.to_iso8601(starts_at),
329         "ends_at" => NaiveDateTime.to_iso8601(ends_at),
330         "all_day" => true
331       })
332       |> json_response_and_validate_schema(:ok)
333
334       clear_config([:instance, :admin_privileges], [])
335
336       conn
337       |> put_req_header("content-type", "application/json")
338       |> post("/api/v1/pleroma/admin/announcements", %{
339         "content" => content,
340         "starts_at" => NaiveDateTime.to_iso8601(starts_at),
341         "ends_at" => NaiveDateTime.to_iso8601(ends_at),
342         "all_day" => true
343       })
344       |> json_response(:forbidden)
345     end
346
347     test "creating with time with utc timezones", %{conn: conn} do
348       content = "test post announcement api"
349
350       now = DateTime.now("Etc/UTC") |> elem(1) |> DateTime.truncate(:second)
351       starts_at = DateTime.add(now, -10, :second)
352       ends_at = DateTime.add(now, 10, :second)
353
354       response =
355         conn
356         |> put_req_header("content-type", "application/json")
357         |> post("/api/v1/pleroma/admin/announcements", %{
358           "content" => content,
359           "starts_at" => DateTime.to_iso8601(starts_at),
360           "ends_at" => DateTime.to_iso8601(ends_at),
361           "all_day" => true
362         })
363         |> json_response_and_validate_schema(:ok)
364
365       assert %{"content" => ^content, "all_day" => true} = response
366
367       announcement = Pleroma.Announcement.get_by_id(response["id"])
368
369       assert not is_nil(announcement)
370
371       assert DateTime.compare(announcement.starts_at, starts_at) == :eq
372       assert DateTime.compare(announcement.ends_at, ends_at) == :eq
373     end
374   end
375 end