commit: c31fabdebddbd434a9fcff57cb36613f52ebc6a2
parent ee291f08e82eee596e5e8651a8bbcf7dad147dc7
Author: Lain Soykaf <lain@lain.com>
Date: Tue, 25 Feb 2025 17:08:21 +0400
Mogrify/Mogrifun: Asyncify
Diffstat:
9 files changed, 90 insertions(+), 40 deletions(-)
diff --git a/config/test.exs b/config/test.exs
@@ -162,6 +162,9 @@ config :pleroma, Pleroma.Web.Plugs.HTTPSignaturePlug, config_impl: Pleroma.Stati
config :pleroma, Pleroma.Upload.Filter.AnonymizeFilename,
config_impl: Pleroma.StaticStubbedConfigMock
+config :pleroma, Pleroma.Upload.Filter.Mogrify, config_impl: Pleroma.StaticStubbedConfigMock
+config :pleroma, Pleroma.Upload.Filter.Mogrify, mogrify_impl: Pleroma.MogrifyMock
+
config :pleroma, Pleroma.Signature, http_signatures_impl: Pleroma.StubbedHTTPSignaturesMock
peer_module =
diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex
@@ -27,6 +27,7 @@ defmodule Pleroma.Config do
Application.get_env(:pleroma, key, default)
end
+ @impl true
def get!(key) do
value = get(key, nil)
diff --git a/lib/pleroma/config/getting.ex b/lib/pleroma/config/getting.ex
@@ -5,10 +5,13 @@
defmodule Pleroma.Config.Getting do
@callback get(any()) :: any()
@callback get(any(), any()) :: any()
+ @callback get!(any()) :: any()
def get(key), do: get(key, nil)
def get(key, default), do: impl().get(key, default)
+ def get!(key), do: impl().get!(key)
+
def impl do
Application.get_env(:pleroma, :config_impl, Pleroma.Config)
end
diff --git a/lib/pleroma/mogrify.ex b/lib/pleroma/mogrify.ex
@@ -0,0 +1,42 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.MogrifyBehaviour do
+ @moduledoc """
+ Behaviour for Mogrify operations.
+ This module defines the interface for Mogrify operations that can be mocked in tests.
+ """
+
+ @callback open(binary()) :: map()
+ @callback custom(map(), binary()) :: map()
+ @callback custom(map(), binary(), binary()) :: map()
+ @callback save(map(), keyword()) :: map()
+end
+
+defmodule Pleroma.MogrifyWrapper do
+ @moduledoc """
+ Default implementation of MogrifyBehaviour that delegates to Mogrify.
+ """
+ @behaviour Pleroma.MogrifyBehaviour
+
+ @impl true
+ def open(file) do
+ Mogrify.open(file)
+ end
+
+ @impl true
+ def custom(image, action) do
+ Mogrify.custom(image, action)
+ end
+
+ @impl true
+ def custom(image, action, options) do
+ Mogrify.custom(image, action, options)
+ end
+
+ @impl true
+ def save(image, opts) do
+ Mogrify.save(image, opts)
+ end
+end
diff --git a/lib/pleroma/upload/filter/mogrify.ex b/lib/pleroma/upload/filter/mogrify.ex
@@ -8,9 +8,16 @@ defmodule Pleroma.Upload.Filter.Mogrify do
@type conversion :: action :: String.t() | {action :: String.t(), opts :: String.t()}
@type conversions :: conversion() | [conversion()]
+ @config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
+ @mogrify_impl Application.compile_env(
+ :pleroma,
+ [__MODULE__, :mogrify_impl],
+ Pleroma.MogrifyWrapper
+ )
+
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
try do
- do_filter(file, Pleroma.Config.get!([__MODULE__, :args]))
+ do_filter(file, @config_impl.get!([__MODULE__, :args]))
{:ok, :filtered}
rescue
e in ErlangError ->
@@ -22,9 +29,9 @@ defmodule Pleroma.Upload.Filter.Mogrify do
def do_filter(file, filters) do
file
- |> Mogrify.open()
+ |> @mogrify_impl.open()
|> mogrify_filter(filters)
- |> Mogrify.save(in_place: true)
+ |> @mogrify_impl.save(in_place: true)
end
defp mogrify_filter(mogrify, nil), do: mogrify
@@ -38,10 +45,10 @@ defmodule Pleroma.Upload.Filter.Mogrify do
defp mogrify_filter(mogrify, []), do: mogrify
defp mogrify_filter(mogrify, {action, options}) do
- Mogrify.custom(mogrify, action, options)
+ @mogrify_impl.custom(mogrify, action, options)
end
defp mogrify_filter(mogrify, action) when is_binary(action) do
- Mogrify.custom(mogrify, action)
+ @mogrify_impl.custom(mogrify, action)
end
end
diff --git a/test/pleroma/upload/filter/mogrifun_test.exs b/test/pleroma/upload/filter/mogrifun_test.exs
@@ -3,11 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Upload.Filter.MogrifunTest do
- use Pleroma.DataCase
- import Mock
+ use Pleroma.DataCase, async: true
+ import Mox
alias Pleroma.Upload
alias Pleroma.Upload.Filter
+ alias Pleroma.MogrifyMock
test "apply mogrify filter" do
File.cp!(
@@ -22,23 +23,12 @@ defmodule Pleroma.Upload.Filter.MogrifunTest do
tempfile: Path.absname("test/fixtures/image_tmp.jpg")
}
- task =
- Task.async(fn ->
- assert_receive {:apply_filter, {}}, 4_000
- end)
+ MogrifyMock
+ |> stub(:open, fn _file -> %{} end)
+ |> stub(:custom, fn _image, _action -> %{} end)
+ |> stub(:custom, fn _image, _action, _options -> %{} end)
+ |> stub(:save, fn _image, [in_place: true] -> :ok end)
- with_mocks([
- {Mogrify, [],
- [
- open: fn _f -> %Mogrify.Image{} end,
- custom: fn _m, _a -> send(task.pid, {:apply_filter, {}}) end,
- custom: fn _m, _a, _o -> send(task.pid, {:apply_filter, {}}) end,
- save: fn _f, _o -> :ok end
- ]}
- ]) do
- assert Filter.Mogrifun.filter(upload) == {:ok, :filtered}
- end
-
- Task.await(task)
+ assert Filter.Mogrifun.filter(upload) == {:ok, :filtered}
end
end
diff --git a/test/pleroma/upload/filter/mogrify_test.exs b/test/pleroma/upload/filter/mogrify_test.exs
@@ -3,13 +3,18 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Upload.Filter.MogrifyTest do
- use Pleroma.DataCase
- import Mock
+ use Pleroma.DataCase, async: true
+ import Mox
alias Pleroma.Upload.Filter
+ alias Pleroma.StaticStubbedConfigMock, as: ConfigMock
+ alias Pleroma.MogrifyMock
+
+ setup :verify_on_exit!
test "apply mogrify filter" do
- clear_config(Filter.Mogrify, args: [{"tint", "40"}])
+ ConfigMock
+ |> stub(:get!, fn [Filter.Mogrify, :args] -> [{"tint", "40"}] end)
File.cp!(
"test/fixtures/image.jpg",
@@ -23,19 +28,11 @@ defmodule Pleroma.Upload.Filter.MogrifyTest do
tempfile: Path.absname("test/fixtures/image_tmp.jpg")
}
- task =
- Task.async(fn ->
- assert_receive {:apply_filter, {_, "tint", "40"}}, 4_000
- end)
-
- with_mock Mogrify,
- open: fn _f -> %Mogrify.Image{} end,
- custom: fn _m, _a -> :ok end,
- custom: fn m, a, o -> send(task.pid, {:apply_filter, {m, a, o}}) end,
- save: fn _f, _o -> :ok end do
- assert Filter.Mogrify.filter(upload) == {:ok, :filtered}
- end
+ MogrifyMock
+ |> expect(:open, fn _file -> %{} end)
+ |> expect(:custom, fn _image, "tint", "40" -> %{} end)
+ |> expect(:save, fn _image, [in_place: true] -> :ok end)
- Task.await(task)
+ assert Filter.Mogrify.filter(upload) == {:ok, :filtered}
end
end
diff --git a/test/support/mocks.ex b/test/support/mocks.ex
@@ -35,3 +35,4 @@ Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)
Mox.defmock(Pleroma.Uploaders.S3.ExAwsMock, for: Pleroma.Uploaders.S3.ExAwsAPI)
Mox.defmock(Pleroma.DateTimeMock, for: Pleroma.DateTime)
+Mox.defmock(Pleroma.MogrifyMock, for: Pleroma.MogrifyBehaviour)
diff --git a/test/test_helper.exs b/test/test_helper.exs
@@ -34,7 +34,13 @@ defmodule Pleroma.Test.StaticConfig do
@behaviour Pleroma.Config.Getting
@config Application.get_all_env(:pleroma)
+ @impl true
def get(path, default \\ nil) do
get_in(@config, path) || default
end
+
+ @impl true
+ def get!(path) do
+ get_in(@config, path)
+ end
end