1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
6 use Pleroma.Web.ConnCase
11 @emoji_path Path.join(
12 Pleroma.Config.get!([:instance, :static_dir]),
15 setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
17 setup do: clear_config([:instance, :public], true)
20 admin = insert(:user, is_admin: true)
21 token = insert(:oauth_admin_token, user: admin)
25 |> assign(:user, admin)
26 |> assign(:token, token)
28 Pleroma.Emoji.reload()
29 {:ok, %{admin_conn: admin_conn}}
32 test "GET /api/pleroma/emoji/packs when :public: false", %{conn: conn} do
33 Config.put([:instance, :public], false)
34 conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
37 test "GET /api/pleroma/emoji/packs", %{conn: conn} do
38 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
40 assert resp["count"] == 4
46 shared = resp["packs"]["test_pack"]
47 assert shared["files"] == %{"blank" => "blank.png", "blank2" => "blank2.png"}
48 assert Map.has_key?(shared["pack"], "download-sha256")
49 assert shared["pack"]["can-download"]
50 assert shared["pack"]["share-files"]
52 non_shared = resp["packs"]["test_pack_nonshared"]
53 assert non_shared["pack"]["share-files"] == false
54 assert non_shared["pack"]["can-download"] == false
58 |> get("/api/pleroma/emoji/packs?page_size=1")
59 |> json_response_and_validate_schema(200)
61 assert resp["count"] == 4
63 packs = Map.keys(resp["packs"])
65 assert length(packs) == 1
71 |> get("/api/pleroma/emoji/packs?page_size=1&page=2")
72 |> json_response_and_validate_schema(200)
74 assert resp["count"] == 4
75 packs = Map.keys(resp["packs"])
76 assert length(packs) == 1
81 |> get("/api/pleroma/emoji/packs?page_size=1&page=3")
82 |> json_response_and_validate_schema(200)
84 assert resp["count"] == 4
85 packs = Map.keys(resp["packs"])
86 assert length(packs) == 1
91 |> get("/api/pleroma/emoji/packs?page_size=1&page=4")
92 |> json_response_and_validate_schema(200)
94 assert resp["count"] == 4
95 packs = Map.keys(resp["packs"])
96 assert length(packs) == 1
98 assert [pack1, pack2, pack3, pack4] |> Enum.uniq() |> length() == 4
101 describe "GET /api/pleroma/emoji/packs/remote" do
102 test "shareable instance", %{admin_conn: admin_conn, conn: conn} do
105 |> get("/api/pleroma/emoji/packs?page=2&page_size=1")
106 |> json_response_and_validate_schema(200)
109 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
110 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
112 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
113 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
115 %{method: :get, url: "https://example.com/api/pleroma/emoji/packs?page=2&page_size=1"} ->
120 |> get("/api/pleroma/emoji/packs/remote?url=https://example.com&page=2&page_size=1")
121 |> json_response_and_validate_schema(200) == resp
124 test "non shareable instance", %{admin_conn: admin_conn} do
126 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
127 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
129 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
130 json(%{metadata: %{features: []}})
134 |> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
135 |> json_response_and_validate_schema(500) == %{
136 "error" => "The requested instance does not support sharing emoji packs"
141 describe "GET /api/pleroma/emoji/packs/archive?name=:name" do
142 test "download shared pack", %{conn: conn} do
145 |> get("/api/pleroma/emoji/packs/archive?name=test_pack")
148 {:ok, arch} = :zip.unzip(resp, [:memory])
150 assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end)
151 assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end)
154 test "non existing pack", %{conn: conn} do
156 |> get("/api/pleroma/emoji/packs/archive?name=test_pack_for_import")
157 |> json_response_and_validate_schema(:not_found) == %{
158 "error" => "Pack test_pack_for_import does not exist"
162 test "non downloadable pack", %{conn: conn} do
164 |> get("/api/pleroma/emoji/packs/archive?name=test_pack_nonshared")
165 |> json_response_and_validate_schema(:forbidden) == %{
167 "Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
172 describe "POST /api/pleroma/emoji/packs/download" do
173 test "shared pack from remote and non shared from fallback-src", %{
174 admin_conn: admin_conn,
178 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
179 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
181 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
182 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
186 url: "https://example.com/api/pleroma/emoji/pack?name=test_pack"
189 |> get("/api/pleroma/emoji/pack?name=test_pack")
190 |> json_response_and_validate_schema(200)
195 url: "https://example.com/api/pleroma/emoji/packs/archive?name=test_pack"
198 |> get("/api/pleroma/emoji/packs/archive?name=test_pack")
204 url: "https://example.com/api/pleroma/emoji/pack?name=test_pack_nonshared"
207 |> get("/api/pleroma/emoji/pack?name=test_pack_nonshared")
208 |> json_response_and_validate_schema(200)
213 url: "https://nonshared-pack"
215 text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip"))
219 |> put_req_header("content-type", "multipart/form-data")
220 |> post("/api/pleroma/emoji/packs/download", %{
221 url: "https://example.com",
225 |> json_response_and_validate_schema(200) == "ok"
227 assert File.exists?("#{@emoji_path}/test_pack2/pack.json")
228 assert File.exists?("#{@emoji_path}/test_pack2/blank.png")
231 |> delete("/api/pleroma/emoji/pack?name=test_pack2")
232 |> json_response_and_validate_schema(200) == "ok"
234 refute File.exists?("#{@emoji_path}/test_pack2")
237 |> put_req_header("content-type", "multipart/form-data")
239 "/api/pleroma/emoji/packs/download",
241 url: "https://example.com",
242 name: "test_pack_nonshared",
243 as: "test_pack_nonshared2"
246 |> json_response_and_validate_schema(200) == "ok"
248 assert File.exists?("#{@emoji_path}/test_pack_nonshared2/pack.json")
249 assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png")
252 |> delete("/api/pleroma/emoji/pack?name=test_pack_nonshared2")
253 |> json_response_and_validate_schema(200) == "ok"
255 refute File.exists?("#{@emoji_path}/test_pack_nonshared2")
258 test "nonshareable instance", %{admin_conn: admin_conn} do
260 %{method: :get, url: "https://old-instance/.well-known/nodeinfo"} ->
261 json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]})
263 %{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} ->
264 json(%{metadata: %{features: []}})
268 |> put_req_header("content-type", "multipart/form-data")
270 "/api/pleroma/emoji/packs/download",
272 url: "https://old-instance",
277 |> json_response_and_validate_schema(500) == %{
278 "error" => "The requested instance does not support sharing emoji packs"
282 test "checksum fail", %{admin_conn: admin_conn} do
284 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
285 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
287 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
288 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
292 url: "https://example.com/api/pleroma/emoji/pack?name=pack_bad_sha"
294 {:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
295 %Tesla.Env{status: 200, body: Jason.encode!(pack)}
299 url: "https://example.com/api/pleroma/emoji/packs/archive?name=pack_bad_sha"
303 body: File.read!("test/instance_static/emoji/pack_bad_sha/pack_bad_sha.zip")
308 |> put_req_header("content-type", "multipart/form-data")
309 |> post("/api/pleroma/emoji/packs/download", %{
310 url: "https://example.com",
311 name: "pack_bad_sha",
314 |> json_response_and_validate_schema(:internal_server_error) == %{
315 "error" => "SHA256 for the pack doesn't match the one sent by the server"
319 test "other error", %{admin_conn: admin_conn} do
321 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
322 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
324 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
325 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
329 url: "https://example.com/api/pleroma/emoji/pack?name=test_pack"
331 {:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
332 %Tesla.Env{status: 200, body: Jason.encode!(pack)}
336 |> put_req_header("content-type", "multipart/form-data")
337 |> post("/api/pleroma/emoji/packs/download", %{
338 url: "https://example.com",
342 |> json_response_and_validate_schema(:internal_server_error) == %{
344 "The pack was not set as shared and there is no fallback src to download from"
349 describe "PATCH /api/pleroma/emoji/pack?name=:name" do
351 pack_file = "#{@emoji_path}/test_pack/pack.json"
352 original_content = File.read!(pack_file)
355 File.write!(pack_file, original_content)
359 pack_file: pack_file,
361 "license" => "Test license changed",
362 "homepage" => "https://pleroma.social",
363 "description" => "Test description",
364 "share-files" => false
368 test "for a pack without a fallback source", ctx do
369 assert ctx[:admin_conn]
370 |> put_req_header("content-type", "multipart/form-data")
371 |> patch("/api/pleroma/emoji/pack?name=test_pack", %{
372 "metadata" => ctx[:new_data]
374 |> json_response_and_validate_schema(200) == ctx[:new_data]
376 assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
379 test "for a pack with a fallback source", ctx do
383 url: "https://nonshared-pack"
385 text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip"))
388 new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
393 "fallback-src-sha256",
394 "1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D"
397 assert ctx[:admin_conn]
398 |> put_req_header("content-type", "multipart/form-data")
399 |> patch("/api/pleroma/emoji/pack?name=test_pack", %{metadata: new_data})
400 |> json_response_and_validate_schema(200) == new_data_with_sha
402 assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
405 test "when the fallback source doesn't have all the files", ctx do
409 url: "https://nonshared-pack"
411 {:ok, {'empty.zip', empty_arch}} = :zip.zip('empty.zip', [], [:memory])
415 new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
417 assert ctx[:admin_conn]
418 |> put_req_header("content-type", "multipart/form-data")
419 |> patch("/api/pleroma/emoji/pack?name=test_pack", %{metadata: new_data})
420 |> json_response_and_validate_schema(:bad_request) == %{
421 "error" => "The fallback archive does not have all files specified in pack.json"
426 describe "POST/DELETE /api/pleroma/emoji/pack?name=:name" do
427 test "creating and deleting a pack", %{admin_conn: admin_conn} do
429 |> post("/api/pleroma/emoji/pack?name=test_created")
430 |> json_response_and_validate_schema(200) == "ok"
432 assert File.exists?("#{@emoji_path}/test_created/pack.json")
434 assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{
441 |> delete("/api/pleroma/emoji/pack?name=test_created")
442 |> json_response_and_validate_schema(200) == "ok"
444 refute File.exists?("#{@emoji_path}/test_created/pack.json")
447 test "if pack exists", %{admin_conn: admin_conn} do
448 path = Path.join(@emoji_path, "test_created")
450 pack_file = Jason.encode!(%{files: %{}, pack: %{}})
451 File.write!(Path.join(path, "pack.json"), pack_file)
454 |> post("/api/pleroma/emoji/pack?name=test_created")
455 |> json_response_and_validate_schema(:conflict) == %{
456 "error" => "A pack named \"test_created\" already exists"
459 on_exit(fn -> File.rm_rf(path) end)
462 test "with empty name", %{admin_conn: admin_conn} do
464 |> post("/api/pleroma/emoji/pack?name= ")
465 |> json_response_and_validate_schema(:bad_request) == %{
466 "error" => "pack name cannot be empty"
471 test "deleting nonexisting pack", %{admin_conn: admin_conn} do
473 |> delete("/api/pleroma/emoji/pack?name=non_existing")
474 |> json_response_and_validate_schema(:not_found) == %{
475 "error" => "Pack non_existing does not exist"
479 test "deleting with empty name", %{admin_conn: admin_conn} do
481 |> delete("/api/pleroma/emoji/pack?name= ")
482 |> json_response_and_validate_schema(:bad_request) == %{
483 "error" => "pack name cannot be empty"
487 test "filesystem import", %{admin_conn: admin_conn, conn: conn} do
489 File.rm!("#{@emoji_path}/test_pack_for_import/emoji.txt")
490 File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
493 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
495 refute Map.has_key?(resp["packs"], "test_pack_for_import")
498 |> get("/api/pleroma/emoji/packs/import")
499 |> json_response_and_validate_schema(200) == ["test_pack_for_import"]
501 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
502 assert resp["packs"]["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
504 File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
505 refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json")
507 emoji_txt_content = """
508 blank, blank.png, Fun
510 foo, /emoji/test_pack_for_import/blank.png
514 File.write!("#{@emoji_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
517 |> get("/api/pleroma/emoji/packs/import")
518 |> json_response_and_validate_schema(200) == ["test_pack_for_import"]
520 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
522 assert resp["packs"]["test_pack_for_import"]["files"] == %{
523 "blank" => "blank.png",
524 "blank2" => "blank.png",
529 describe "GET /api/pleroma/emoji/pack?name=:name" do
530 test "shows pack.json", %{conn: conn} do
535 "can-download" => true,
536 "description" => "Test description",
537 "download-sha256" => _,
538 "homepage" => "https://pleroma.social",
539 "license" => "Test license",
540 "share-files" => true
544 |> get("/api/pleroma/emoji/pack?name=test_pack")
545 |> json_response_and_validate_schema(200)
547 assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"}
554 |> get("/api/pleroma/emoji/pack?name=test_pack&page_size=1")
555 |> json_response_and_validate_schema(200)
557 assert files |> Map.keys() |> length() == 1
564 |> get("/api/pleroma/emoji/pack?name=test_pack&page_size=1&page=2")
565 |> json_response_and_validate_schema(200)
567 assert files |> Map.keys() |> length() == 1
570 test "for pack name with special chars", %{conn: conn} do
575 "can-download" => true,
576 "description" => "Test description",
577 "download-sha256" => _,
578 "homepage" => "https://pleroma.social",
579 "license" => "Test license",
580 "share-files" => true
584 |> get("/api/pleroma/emoji/pack?name=blobs.gg")
585 |> json_response_and_validate_schema(200)
588 test "non existing pack", %{conn: conn} do
590 |> get("/api/pleroma/emoji/pack?name=non_existing")
591 |> json_response_and_validate_schema(:not_found) == %{
592 "error" => "Pack non_existing does not exist"
596 test "error name", %{conn: conn} do
598 |> get("/api/pleroma/emoji/pack?name= ")
599 |> json_response_and_validate_schema(:bad_request) == %{
600 "error" => "pack name cannot be empty"