added tests
authorMaksim Pechnikov <parallel588@gmail.com>
Mon, 24 Aug 2020 06:47:25 +0000 (09:47 +0300)
committerMaksim Pechnikov <parallel588@gmail.com>
Mon, 24 Aug 2020 12:01:45 +0000 (15:01 +0300)
lib/pleroma/emoji.ex
lib/pleroma/emoji/pack.ex
lib/pleroma/utils.ex
test/emoji/pack_test.exs [new file with mode: 0644]
test/fixtures/empty.zip [new file with mode: 0644]
test/utils_test.exs [new file with mode: 0644]

index f6016d73fb5c02a0118cfe250a5980d844dd4c99..04936155b5e1419c63878f437f75c4224e687f14 100644 (file)
@@ -56,6 +56,9 @@ defmodule Pleroma.Emoji do
     end
   end
 
+  @spec exist?(String.t()) :: boolean()
+  def exist?(name), do: not is_nil(get(name))
+
   @doc "Returns all the emojos!!"
   @spec get_all() :: list({String.t(), String.t(), String.t()})
   def get_all do
index 03aed33bbe7e6b07b1eab4b1a67c40a9f7badf38..dd79bdfab1917e31cd12eb277b3c4e5dbc9fdf93 100644 (file)
@@ -65,71 +65,73 @@ defmodule Pleroma.Emoji.Pack do
     end
   end
 
+  @spec unpack_zip_emojies(list(tuple())) :: list(map())
+  defp unpack_zip_emojies(zip_files) do
+    Enum.reduce(zip_files, [], fn
+      {_, path, s, _, _, _}, acc when elem(s, 2) == :regular ->
+        with(
+          filename <- Path.basename(path),
+          shortcode <- Path.basename(filename, Path.extname(filename)),
+          false <- Emoji.exist?(shortcode)
+        ) do
+          acc ++ [%{path: path, filename: path, shortcode: shortcode}]
+        else
+          _ -> acc
+        end
+
+      _, acc ->
+        acc
+    end)
+  end
+
   @spec add_file(String.t(), String.t(), Path.t(), Plug.Upload.t()) ::
           {:ok, t()}
           | {:error, File.posix() | atom()}
   def add_file(%Pack{} = pack, _, _, %Plug.Upload{content_type: "application/zip"} = file) do
-    with {:ok, zip_items} <- :zip.table(to_charlist(file.path)) do
-      emojies =
-        for {_, path, s, _, _, _} <- zip_items, elem(s, 2) == :regular do
-          filename = Path.basename(path)
-          shortcode = Path.basename(filename, Path.extname(filename))
-
-          %{
-            path: path,
-            filename: path,
-            shortcode: shortcode,
-            exist: not is_nil(Pleroma.Emoji.get(shortcode))
-          }
-        end
-        |> Enum.group_by(& &1[:exist])
-
-      case Map.get(emojies, false, []) do
-        [_ | _] = new_emojies ->
-          {:ok, tmp_dir} = Pleroma.Utils.tmp_dir("emoji")
-
-          try do
-            {:ok, _emoji_files} =
-              :zip.unzip(
-                to_charlist(file.path),
-                [
-                  {:file_list, Enum.map(new_emojies, & &1[:path])},
-                  {:cwd, tmp_dir}
-                ]
+    with {:ok, zip_files} <- :zip.table(to_charlist(file.path)),
+         [_ | _] = emojies <- unpack_zip_emojies(zip_files),
+         {:ok, tmp_dir} <- Pleroma.Utils.tmp_dir("emoji") do
+      try do
+        {:ok, _emoji_files} =
+          :zip.unzip(
+            to_charlist(file.path),
+            [{:file_list, Enum.map(emojies, & &1[:path])}, {:cwd, tmp_dir}]
+          )
+
+        {_, updated_pack} =
+          Enum.map_reduce(emojies, pack, fn item, emoji_pack ->
+            emoji_file = %Plug.Upload{
+              filename: item[:filename],
+              path: Path.join(tmp_dir, item[:path])
+            }
+
+            {:ok, updated_pack} =
+              do_add_file(
+                emoji_pack,
+                item[:shortcode],
+                to_string(item[:filename]),
+                emoji_file
               )
 
-            {_, updated_pack} =
-              Enum.map_reduce(new_emojies, pack, fn item, emoji_pack ->
-                emoji_file = %Plug.Upload{
-                  filename: item[:filename],
-                  path: Path.join(tmp_dir, item[:path])
-                }
-
-                {:ok, updated_pack} =
-                  do_add_file(
-                    emoji_pack,
-                    item[:shortcode],
-                    to_string(item[:filename]),
-                    emoji_file
-                  )
-
-                {item, updated_pack}
-              end)
-
-            Emoji.reload()
-
-            {:ok, updated_pack}
-          after
-            File.rm_rf(tmp_dir)
-          end
+            {item, updated_pack}
+          end)
+
+        Emoji.reload()
 
-        _ ->
-          {:ok, pack}
+        {:ok, updated_pack}
+      after
+        File.rm_rf(tmp_dir)
       end
+    else
+      {:error, _} = error ->
+        error
+
+      _ ->
+        {:ok, pack}
     end
   end
 
-  def add_file(%Pack{} = pack, shortcode, filename, file) do
+  def add_file(%Pack{} = pack, shortcode, filename, %Plug.Upload{} = file) do
     with :ok <- validate_not_empty([shortcode, filename]),
          :ok <- validate_emoji_not_exists(shortcode),
          {:ok, updated_pack} <- do_add_file(pack, shortcode, filename, file) do
@@ -139,12 +141,10 @@ defmodule Pleroma.Emoji.Pack do
   end
 
   defp do_add_file(pack, shortcode, filename, file) do
-    with :ok <- save_file(file, pack, filename),
-         {:ok, updated_pack} <-
-           pack
-           |> put_emoji(shortcode, filename)
-           |> save_pack() do
-      {:ok, updated_pack}
+    with :ok <- save_file(file, pack, filename) do
+      pack
+      |> put_emoji(shortcode, filename)
+      |> save_pack()
     end
   end
 
@@ -312,9 +312,10 @@ defmodule Pleroma.Emoji.Pack do
   defp validate_emoji_not_exists(_shortcode, true), do: :ok
 
   defp validate_emoji_not_exists(shortcode, _) do
-    case Emoji.get(shortcode) do
-      nil -> :ok
-      _ -> {:error, :already_exists}
+    if Emoji.exist?(shortcode) do
+      {:error, :already_exists}
+    else
+      :ok
     end
   end
 
@@ -466,7 +467,7 @@ defmodule Pleroma.Emoji.Pack do
 
   defp put_emoji(pack, shortcode, filename) do
     files = Map.put(pack.files, shortcode, filename)
-    %{pack | files: files}
+    %{pack | files: files, files_count: length(Map.keys(files))}
   end
 
   defp delete_emoji(pack, shortcode) do
index fcb8c64c77cabe85fb6b4faeaae0920067e11fa4..e95766223d86e9965fbcfdc9f5595e98a5505461 100644 (file)
@@ -28,14 +28,16 @@ defmodule Pleroma.Utils do
   @doc "creates the uniq temporary directory"
   @spec tmp_dir(String.t()) :: {:ok, String.t()} | {:error, :file.posix()}
   def tmp_dir(prefix \\ "") do
-    sub_dir = [
-      prefix,
-      Timex.to_unix(Timex.now()),
-      :os.getpid(),
-      String.downcase(Integer.to_string(:rand.uniform(0x100000000), 36))
-    ]
+    sub_dir =
+      [
+        prefix,
+        Timex.to_unix(Timex.now()),
+        :os.getpid(),
+        String.downcase(Integer.to_string(:rand.uniform(0x100000000), 36))
+      ]
+      |> Enum.join("-")
 
-    tmp_dir = Path.join(System.tmp_dir!(), Enum.join(sub_dir, "-"))
+    tmp_dir = Path.join(System.tmp_dir!(), sub_dir)
 
     case File.mkdir(tmp_dir) do
       :ok -> {:ok, tmp_dir}
diff --git a/test/emoji/pack_test.exs b/test/emoji/pack_test.exs
new file mode 100644 (file)
index 0000000..3ec991f
--- /dev/null
@@ -0,0 +1,93 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Emoji.PackTest do
+  use ExUnit.Case, async: true
+  alias Pleroma.Emoji.Pack
+
+  @emoji_path Path.join(
+                Pleroma.Config.get!([:instance, :static_dir]),
+                "emoji"
+              )
+
+  setup do
+    pack_path = Path.join(@emoji_path, "dump_pack")
+    File.mkdir(pack_path)
+
+    File.write!(Path.join(pack_path, "pack.json"), """
+    {
+    "files": { },
+    "pack": {
+    "description": "Dump pack", "homepage": "https://pleroma.social",
+    "license": "Test license", "share-files": true
+    }}
+    """)
+
+    {:ok, pack} = Pleroma.Emoji.Pack.load_pack("dump_pack")
+
+    on_exit(fn ->
+      File.rm_rf!(pack_path)
+    end)
+
+    {:ok, pack: pack}
+  end
+
+  describe "add_file/4" do
+    test "add emojies from zip file", %{pack: pack} do
+      file = %Plug.Upload{
+        content_type: "application/zip",
+        filename: "finland-emojis.zip",
+        path: Path.absname("test/fixtures/finland-emojis.zip")
+      }
+
+      {:ok, updated_pack} = Pack.add_file(pack, nil, nil, file)
+
+      assert updated_pack.files == %{
+               "a_trusted_friend-128" => "128px/a_trusted_friend-128.png",
+               "auroraborealis" => "auroraborealis.png",
+               "baby_in_a_box" => "1000px/baby_in_a_box.png",
+               "bear" => "1000px/bear.png",
+               "bear-128" => "128px/bear-128.png"
+             }
+
+      assert updated_pack.files_count == 5
+    end
+  end
+
+  test "returns error when zip file is bad", %{pack: pack} do
+    file = %Plug.Upload{
+      content_type: "application/zip",
+      filename: "finland-emojis.zip",
+      path: Path.absname("test/instance_static/emoji/test_pack/blank.png")
+    }
+
+    assert Pack.add_file(pack, nil, nil, file) == {:error, :einval}
+  end
+
+  test "returns pack when zip file is empty", %{pack: pack} do
+    file = %Plug.Upload{
+      content_type: "application/zip",
+      filename: "finland-emojis.zip",
+      path: Path.absname("test/fixtures/empty.zip")
+    }
+
+    {:ok, updated_pack} = Pack.add_file(pack, nil, nil, file)
+    assert updated_pack == pack
+  end
+
+  test "add emoji file", %{pack: pack} do
+    file = %Plug.Upload{
+      filename: "blank.png",
+      path: "#{@emoji_path}/test_pack/blank.png"
+    }
+
+    {:ok, updated_pack} = Pack.add_file(pack, "test_blank", "test_blank.png", file)
+
+    assert updated_pack.files == %{
+             "test_blank" => "test_blank.png"
+           }
+
+    assert updated_pack.files_count == 1
+  end
+end
diff --git a/test/fixtures/empty.zip b/test/fixtures/empty.zip
new file mode 100644 (file)
index 0000000..15cb0ec
Binary files /dev/null and b/test/fixtures/empty.zip differ
diff --git a/test/utils_test.exs b/test/utils_test.exs
new file mode 100644 (file)
index 0000000..3a730d5
--- /dev/null
@@ -0,0 +1,15 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.UtilsTest do
+  use ExUnit.Case, async: true
+
+  describe "tmp_dir/1" do
+    test "returns unique temporary directory" do
+      {:ok, path} = Pleroma.Utils.tmp_dir("emoji")
+      assert path =~ ~r/\/tmp\/emoji-(.*)-#{:os.getpid()}-(.*)/
+      File.rm_rf(path)
+    end
+  end
+end