Repository: swoosh/swoosh
Pull request #834 (2023-11-24 12:57:02)

Do not send subject to customer.io when empty
Customer.io transactional emails can have subjects defined in the template, and if the subject is empty they won't deliver the email.

This PR changes the code so that, if the subject is an empty string, it won't set it in the request to customer.io. Previously it would only check if subject is `nil`, but that's not supported by swoosh's API (I still left the `nil` implementation in case someone managed to use it).

Also added a test checking that we're not sending empty `from` values, as those can also be populated by customer.io

caioaao: Oh, forgot to mention: another approach would be to allow `subject` to be `nil`, but I didn't want to change swoosh's core API to support this

Patch:
diff --git a/lib/swoosh/adapters/customer_io.ex b/lib/swoosh/adapters/customer_io.ex
index 36eb91c..b163768 100644
--- a/lib/swoosh/adapters/customer_io.ex
+++ b/lib/swoosh/adapters/customer_io.ex
@@ -179,6 +179,7 @@ defmodule Swoosh.Adapters.CustomerIO do
     do: Map.put(body, :reply_to, render_recipient(reply_to))
 
   defp prepare_subject(body, %Email{subject: nil}), do: body
+  defp prepare_subject(body, %Email{subject: ""}), do: body
   defp prepare_subject(body, %Email{subject: subject}), do: Map.put(body, :subject, subject)
 
   defp prepare_content(body, %Email{html_body: nil, text_body: nil}), do: body


Test patch:
diff --git a/test/swoosh/adapters/customer_io_test.exs b/test/swoosh/adapters/customer_io_test.exs
index 7e73ad8..b1b254e 100644
--- a/test/swoosh/adapters/customer_io_test.exs
+++ b/test/swoosh/adapters/customer_io_test.exs
@@ -343,4 +343,62 @@ defmodule Swoosh.Adapters.CustomerIOTest do
 
     assert CustomerIO.deliver(email, config) == {:ok, %{id: "123-xyz"}}
   end
+
+  test "deliver/1 without subject", %{bypass: bypass, config: config} do
+    email =
+      new()
+      |> from("tony.stark@example.com")
+      |> to("steve.rogers@example.com")
+      |> html_body("<h1>Hello</h1>")
+      |> text_body("Hello")
+
+    Bypass.expect(bypass, fn conn ->
+      conn = parse(conn)
+
+      body_params = %{
+        "from" => "tony.stark@example.com",
+        "to" => "steve.rogers@example.com",
+        "body" => "<h1>Hello</h1>",
+        "plaintext_body" => "Hello"
+      }
+
+      assert ^body_params = conn.body_params
+      assert "subject" not in body_params
+      assert "/send/email" == conn.request_path
+      assert "POST" == conn.method
+
+      Plug.Conn.resp(conn, 200, "{\"delivery_id\": \"123-xyz\"}")
+    end)
+
+    assert CustomerIO.deliver(email, config) == {:ok, %{id: "123-xyz"}}
+  end
+
+  test "deliver/1 without sender", %{bypass: bypass, config: config} do
+    email =
+      new()
+      |> to("steve.rogers@example.com")
+      |> subject("Hello, Avengers!")
+      |> html_body("<h1>Hello</h1>")
+      |> text_body("Hello")
+
+    Bypass.expect(bypass, fn conn ->
+      conn = parse(conn)
+
+      body_params = %{
+        "to" => "steve.rogers@example.com",
+        "subject" => "Hello, Avengers!",
+        "body" => "<h1>Hello</h1>",
+        "plaintext_body" => "Hello"
+      }
+
+      assert ^body_params = conn.body_params
+      assert "from" not in body_params
+      assert "/send/email" == conn.request_path
+      assert "POST" == conn.method
+
+      Plug.Conn.resp(conn, 200, "{\"delivery_id\": \"123-xyz\"}")
+    end)
+
+    assert CustomerIO.deliver(email, config) == {:ok, %{id: "123-xyz"}}
+  end
 end