# The following module is taken from this issue # https://github.com/swoosh/swoosh/issues/488#issuecomment-1671224765 defmodule Mobilizon.Tests.SwooshAssertions do @moduledoc ~S""" Assertions for emails. The assertions provided by this module work by pattern matching against all emails received by the test process against the `Swoosh.Email` struct. For example: assert_email_sent %{subject: "You got a message"} If you want to be additionally explicit, you might: assert_email_sent %Swoosh.Email{subject: "You got a message"} If emails are being sent concurrently, you can use `assert_email_sending/2`: assert_email_sending %{subject: "You got a message"} Both functions will return the matched email if the assertion succeeds. You can then perform further matches on it: email = assert_email_sent %Swoosh.Email{subject: "You got a message"} assert email.from == {"MyApp", "no-reply@example.com"} Using pattern matching imposes two limitations. The first one is that you must match precisely the Swoosh.Email structure. For example, the following will not work: assert_email_sent %{to: "foobar@example.com"} That's because `Swoosh.Email` keeps the field as a list. This will work: assert_email_sent %{to: [{"FooBar", "foobar@example.com"}]} You are also not allowed to have interpolations. For example, the following will not work: assert_email_sent %{ subject: "You have been invited to #{org.name}", to: [{user.name, user.email}] } However, you can rely on pattern matching and rewrite it as: email = assert_email_sent %{subject: "You have been invited to " <> org_name} assert org_name == org.name assert email.to == [{user.name, user.email}] """ @doc """ Matches an email has been sent. See moduledoc for more information. """ defmacro assert_email_sent(pattern) do quote do {:email, email} = assert_received({:email, unquote(pattern)}) email end end @doc """ Matches an email is sending (within a timeout). See moduledoc for more information. """ defmacro assert_email_sending( pattern, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout) ) do quote do {:email, email} = assert_receive({:email, unquote(pattern)}, unquote(timeout)) email end end @doc """ Refutes an email matching pattern has been sent. The opposite of `assert_email_sent`. """ defmacro refute_email_sent(pattern) do quote do refute_received({:email, unquote(pattern)}) end end end