move to 2.5.5
[anni] / test / pleroma / web / pleroma_api / controllers / emoji_file_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.PleromaAPI.EmojiFileControllerTest do
6   use Pleroma.Web.ConnCase, async: false
7
8   import Mock
9   import Tesla.Mock
10   import Pleroma.Factory
11
12   @emoji_path Path.join(
13                 Pleroma.Config.get!([:instance, :static_dir]),
14                 "emoji"
15               )
16   setup do: clear_config([:instance, :public], true)
17
18   setup do
19     admin = insert(:user, is_admin: true)
20     token = insert(:oauth_admin_token, user: admin)
21
22     admin_conn =
23       build_conn()
24       |> assign(:user, admin)
25       |> assign(:token, token)
26
27     Pleroma.Emoji.reload()
28     {:ok, %{admin_conn: admin_conn}}
29   end
30
31   describe "POST/PATCH/DELETE /api/pleroma/emoji/packs/files?name=:name" do
32     setup do
33       clear_config([:instance, :admin_privileges], [:emoji_manage_emoji])
34       pack_file = "#{@emoji_path}/test_pack/pack.json"
35       original_content = File.read!(pack_file)
36
37       on_exit(fn ->
38         File.write!(pack_file, original_content)
39       end)
40
41       :ok
42     end
43
44     test "upload zip file with emojies", %{admin_conn: admin_conn} do
45       on_exit(fn ->
46         [
47           "128px/a_trusted_friend-128.png",
48           "auroraborealis.png",
49           "1000px/baby_in_a_box.png",
50           "1000px/bear.png",
51           "128px/bear-128.png"
52         ]
53         |> Enum.each(fn path -> File.rm_rf!("#{@emoji_path}/test_pack/#{path}") end)
54       end)
55
56       resp =
57         admin_conn
58         |> put_req_header("content-type", "multipart/form-data")
59         |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
60           file: %Plug.Upload{
61             content_type: "application/zip",
62             filename: "emojis.zip",
63             path: Path.absname("test/fixtures/emojis.zip")
64           }
65         })
66         |> json_response_and_validate_schema(200)
67
68       assert resp == %{
69                "a_trusted_friend-128" => "128px/a_trusted_friend-128.png",
70                "auroraborealis" => "auroraborealis.png",
71                "baby_in_a_box" => "1000px/baby_in_a_box.png",
72                "bear" => "1000px/bear.png",
73                "bear-128" => "128px/bear-128.png",
74                "blank" => "blank.png",
75                "blank2" => "blank2.png"
76              }
77
78       Enum.each(Map.values(resp), fn path ->
79         assert File.exists?("#{@emoji_path}/test_pack/#{path}")
80       end)
81     end
82
83     test "create shortcode exists", %{admin_conn: admin_conn} do
84       assert admin_conn
85              |> put_req_header("content-type", "multipart/form-data")
86              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
87                shortcode: "blank",
88                filename: "dir/blank.png",
89                file: %Plug.Upload{
90                  filename: "blank.png",
91                  path: "#{@emoji_path}/test_pack/blank.png"
92                }
93              })
94              |> json_response_and_validate_schema(:conflict) == %{
95                "error" => "An emoji with the \"blank\" shortcode already exists"
96              }
97     end
98
99     test "don't rewrite old emoji", %{admin_conn: admin_conn} do
100       on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end)
101
102       assert admin_conn
103              |> put_req_header("content-type", "multipart/form-data")
104              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
105                shortcode: "blank3",
106                filename: "dir/blank.png",
107                file: %Plug.Upload{
108                  filename: "blank.png",
109                  path: "#{@emoji_path}/test_pack/blank.png"
110                }
111              })
112              |> json_response_and_validate_schema(200) == %{
113                "blank" => "blank.png",
114                "blank2" => "blank2.png",
115                "blank3" => "dir/blank.png"
116              }
117
118       assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
119
120       assert admin_conn
121              |> put_req_header("content-type", "multipart/form-data")
122              |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
123                shortcode: "blank",
124                new_shortcode: "blank2",
125                new_filename: "dir_2/blank_3.png"
126              })
127              |> json_response_and_validate_schema(:conflict) == %{
128                "error" =>
129                  "New shortcode \"blank2\" is already used. If you want to override emoji use 'force' option"
130              }
131     end
132
133     test "rewrite old emoji with force option", %{admin_conn: admin_conn} do
134       on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end)
135
136       assert admin_conn
137              |> put_req_header("content-type", "multipart/form-data")
138              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
139                shortcode: "blank3",
140                filename: "dir/blank.png",
141                file: %Plug.Upload{
142                  filename: "blank.png",
143                  path: "#{@emoji_path}/test_pack/blank.png"
144                }
145              })
146              |> json_response_and_validate_schema(200) == %{
147                "blank" => "blank.png",
148                "blank2" => "blank2.png",
149                "blank3" => "dir/blank.png"
150              }
151
152       assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
153
154       assert admin_conn
155              |> put_req_header("content-type", "multipart/form-data")
156              |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
157                shortcode: "blank3",
158                new_shortcode: "blank4",
159                new_filename: "dir_2/blank_3.png",
160                force: true
161              })
162              |> json_response_and_validate_schema(200) == %{
163                "blank" => "blank.png",
164                "blank2" => "blank2.png",
165                "blank4" => "dir_2/blank_3.png"
166              }
167
168       assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
169     end
170
171     test "with empty filename", %{admin_conn: admin_conn} do
172       assert admin_conn
173              |> put_req_header("content-type", "multipart/form-data")
174              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
175                shortcode: "blank2",
176                filename: "",
177                file: %Plug.Upload{
178                  filename: "blank.png",
179                  path: "#{@emoji_path}/test_pack/blank.png"
180                }
181              })
182              |> json_response_and_validate_schema(422) == %{
183                "error" => "pack name, shortcode or filename cannot be empty"
184              }
185     end
186
187     test "add file with not loaded pack", %{admin_conn: admin_conn} do
188       assert admin_conn
189              |> put_req_header("content-type", "multipart/form-data")
190              |> post("/api/pleroma/emoji/packs/files?name=not_loaded", %{
191                shortcode: "blank3",
192                filename: "dir/blank.png",
193                file: %Plug.Upload{
194                  filename: "blank.png",
195                  path: "#{@emoji_path}/test_pack/blank.png"
196                }
197              })
198              |> json_response_and_validate_schema(:not_found) == %{
199                "error" => "pack \"not_loaded\" is not found"
200              }
201     end
202
203     test "returns an error on add file when file system is not writable", %{
204       admin_conn: admin_conn
205     } do
206       pack_file = Path.join([@emoji_path, "not_loaded", "pack.json"])
207
208       with_mocks([
209         {File, [:passthrough], [stat: fn ^pack_file -> {:error, :eacces} end]}
210       ]) do
211         assert admin_conn
212                |> put_req_header("content-type", "multipart/form-data")
213                |> post("/api/pleroma/emoji/packs/files?name=not_loaded", %{
214                  shortcode: "blank3",
215                  filename: "dir/blank.png",
216                  file: %Plug.Upload{
217                    filename: "blank.png",
218                    path: "#{@emoji_path}/test_pack/blank.png"
219                  }
220                })
221                |> json_response_and_validate_schema(500) == %{
222                  "error" =>
223                    "Unexpected error occurred while adding file to pack. (POSIX error: Permission denied)"
224                }
225       end
226     end
227
228     test "remove file with not loaded pack", %{admin_conn: admin_conn} do
229       assert admin_conn
230              |> delete("/api/pleroma/emoji/packs/files?name=not_loaded&shortcode=blank3")
231              |> json_response_and_validate_schema(:not_found) == %{
232                "error" => "pack \"not_loaded\" is not found"
233              }
234     end
235
236     test "remove file with empty shortcode", %{admin_conn: admin_conn} do
237       assert admin_conn
238              |> delete("/api/pleroma/emoji/packs/files?name=not_loaded&shortcode=")
239              |> json_response_and_validate_schema(:not_found) == %{
240                "error" => "pack \"not_loaded\" is not found"
241              }
242     end
243
244     test "update file with not loaded pack", %{admin_conn: admin_conn} do
245       assert admin_conn
246              |> put_req_header("content-type", "multipart/form-data")
247              |> patch("/api/pleroma/emoji/packs/files?name=not_loaded", %{
248                shortcode: "blank4",
249                new_shortcode: "blank3",
250                new_filename: "dir_2/blank_3.png"
251              })
252              |> json_response_and_validate_schema(:not_found) == %{
253                "error" => "pack \"not_loaded\" is not found"
254              }
255     end
256
257     test "new with shortcode as file with update", %{admin_conn: admin_conn} do
258       assert admin_conn
259              |> put_req_header("content-type", "multipart/form-data")
260              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
261                shortcode: "blank4",
262                filename: "dir/blank.png",
263                file: %Plug.Upload{
264                  filename: "blank.png",
265                  path: "#{@emoji_path}/test_pack/blank.png"
266                }
267              })
268              |> json_response_and_validate_schema(200) == %{
269                "blank" => "blank.png",
270                "blank4" => "dir/blank.png",
271                "blank2" => "blank2.png"
272              }
273
274       assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
275
276       assert admin_conn
277              |> put_req_header("content-type", "multipart/form-data")
278              |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
279                shortcode: "blank4",
280                new_shortcode: "blank3",
281                new_filename: "dir_2/blank_3.png"
282              })
283              |> json_response_and_validate_schema(200) == %{
284                "blank3" => "dir_2/blank_3.png",
285                "blank" => "blank.png",
286                "blank2" => "blank2.png"
287              }
288
289       refute File.exists?("#{@emoji_path}/test_pack/dir/")
290       assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
291
292       assert admin_conn
293              |> delete("/api/pleroma/emoji/packs/files?name=test_pack&shortcode=blank3")
294              |> json_response_and_validate_schema(200) == %{
295                "blank" => "blank.png",
296                "blank2" => "blank2.png"
297              }
298
299       refute File.exists?("#{@emoji_path}/test_pack/dir_2/")
300
301       on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir") end)
302     end
303
304     test "new with shortcode from url", %{admin_conn: admin_conn} do
305       mock(fn
306         %{
307           method: :get,
308           url: "https://test-blank/blank_url.png"
309         } ->
310           text(File.read!("#{@emoji_path}/test_pack/blank.png"))
311       end)
312
313       assert admin_conn
314              |> put_req_header("content-type", "multipart/form-data")
315              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
316                shortcode: "blank_url",
317                file: "https://test-blank/blank_url.png"
318              })
319              |> json_response_and_validate_schema(200) == %{
320                "blank_url" => "blank_url.png",
321                "blank" => "blank.png",
322                "blank2" => "blank2.png"
323              }
324
325       assert File.exists?("#{@emoji_path}/test_pack/blank_url.png")
326
327       on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/blank_url.png") end)
328     end
329
330     test "new without shortcode", %{admin_conn: admin_conn} do
331       on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end)
332
333       assert admin_conn
334              |> put_req_header("content-type", "multipart/form-data")
335              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
336                file: %Plug.Upload{
337                  filename: "shortcode.png",
338                  path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"
339                }
340              })
341              |> json_response_and_validate_schema(200) == %{
342                "shortcode" => "shortcode.png",
343                "blank" => "blank.png",
344                "blank2" => "blank2.png"
345              }
346     end
347
348     test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do
349       assert admin_conn
350              |> delete("/api/pleroma/emoji/packs/files?name=test_pack&shortcode=blank3")
351              |> json_response_and_validate_schema(:bad_request) == %{
352                "error" => "Emoji \"blank3\" does not exist"
353              }
354     end
355
356     test "update non existing emoji", %{admin_conn: admin_conn} do
357       assert admin_conn
358              |> put_req_header("content-type", "multipart/form-data")
359              |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
360                shortcode: "blank3",
361                new_shortcode: "blank4",
362                new_filename: "dir_2/blank_3.png"
363              })
364              |> json_response_and_validate_schema(:bad_request) == %{
365                "error" => "Emoji \"blank3\" does not exist"
366              }
367     end
368
369     test "update with empty shortcode", %{admin_conn: admin_conn} do
370       assert %{
371                "error" => "Missing field: new_shortcode."
372              } =
373                admin_conn
374                |> put_req_header("content-type", "multipart/form-data")
375                |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
376                  shortcode: "blank",
377                  new_filename: "dir_2/blank_3.png"
378                })
379                |> json_response_and_validate_schema(:bad_request)
380     end
381
382     test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do
383       clear_config([:instance, :admin_privileges], [])
384
385       assert admin_conn
386              |> put_req_header("content-type", "multipart/form-data")
387              |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{
388                file: %Plug.Upload{
389                  filename: "shortcode.png",
390                  path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"
391                }
392              })
393              |> json_response(:forbidden)
394
395       assert admin_conn
396              |> put_req_header("content-type", "multipart/form-data")
397              |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{
398                shortcode: "blank",
399                new_filename: "dir_2/blank_3.png"
400              })
401              |> json_response(:forbidden)
402
403       assert admin_conn
404              |> put_req_header("content-type", "multipart/form-data")
405              |> delete("/api/pleroma/emoji/packs/files?name=test_pack&shortcode=blank3")
406              |> json_response(:forbidden)
407     end
408   end
409 end