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"] == 3
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"] == 3
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"] == 3
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"] == 3
85 packs = Map.keys(resp["packs"])
86 assert length(packs) == 1
88 assert [pack1, pack2, pack3] |> Enum.uniq() |> length() == 3
91 describe "GET /api/pleroma/emoji/packs/remote" do
92 test "shareable instance", %{admin_conn: admin_conn, conn: conn} do
95 |> get("/api/pleroma/emoji/packs")
96 |> json_response_and_validate_schema(200)
99 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
100 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
102 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
103 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
105 %{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} ->
110 |> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
111 |> json_response_and_validate_schema(200) == resp
114 test "non shareable instance", %{admin_conn: admin_conn} do
116 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
117 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
119 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
120 json(%{metadata: %{features: []}})
124 |> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
125 |> json_response_and_validate_schema(500) == %{
126 "error" => "The requested instance does not support sharing emoji packs"
131 describe "GET /api/pleroma/emoji/packs/:name/archive" do
132 test "download shared pack", %{conn: conn} do
135 |> get("/api/pleroma/emoji/packs/test_pack/archive")
138 {:ok, arch} = :zip.unzip(resp, [:memory])
140 assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end)
141 assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end)
144 test "non existing pack", %{conn: conn} do
146 |> get("/api/pleroma/emoji/packs/test_pack_for_import/archive")
147 |> json_response_and_validate_schema(:not_found) == %{
148 "error" => "Pack test_pack_for_import does not exist"
152 test "non downloadable pack", %{conn: conn} do
154 |> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive")
155 |> json_response_and_validate_schema(:forbidden) == %{
157 "Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
162 describe "POST /api/pleroma/emoji/packs/download" do
163 test "shared pack from remote and non shared from fallback-src", %{
164 admin_conn: admin_conn,
168 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
169 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
171 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
172 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
176 url: "https://example.com/api/pleroma/emoji/packs/test_pack"
179 |> get("/api/pleroma/emoji/packs/test_pack")
180 |> json_response_and_validate_schema(200)
185 url: "https://example.com/api/pleroma/emoji/packs/test_pack/archive"
188 |> get("/api/pleroma/emoji/packs/test_pack/archive")
194 url: "https://example.com/api/pleroma/emoji/packs/test_pack_nonshared"
197 |> get("/api/pleroma/emoji/packs/test_pack_nonshared")
198 |> json_response_and_validate_schema(200)
203 url: "https://nonshared-pack"
205 text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip"))
209 |> put_req_header("content-type", "multipart/form-data")
210 |> post("/api/pleroma/emoji/packs/download", %{
211 url: "https://example.com",
215 |> json_response_and_validate_schema(200) == "ok"
217 assert File.exists?("#{@emoji_path}/test_pack2/pack.json")
218 assert File.exists?("#{@emoji_path}/test_pack2/blank.png")
221 |> delete("/api/pleroma/emoji/packs/test_pack2")
222 |> json_response_and_validate_schema(200) == "ok"
224 refute File.exists?("#{@emoji_path}/test_pack2")
227 |> put_req_header("content-type", "multipart/form-data")
229 "/api/pleroma/emoji/packs/download",
231 url: "https://example.com",
232 name: "test_pack_nonshared",
233 as: "test_pack_nonshared2"
236 |> json_response_and_validate_schema(200) == "ok"
238 assert File.exists?("#{@emoji_path}/test_pack_nonshared2/pack.json")
239 assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png")
242 |> delete("/api/pleroma/emoji/packs/test_pack_nonshared2")
243 |> json_response_and_validate_schema(200) == "ok"
245 refute File.exists?("#{@emoji_path}/test_pack_nonshared2")
248 test "nonshareable instance", %{admin_conn: admin_conn} do
250 %{method: :get, url: "https://old-instance/.well-known/nodeinfo"} ->
251 json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]})
253 %{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} ->
254 json(%{metadata: %{features: []}})
258 |> put_req_header("content-type", "multipart/form-data")
260 "/api/pleroma/emoji/packs/download",
262 url: "https://old-instance",
267 |> json_response_and_validate_schema(500) == %{
268 "error" => "The requested instance does not support sharing emoji packs"
272 test "checksum fail", %{admin_conn: admin_conn} do
274 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
275 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
277 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
278 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
282 url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha"
284 {:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
285 %Tesla.Env{status: 200, body: Jason.encode!(pack)}
289 url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha/archive"
293 body: File.read!("test/instance_static/emoji/pack_bad_sha/pack_bad_sha.zip")
298 |> put_req_header("content-type", "multipart/form-data")
299 |> post("/api/pleroma/emoji/packs/download", %{
300 url: "https://example.com",
301 name: "pack_bad_sha",
304 |> json_response_and_validate_schema(:internal_server_error) == %{
305 "error" => "SHA256 for the pack doesn't match the one sent by the server"
309 test "other error", %{admin_conn: admin_conn} do
311 %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
312 json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
314 %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
315 json(%{metadata: %{features: ["shareable_emoji_packs"]}})
319 url: "https://example.com/api/pleroma/emoji/packs/test_pack"
321 {:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
322 %Tesla.Env{status: 200, body: Jason.encode!(pack)}
326 |> put_req_header("content-type", "multipart/form-data")
327 |> post("/api/pleroma/emoji/packs/download", %{
328 url: "https://example.com",
332 |> json_response_and_validate_schema(:internal_server_error) == %{
334 "The pack was not set as shared and there is no fallback src to download from"
339 describe "PATCH /api/pleroma/emoji/packs/:name" do
341 pack_file = "#{@emoji_path}/test_pack/pack.json"
342 original_content = File.read!(pack_file)
345 File.write!(pack_file, original_content)
349 pack_file: pack_file,
351 "license" => "Test license changed",
352 "homepage" => "https://pleroma.social",
353 "description" => "Test description",
354 "share-files" => false
358 test "for a pack without a fallback source", ctx do
359 assert ctx[:admin_conn]
360 |> put_req_header("content-type", "multipart/form-data")
361 |> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]})
362 |> json_response_and_validate_schema(200) == ctx[:new_data]
364 assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
367 test "for a pack with a fallback source", ctx do
371 url: "https://nonshared-pack"
373 text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip"))
376 new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
381 "fallback-src-sha256",
382 "1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D"
385 assert ctx[:admin_conn]
386 |> put_req_header("content-type", "multipart/form-data")
387 |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
388 |> json_response_and_validate_schema(200) == new_data_with_sha
390 assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
393 test "when the fallback source doesn't have all the files", ctx do
397 url: "https://nonshared-pack"
399 {:ok, {'empty.zip', empty_arch}} = :zip.zip('empty.zip', [], [:memory])
403 new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
405 assert ctx[:admin_conn]
406 |> put_req_header("content-type", "multipart/form-data")
407 |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
408 |> json_response_and_validate_schema(:bad_request) == %{
409 "error" => "The fallback archive does not have all files specified in pack.json"
414 describe "POST/DELETE /api/pleroma/emoji/packs/:name" do
415 test "creating and deleting a pack", %{admin_conn: admin_conn} do
417 |> post("/api/pleroma/emoji/packs/test_created")
418 |> json_response_and_validate_schema(200) == "ok"
420 assert File.exists?("#{@emoji_path}/test_created/pack.json")
422 assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{
429 |> delete("/api/pleroma/emoji/packs/test_created")
430 |> json_response_and_validate_schema(200) == "ok"
432 refute File.exists?("#{@emoji_path}/test_created/pack.json")
435 test "if pack exists", %{admin_conn: admin_conn} do
436 path = Path.join(@emoji_path, "test_created")
438 pack_file = Jason.encode!(%{files: %{}, pack: %{}})
439 File.write!(Path.join(path, "pack.json"), pack_file)
442 |> post("/api/pleroma/emoji/packs/test_created")
443 |> json_response_and_validate_schema(:conflict) == %{
444 "error" => "A pack named \"test_created\" already exists"
447 on_exit(fn -> File.rm_rf(path) end)
450 test "with empty name", %{admin_conn: admin_conn} do
452 |> post("/api/pleroma/emoji/packs/ ")
453 |> json_response_and_validate_schema(:bad_request) == %{
454 "error" => "pack name cannot be empty"
459 test "deleting nonexisting pack", %{admin_conn: admin_conn} do
461 |> delete("/api/pleroma/emoji/packs/non_existing")
462 |> json_response_and_validate_schema(:not_found) == %{
463 "error" => "Pack non_existing does not exist"
467 test "deleting with empty name", %{admin_conn: admin_conn} do
469 |> delete("/api/pleroma/emoji/packs/ ")
470 |> json_response_and_validate_schema(:bad_request) == %{
471 "error" => "pack name cannot be empty"
475 test "filesystem import", %{admin_conn: admin_conn, conn: conn} do
477 File.rm!("#{@emoji_path}/test_pack_for_import/emoji.txt")
478 File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
481 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
483 refute Map.has_key?(resp["packs"], "test_pack_for_import")
486 |> get("/api/pleroma/emoji/packs/import")
487 |> json_response_and_validate_schema(200) == ["test_pack_for_import"]
489 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
490 assert resp["packs"]["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
492 File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
493 refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json")
495 emoji_txt_content = """
496 blank, blank.png, Fun
498 foo, /emoji/test_pack_for_import/blank.png
502 File.write!("#{@emoji_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
505 |> get("/api/pleroma/emoji/packs/import")
506 |> json_response_and_validate_schema(200) == ["test_pack_for_import"]
508 resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
510 assert resp["packs"]["test_pack_for_import"]["files"] == %{
511 "blank" => "blank.png",
512 "blank2" => "blank.png",
517 describe "GET /api/pleroma/emoji/packs/:name" do
518 test "shows pack.json", %{conn: conn} do
523 "can-download" => true,
524 "description" => "Test description",
525 "download-sha256" => _,
526 "homepage" => "https://pleroma.social",
527 "license" => "Test license",
528 "share-files" => true
532 |> get("/api/pleroma/emoji/packs/test_pack")
533 |> json_response_and_validate_schema(200)
535 assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"}
542 |> get("/api/pleroma/emoji/packs/test_pack?page_size=1")
543 |> json_response_and_validate_schema(200)
545 assert files |> Map.keys() |> length() == 1
552 |> get("/api/pleroma/emoji/packs/test_pack?page_size=1&page=2")
553 |> json_response_and_validate_schema(200)
555 assert files |> Map.keys() |> length() == 1
558 test "non existing pack", %{conn: conn} do
560 |> get("/api/pleroma/emoji/packs/non_existing")
561 |> json_response_and_validate_schema(:not_found) == %{
562 "error" => "Pack non_existing does not exist"
566 test "error name", %{conn: conn} do
568 |> get("/api/pleroma/emoji/packs/ ")
569 |> json_response_and_validate_schema(:bad_request) == %{
570 "error" => "pack name cannot be empty"