1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
6 use Pleroma.Web.ConnCase
11 @emoji_dir_path Path.join(
12 Pleroma.Config.get!([:instance, :static_dir]),
16 clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
17 Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
20 test "shared & non-shared pack information in list_packs is ok" do
22 resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
24 assert Map.has_key?(resp, "test_pack")
26 pack = resp["test_pack"]
28 assert Map.has_key?(pack["pack"], "download-sha256")
29 assert pack["pack"]["can-download"]
31 assert pack["files"] == %{"blank" => "blank.png"}
35 assert Map.has_key?(resp, "test_pack_nonshared")
37 pack = resp["test_pack_nonshared"]
39 refute pack["pack"]["shared"]
40 refute pack["pack"]["can-download"]
43 test "listing remote packs" do
44 admin = insert(:user, is_admin: true)
45 %{conn: conn} = oauth_access(["admin:write"], user: admin)
49 |> get(emoji_api_path(conn, :list_packs))
53 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
54 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
56 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
57 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
59 %{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} ->
64 |> post(emoji_api_path(conn, :list_from), %{instance_address: "https://example.com"})
65 |> json_response(200) == resp
68 test "downloading a shared pack from download_shared" do
73 |> get(emoji_api_path(conn, :download_shared, "test_pack"))
76 {:ok, arch} = :zip.unzip(resp, [:memory])
78 assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end)
79 assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end)
82 test "downloading shared & unshared packs from another instance via download_from, deleting them" do
84 File.rm_rf!("#{@emoji_dir_path}/test_pack2")
85 File.rm_rf!("#{@emoji_dir_path}/test_pack_nonshared2")
89 %{method: :get, url: "https://old-instance/.well-known/nodeinfo"} ->
90 json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]})
92 %{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} ->
93 json(%{metadata: %{features: []}})
95 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
96 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
98 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
99 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
103 url: "https://example.com/api/pleroma/emoji/packs/list"
108 |> get(emoji_api_path(conn, :list_packs))
109 |> json_response(200)
114 url: "https://example.com/api/pleroma/emoji/packs/download_shared/test_pack"
119 |> get(emoji_api_path(conn, :download_shared, "test_pack"))
125 url: "https://nonshared-pack"
127 text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip"))
130 admin = insert(:user, is_admin: true)
134 |> assign(:user, admin)
135 |> assign(:token, insert(:oauth_admin_token, user: admin, scopes: ["admin:write"]))
138 |> put_req_header("content-type", "application/json")
145 instance_address: "https://old-instance",
146 pack_name: "test_pack",
151 |> json_response(500))["error"] =~ "does not support"
154 |> put_req_header("content-type", "application/json")
161 instance_address: "https://example.com",
162 pack_name: "test_pack",
167 |> json_response(200) == "ok"
169 assert File.exists?("#{@emoji_dir_path}/test_pack2/pack.json")
170 assert File.exists?("#{@emoji_dir_path}/test_pack2/blank.png")
173 |> delete(emoji_api_path(conn, :delete, "test_pack2"))
174 |> json_response(200) == "ok"
176 refute File.exists?("#{@emoji_dir_path}/test_pack2")
178 # non-shared, downloaded from the fallback URL
181 |> put_req_header("content-type", "application/json")
188 instance_address: "https://example.com",
189 pack_name: "test_pack_nonshared",
190 as: "test_pack_nonshared2"
194 |> json_response(200) == "ok"
196 assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/pack.json")
197 assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/blank.png")
200 |> delete(emoji_api_path(conn, :delete, "test_pack_nonshared2"))
201 |> json_response(200) == "ok"
203 refute File.exists?("#{@emoji_dir_path}/test_pack_nonshared2")
206 describe "updating pack metadata" do
208 pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
209 original_content = File.read!(pack_file)
212 File.write!(pack_file, original_content)
215 admin = insert(:user, is_admin: true)
216 %{conn: conn} = oauth_access(["admin:write"], user: admin)
221 pack_file: pack_file,
223 "license" => "Test license changed",
224 "homepage" => "https://pleroma.social",
225 "description" => "Test description",
226 "share-files" => false
230 test "for a pack without a fallback source", ctx do
235 emoji_api_path(conn, :update_metadata, "test_pack"),
237 "new_data" => ctx[:new_data]
240 |> json_response(200) == ctx[:new_data]
242 assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
245 test "for a pack with a fallback source", ctx do
249 url: "https://nonshared-pack"
251 text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip"))
254 new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
259 "fallback-src-sha256",
260 "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF"
267 emoji_api_path(conn, :update_metadata, "test_pack"),
269 "new_data" => new_data
272 |> json_response(200) == new_data_with_sha
274 assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
277 test "when the fallback source doesn't have all the files", ctx do
281 url: "https://nonshared-pack"
283 {:ok, {'empty.zip', empty_arch}} = :zip.zip('empty.zip', [], [:memory])
287 new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
293 emoji_api_path(conn, :update_metadata, "test_pack"),
295 "new_data" => new_data
298 |> json_response(:bad_request))["error"] =~ "does not have all"
302 test "updating pack files" do
303 pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
304 original_content = File.read!(pack_file)
307 File.write!(pack_file, original_content)
309 File.rm_rf!("#{@emoji_dir_path}/test_pack/blank_url.png")
310 File.rm_rf!("#{@emoji_dir_path}/test_pack/dir")
311 File.rm_rf!("#{@emoji_dir_path}/test_pack/dir_2")
314 admin = insert(:user, is_admin: true)
315 %{conn: conn} = oauth_access(["admin:write"], user: admin)
319 "shortcode" => "blank",
320 "filename" => "dir/blank.png",
321 "file" => %Plug.Upload{
322 filename: "blank.png",
323 path: "#{@emoji_dir_path}/test_pack/blank.png"
327 different_name = %{same_name | "shortcode" => "blank_2"}
330 |> post(emoji_api_path(conn, :update_file, "test_pack"), same_name)
331 |> json_response(:conflict))["error"] =~ "already exists"
334 |> post(emoji_api_path(conn, :update_file, "test_pack"), different_name)
335 |> json_response(200) == %{"blank" => "blank.png", "blank_2" => "dir/blank.png"}
337 assert File.exists?("#{@emoji_dir_path}/test_pack/dir/blank.png")
340 |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
341 "action" => "update",
342 "shortcode" => "blank_2",
343 "new_shortcode" => "blank_3",
344 "new_filename" => "dir_2/blank_3.png"
346 |> json_response(200) == %{"blank" => "blank.png", "blank_3" => "dir_2/blank_3.png"}
348 refute File.exists?("#{@emoji_dir_path}/test_pack/dir/")
349 assert File.exists?("#{@emoji_dir_path}/test_pack/dir_2/blank_3.png")
352 |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
353 "action" => "remove",
354 "shortcode" => "blank_3"
356 |> json_response(200) == %{"blank" => "blank.png"}
358 refute File.exists?("#{@emoji_dir_path}/test_pack/dir_2/")
363 url: "https://test-blank/blank_url.png"
365 text(File.read!("#{@emoji_dir_path}/test_pack/blank.png"))
368 # The name should be inferred from the URL ending
371 "shortcode" => "blank_url",
372 "file" => "https://test-blank/blank_url.png"
376 |> post(emoji_api_path(conn, :update_file, "test_pack"), from_url)
377 |> json_response(200) == %{
378 "blank" => "blank.png",
379 "blank_url" => "blank_url.png"
382 assert File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png")
385 |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
386 "action" => "remove",
387 "shortcode" => "blank_url"
389 |> json_response(200) == %{"blank" => "blank.png"}
391 refute File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png")
394 test "creating and deleting a pack" do
396 File.rm_rf!("#{@emoji_dir_path}/test_created")
399 admin = insert(:user, is_admin: true)
400 %{conn: conn} = oauth_access(["admin:write"], user: admin)
403 |> put_req_header("content-type", "application/json")
411 |> json_response(200) == "ok"
413 assert File.exists?("#{@emoji_dir_path}/test_created/pack.json")
415 assert Jason.decode!(File.read!("#{@emoji_dir_path}/test_created/pack.json")) == %{
421 |> delete(emoji_api_path(conn, :delete, "test_created"))
422 |> json_response(200) == "ok"
424 refute File.exists?("#{@emoji_dir_path}/test_created/pack.json")
427 test "filesystem import" do
429 File.rm!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt")
430 File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json")
434 resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
436 refute Map.has_key?(resp, "test_pack_for_import")
438 admin = insert(:user, is_admin: true)
439 %{conn: conn} = oauth_access(["admin:write"], user: admin)
442 |> post(emoji_api_path(conn, :import_from_fs))
443 |> json_response(200) == ["test_pack_for_import"]
445 resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
446 assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
448 File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json")
449 refute File.exists?("#{@emoji_dir_path}/test_pack_for_import/pack.json")
451 emoji_txt_content = "blank, blank.png, Fun\n\nblank2, blank.png"
453 File.write!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
456 |> post(emoji_api_path(conn, :import_from_fs))
457 |> json_response(200) == ["test_pack_for_import"]
459 resp = build_conn() |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
461 assert resp["test_pack_for_import"]["files"] == %{
462 "blank" => "blank.png",
463 "blank2" => "blank.png"