Skip to content

Commit

Permalink
Use refute_timeout configured for all refute_ assertions
Browse files Browse the repository at this point in the history
What changed?
============

All refutation test helpers in `Bamboo.Test` should be using the
`refute_timeout` configuration when testing on shared mode.

```elixir
config :bamboo, :refute_timeout, 10
```

The `refute_email_delivered_with/1` macro was not using the
configuration, but instead it has 100ms hardcoded. This was a bug, since
the original implementation should have used it.

Known potential issue
----------------------

Since the previous waiting time was 100ms, and the `refute_timeout/0`
function returns 0ms when not using shared mode, then it's possible some
people could experience false positives in their tests (they think the
email isn't received, so test passes. But 10ms later it arrives in the
mailbox. Before, they were waiting 100ms, so they would have caught the
error.)
  • Loading branch information
germsvel committed May 21, 2021
1 parent b82a1ec commit 427c795
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions lib/bamboo/test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,28 @@ defmodule Bamboo.Test do
@doc """
Check that no email was sent with the given parameters
Similarly to `assert_email_delivered_with`, the assertion waits up to 100ms before
failing. Note that you need to send the email again if you want to make other
assertions after this, as this will receive the `{:delivered_email, email}` message.
Similar to `assert_email_delivered_with/1`, but it checks that an email with
those parameters wasn't sent.
If `Bamboo.Test` is used with shared mode, you must also configure a timeout
in your test config.
# Set this in your config, typically in config/test.exs
config :bamboo, :refute_timeout, 10
The value you set is up to you. Lower values may result in faster tests, but
your tests may incorrectly pass if an email is delivered *after* the timeout.
Note that this assertion helper will grab the email out of the process
mailbox. So if you want to make other assertions about the same email after
this assertion, you need to send the email again.
## Examples
Bamboo.Email.new_email(subject: "something") |> MyApp.Mailer.deliver
refute_email_delivered_with(subject: "something else") # Will pass
email = Bamboo.Email.new_email(subject: "something") |> MyApp.Mailer.deliver
Bamboo.Email.new_email(subject: "something") |> MyApp.Mailer.deliver
refute_email_delivered_with(subject: ~r/some/) # Will fail
"""
defmacro refute_email_delivered_with(email_params) do
Expand All @@ -255,7 +267,7 @@ defmodule Bamboo.Test do
receive do
{:delivered_email, email} -> Map.from_struct(email)
after
100 -> []
Bamboo.Test.refute_timeout() -> []
end

if is_nil(received_email_params) do
Expand Down Expand Up @@ -435,7 +447,8 @@ defmodule Bamboo.Test do
""")
end

defp refute_timeout do
@doc false
def refute_timeout do
if using_shared_mode?() do
Application.get_env(:bamboo, :refute_timeout) ||
raise """
Expand Down

0 comments on commit 427c795

Please sign in to comment.