commit: 90a47ca050c5839e8b4dc3bac315dc436d49152d
parent 0e005acd44cd72e351f035b3268aec75ea00a496
Author: Lain Soykaf <lain@lain.com>
Date: Mon, 11 Dec 2023 09:25:05 +0400
S3 Test: Remove global state dependencies
Diffstat:
5 files changed, 81 insertions(+), 43 deletions(-)
diff --git a/config/test.exs b/config/test.exs
@@ -147,6 +147,9 @@ config :pleroma, Pleroma.PromEx, disabled: true
# Mox definitions. Only read during compile time.
config :pleroma, Pleroma.User.Backup, config_impl: Pleroma.UnstubbedConfigMock
+config :pleroma, Pleroma.Uploaders.S3, ex_aws_impl: Pleroma.Uploaders.S3.ExAwsMock
+config :pleroma, Pleroma.Uploaders.S3, config_impl: Pleroma.UnstubbedConfigMock
+config :pleroma, Pleroma.Upload, config_impl: Pleroma.UnstubbedConfigMock
if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs"
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
@@ -34,7 +34,6 @@ defmodule Pleroma.Upload do
"""
alias Ecto.UUID
- alias Pleroma.Config
alias Pleroma.Maps
alias Pleroma.Web.ActivityPub.Utils
require Logger
@@ -76,6 +75,8 @@ defmodule Pleroma.Upload do
:path
]
+ @config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
+
defp get_description(upload) do
case {upload.description, Pleroma.Config.get([Pleroma.Upload, :default_description])} do
{description, _} when is_binary(description) -> description
@@ -244,18 +245,18 @@ defmodule Pleroma.Upload do
defp url_from_spec(_upload, _base_url, {:url, url}), do: url
def base_url do
- uploader = Config.get([Pleroma.Upload, :uploader])
- upload_base_url = Config.get([Pleroma.Upload, :base_url])
- public_endpoint = Config.get([uploader, :public_endpoint])
+ uploader = @config_impl.get([Pleroma.Upload, :uploader])
+ upload_base_url = @config_impl.get([Pleroma.Upload, :base_url])
+ public_endpoint = @config_impl.get([uploader, :public_endpoint])
case uploader do
Pleroma.Uploaders.Local ->
upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"
Pleroma.Uploaders.S3 ->
- bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
- truncated_namespace = Config.get([Pleroma.Uploaders.S3, :truncated_namespace])
- namespace = Config.get([Pleroma.Uploaders.S3, :bucket_namespace])
+ bucket = @config_impl.get([Pleroma.Uploaders.S3, :bucket])
+ truncated_namespace = @config_impl.get([Pleroma.Uploaders.S3, :truncated_namespace])
+ namespace = @config_impl.get([Pleroma.Uploaders.S3, :bucket_namespace])
bucket_with_namespace =
cond do
diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex
@@ -6,7 +6,8 @@ defmodule Pleroma.Uploaders.S3 do
@behaviour Pleroma.Uploaders.Uploader
require Logger
- alias Pleroma.Config
+ @ex_aws_impl Application.compile_env(:pleroma, [__MODULE__, :ex_aws_impl], ExAws)
+ @config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
# The file name is re-encoded with S3's constraints here to comply with previous
# links with less strict filenames
@@ -22,7 +23,7 @@ defmodule Pleroma.Uploaders.S3 do
@impl true
def put_file(%Pleroma.Upload{} = upload) do
- config = Config.get([__MODULE__])
+ config = @config_impl.get([__MODULE__])
bucket = Keyword.get(config, :bucket)
streaming = Keyword.get(config, :streaming_enabled)
@@ -56,7 +57,7 @@ defmodule Pleroma.Uploaders.S3 do
])
end
- case ExAws.request(op) do
+ case @ex_aws_impl.request(op) do
{:ok, _} ->
{:ok, {:file, s3_name}}
@@ -69,9 +70,9 @@ defmodule Pleroma.Uploaders.S3 do
@impl true
def delete_file(file) do
[__MODULE__, :bucket]
- |> Config.get()
+ |> @config_impl.get()
|> ExAws.S3.delete_object(file)
- |> ExAws.request()
+ |> @ex_aws_impl.request()
|> case do
{:ok, %{status_code: 204}} -> :ok
error -> {:error, inspect(error)}
@@ -83,3 +84,7 @@ defmodule Pleroma.Uploaders.S3 do
String.replace(name, @regex, "-")
end
end
+
+defmodule Pleroma.Uploaders.S3.ExAwsAPI do
+ @callback request(op :: ExAws.Operation.t()) :: {:ok, ExAws.Operation.t()} | {:error, term()}
+end
diff --git a/test/pleroma/uploaders/s3_test.exs b/test/pleroma/uploaders/s3_test.exs
@@ -3,22 +3,27 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Uploaders.S3Test do
- use Pleroma.DataCase
+ use Pleroma.DataCase, async: true
alias Pleroma.Uploaders.S3
+ alias Pleroma.Uploaders.S3.ExAwsMock
+ alias Pleroma.UnstubbedConfigMock, as: ConfigMock
- import Mock
+ import Mox
import ExUnit.CaptureLog
- setup do
- clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.S3)
- clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
- clear_config([Pleroma.Uploaders.S3])
- clear_config([Pleroma.Uploaders.S3, :bucket], "test_bucket")
- end
-
describe "get_file/1" do
- test "it returns path to local folder for files" do
+ test "it returns url for files" do
+ ConfigMock
+ |> expect(:get, 6, fn key ->
+ [
+ {Pleroma.Upload,
+ [uploader: Pleroma.Uploaders.S3, base_url: "https://s3.amazonaws.com"]},
+ {Pleroma.Uploaders.S3, [bucket: "test_bucket"]}
+ ]
+ |> get_in(key)
+ end)
+
assert S3.get_file("test_image.jpg") == {
:ok,
{:url, "https://s3.amazonaws.com/test_bucket/test_image.jpg"}
@@ -26,13 +31,16 @@ defmodule Pleroma.Uploaders.S3Test do
end
test "it returns path without bucket when truncated_namespace set to ''" do
- clear_config([Pleroma.Uploaders.S3],
- bucket: "test_bucket",
- bucket_namespace: "myaccount",
- truncated_namespace: ""
- )
-
- clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
+ ConfigMock
+ |> expect(:get, 6, fn key ->
+ [
+ {Pleroma.Upload,
+ [uploader: Pleroma.Uploaders.S3, base_url: "https://s3.amazonaws.com"]},
+ {Pleroma.Uploaders.S3,
+ [bucket: "test_bucket", truncated_namespace: "", bucket_namespace: "myaccount"]}
+ ]
+ |> get_in(key)
+ end)
assert S3.get_file("test_image.jpg") == {
:ok,
@@ -41,10 +49,15 @@ defmodule Pleroma.Uploaders.S3Test do
end
test "it returns path with bucket namespace when namespace is set" do
- clear_config([Pleroma.Uploaders.S3],
- bucket: "test_bucket",
- bucket_namespace: "family"
- )
+ ConfigMock
+ |> expect(:get, 6, fn key ->
+ [
+ {Pleroma.Upload,
+ [uploader: Pleroma.Uploaders.S3, base_url: "https://s3.amazonaws.com"]},
+ {Pleroma.Uploaders.S3, [bucket: "test_bucket", bucket_namespace: "family"]}
+ ]
+ |> get_in(key)
+ end)
assert S3.get_file("test_image.jpg") == {
:ok,
@@ -62,28 +75,42 @@ defmodule Pleroma.Uploaders.S3Test do
tempfile: Path.absname("test/instance_static/add/shortcode.png")
}
+ ConfigMock
+ |> expect(:get, fn [Pleroma.Uploaders.S3] ->
+ [
+ bucket: "test_bucket"
+ ]
+ end)
+
[file_upload: file_upload]
end
test "save file", %{file_upload: file_upload} do
- with_mock ExAws, request: fn _ -> {:ok, :ok} end do
- assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}}
- end
+ ExAwsMock
+ |> expect(:request, fn _req -> {:ok, %{status_code: 200}} end)
+
+ assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}}
end
test "returns error", %{file_upload: file_upload} do
- with_mock ExAws, request: fn _ -> {:error, "S3 Upload failed"} end do
- assert capture_log(fn ->
- assert S3.put_file(file_upload) == {:error, "S3 Upload failed"}
- end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}"
- end
+ ExAwsMock
+ |> expect(:request, fn _req -> {:error, "S3 Upload failed"} end)
+
+ assert capture_log(fn ->
+ assert S3.put_file(file_upload) == {:error, "S3 Upload failed"}
+ end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}"
end
end
describe "delete_file/1" do
- test_with_mock "deletes file", ExAws, request: fn _req -> {:ok, %{status_code: 204}} end do
+ test "deletes file" do
+ ExAwsMock
+ |> expect(:request, fn _req -> {:ok, %{status_code: 204}} end)
+
+ ConfigMock
+ |> expect(:get, fn [Pleroma.Uploaders.S3, :bucket] -> "test_bucket" end)
+
assert :ok = S3.delete_file("image.jpg")
- assert_called(ExAws.request(:_))
end
end
end
diff --git a/test/support/mocks.ex b/test/support/mocks.ex
@@ -31,3 +31,5 @@ Mox.defmock(Pleroma.UnstubbedConfigMock, for: Pleroma.Config.Getting)
Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)
Mox.defmock(Pleroma.User.Backup.ProcessorMock, for: Pleroma.User.Backup.ProcessorAPI)
+
+Mox.defmock(Pleroma.Uploaders.S3.ExAwsMock, for: Pleroma.Uploaders.S3.ExAwsAPI)