Remove faker, floki, igniter, ecto_psql_extras (zero usages), exvcr (zero usages), and resend. Replace resend with Aprsme.Swoosh.ResendAdapter using the already-present req dependency. Frees 23 packages total from the lockfile including hackney, certifi, and the tesla dependency chain. Fix two pre-existing test isolation bugs: - signal_handler_test called the real ShutdownHandler.shutdown() via SIGTERM simulation without restoring state, causing page_controller_test to see shutting_down: true and return 503 - page_controller_test setup now resets ShutdownHandler state defensively
132 lines
4 KiB
Elixir
132 lines
4 KiB
Elixir
defmodule Aprsme.Swoosh.ResendAdapterTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Aprsme.Swoosh.ResendAdapter
|
|
alias Swoosh.Email
|
|
|
|
defp stub_config(plug_name) do
|
|
[api_key: "re_test_key", plug: {Req.Test, plug_name}]
|
|
end
|
|
|
|
defp new_email(opts \\ []) do
|
|
defaults = [
|
|
from: {"Sender Name", "sender@example.com"},
|
|
to: [{"Recipient", "recipient@example.com"}],
|
|
subject: "Test Subject",
|
|
html_body: "<p>Hello</p>",
|
|
text_body: "Hello"
|
|
]
|
|
|
|
Email.new(Keyword.merge(defaults, opts))
|
|
end
|
|
|
|
describe "deliver/2" do
|
|
test "posts to Resend API and returns id on success" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
Req.Test.json(conn, %{"id" => "msg_abc123"})
|
|
end)
|
|
|
|
email = new_email()
|
|
|
|
assert {:ok, %{id: "msg_abc123"}} = ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
end
|
|
|
|
test "returns error on API error response" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
conn
|
|
|> Plug.Conn.put_status(422)
|
|
|> Req.Test.json(%{"name" => "validation_error", "message" => "Invalid email"})
|
|
end)
|
|
|
|
email = new_email()
|
|
|
|
assert {:error, {"validation_error", "Invalid email"}} =
|
|
ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
end
|
|
|
|
test "returns error on network failure" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
Req.Test.transport_error(conn, :econnrefused)
|
|
end)
|
|
|
|
email = new_email()
|
|
|
|
assert {:error, %Req.TransportError{reason: :econnrefused}} =
|
|
ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
end
|
|
|
|
test "formats named sender as 'Name <email>'" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
{:ok, body, conn} = Plug.Conn.read_body(conn)
|
|
decoded = Jason.decode!(body)
|
|
send(self(), {:request_body, decoded})
|
|
Req.Test.json(conn, %{"id" => "msg_1"})
|
|
end)
|
|
|
|
email = new_email(from: {"My App", "noreply@example.com"})
|
|
ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
|
|
assert_received {:request_body, body}
|
|
assert body["from"] == "My App <noreply@example.com>"
|
|
end
|
|
|
|
test "formats bare email sender without name prefix" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
{:ok, body, conn} = Plug.Conn.read_body(conn)
|
|
decoded = Jason.decode!(body)
|
|
send(self(), {:request_body, decoded})
|
|
Req.Test.json(conn, %{"id" => "msg_1"})
|
|
end)
|
|
|
|
email = new_email(from: {"", "noreply@example.com"})
|
|
ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
|
|
assert_received {:request_body, body}
|
|
assert body["from"] == "noreply@example.com"
|
|
end
|
|
|
|
test "formats list of recipients as list of email strings" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
{:ok, body, conn} = Plug.Conn.read_body(conn)
|
|
decoded = Jason.decode!(body)
|
|
send(self(), {:request_body, decoded})
|
|
Req.Test.json(conn, %{"id" => "msg_1"})
|
|
end)
|
|
|
|
email =
|
|
new_email(to: [{"Alice", "alice@example.com"}, {"Bob", "bob@example.com"}])
|
|
|
|
ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
|
|
assert_received {:request_body, body}
|
|
assert body["to"] == ["alice@example.com", "bob@example.com"]
|
|
end
|
|
|
|
test "omits nil fields from request body" do
|
|
Req.Test.stub(__MODULE__, fn conn ->
|
|
{:ok, body, conn} = Plug.Conn.read_body(conn)
|
|
decoded = Jason.decode!(body)
|
|
send(self(), {:request_body, decoded})
|
|
Req.Test.json(conn, %{"id" => "msg_1"})
|
|
end)
|
|
|
|
email = new_email()
|
|
ResendAdapter.deliver(email, stub_config(__MODULE__))
|
|
|
|
assert_received {:request_body, body}
|
|
refute Map.has_key?(body, "cc")
|
|
refute Map.has_key?(body, "bcc")
|
|
refute Map.has_key?(body, "reply_to")
|
|
end
|
|
end
|
|
|
|
describe "validate_config/1" do
|
|
test "returns :ok when api_key is present" do
|
|
assert :ok = ResendAdapter.validate_config(api_key: "re_abc")
|
|
end
|
|
|
|
test "returns error when api_key is missing" do
|
|
assert {:error, _reason} = ResendAdapter.validate_config([])
|
|
end
|
|
end
|
|
end
|