Skip to content

Commit b3da3ee

Browse files
committed
allow partial args when using have_enqueued_mail
this provide parity with have_enqueued_job with partial arguments which would be useful especially in negated case where we want to make sure that absolutely no emails are enqueued
1 parent e6fe572 commit b3da3ee

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

lib/rspec/rails/matchers/have_enqueued_mail.rb

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def initialize(mailer_class, method_name)
2323
end
2424

2525
def description
26-
"enqueues #{@mailer_class.name}.#{@method_name}"
26+
"enqueues #{mailer_class_name}.#{@method_name}"
2727
end
2828

2929
def with(*args, &block)
@@ -50,7 +50,7 @@ def failure_message_when_negated
5050
private
5151

5252
def base_message
53-
"#{@mailer_class.name}.#{@method_name}".tap do |msg|
53+
[mailer_class_name, @method_name].compact.join('.').tap do |msg|
5454
msg << " #{expected_count_message}"
5555
msg << " with #{@mail_args}," if @mail_args.any?
5656
msg << " on queue #{@queue}," if @queue
@@ -63,10 +63,14 @@ def expected_count_message
6363
"#{message_expectation_modifier} #{@expected_number} #{@expected_number == 1 ? 'time' : 'times'}"
6464
end
6565

66+
def mailer_class_name
67+
@mailer_class ? @mailer_class.name : 'ActionMailer::Base'
68+
end
69+
6670
def mailer_args
6771
if @mail_args.any?
6872
base_mailer_args + @mail_args
69-
else
73+
elsif @mailer_class && @method_name
7074
mailer_method_arity = @mailer_class.instance_method(@method_name).arity
7175

7276
number_of_args = if mailer_method_arity < 0
@@ -76,11 +80,15 @@ def mailer_args
7680
end
7781

7882
base_mailer_args + Array.new(number_of_args) { anything }
83+
elsif @mailer_class
84+
[mailer_class_name, any_args]
85+
else
86+
[]
7987
end
8088
end
8189

8290
def base_mailer_args
83-
[@mailer_class.name, @method_name.to_s, MAILER_JOB_METHOD]
91+
[mailer_class_name, @method_name.to_s, MAILER_JOB_METHOD]
8492
end
8593

8694
def yield_mail_args(block)
@@ -136,6 +144,14 @@ def mailer_job
136144
# @example
137145
# expect {
138146
# MyMailer.welcome(user).deliver_later
147+
# }.to have_enqueued_mail
148+
#
149+
# expect {
150+
# MyMailer.welcome(user).deliver_later
151+
# }.to have_enqueued_mail(MyMailer)
152+
#
153+
# expect {
154+
# MyMailer.welcome(user).deliver_later
139155
# }.to have_enqueued_mail(MyMailer, :welcome)
140156
#
141157
# # Using alias
@@ -163,7 +179,7 @@ def mailer_job
163179
# expect {
164180
# MyMailer.welcome(user).deliver_later(queue: :urgent_mail)
165181
# }.to have_enqueued_mail(MyMailer, :welcome).on_queue(:urgent_mail)
166-
def have_enqueued_mail(mailer_class, mail_method_name)
182+
def have_enqueued_mail(mailer_class = nil, mail_method_name = nil)
167183
HaveEnqueuedMail.new(mailer_class, mail_method_name)
168184
end
169185
alias_method :have_enqueued_email, :have_enqueued_mail

spec/rspec/rails/matchers/have_enqueued_mail_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ def test_email; end
1010
def email_with_args(arg1, arg2); end
1111
def email_with_optional_args(required_arg, optional_arg = nil); end
1212
end
13+
14+
class AnotherTestMailer < ActionMailer::Base
15+
def test_email; end
16+
end
1317
end
1418

1519
RSpec.describe "HaveEnqueuedMail matchers", :skip => !RSpec::Rails::FeatureCheck.has_active_job? do
@@ -53,6 +57,34 @@ def email_with_optional_args(required_arg, optional_arg = nil); end
5357
expect { }.not_to have_enqueued_mail(TestMailer, :test_email)
5458
end
5559

60+
it "passes when given 0 arguments" do
61+
expect {
62+
TestMailer.test_email.deliver_later
63+
}.to have_enqueued_email
64+
end
65+
66+
it "passes when negated with 0 arguments" do
67+
expect { }.not_to have_enqueued_email
68+
end
69+
70+
it "passes when only given mailer argument" do
71+
expect {
72+
TestMailer.test_email.deliver_later
73+
}.to have_enqueued_email(TestMailer)
74+
end
75+
76+
it "passes when negated with only mailer arguments" do
77+
expect { }.not_to have_enqueued_email(TestMailer)
78+
end
79+
80+
it "ensure that the right mailer is enqueued" do
81+
expect {
82+
expect {
83+
AnotherTestMailer.test_email.deliver_later
84+
}.to have_enqueued_mail(TestMailer)
85+
}.to raise_error(/expected to enqueue TestMailer exactly 1 time but enqueued 0/)
86+
end
87+
5688
it "counts only emails enqueued in the block" do
5789
TestMailer.test_email.deliver_later
5890

@@ -126,6 +158,18 @@ def email_with_optional_args(required_arg, optional_arg = nil); end
126158
}.to have_enqueued_mail(TestMailer, :test_email).at_most(:twice)
127159
end
128160

161+
it "generates a failure message when given 0 argument" do
162+
expect {
163+
expect { }.to have_enqueued_mail.at_least(:once)
164+
}.to raise_error(/expected to enqueue ActionMailer::Base at least 1 time but enqueued 0/)
165+
end
166+
167+
it "generates a failure message when given only mailer argument" do
168+
expect {
169+
expect { }.to have_enqueued_mail(TestMailer).at_least(:once)
170+
}.to raise_error(/expected to enqueue TestMailer at least 1 time but enqueued 0/)
171+
end
172+
129173
it "generates a failure message with at least hint" do
130174
expect {
131175
expect { }.to have_enqueued_mail(TestMailer, :test_email).at_least(:once)

0 commit comments

Comments
 (0)