Skip to content

Commit 53fefbd

Browse files
odlpJonRowe
authored andcommitted
Verify arguments match mailer in HaveEnqueuedMail
Guards against false-positives where both the implementation and have_enqueued_mail matchers are passed the wrong arguments which don't match the mailer's signature.
1 parent 442bc62 commit 53fefbd

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

lib/rspec/rails/matchers/have_enqueued_mail.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,19 @@ def arguments_match?(job)
8989
super(job)
9090
end
9191

92-
def verify_arguments_match_signature!(_job, _args)
93-
# Not implemented for mailers
92+
def verify_arguments_match_signature!(job, args)
93+
return if @method_name.nil?
94+
95+
mailer_method = mailer_class_name.constantize.public_instance_method(@method_name)
96+
mailer_args = args - base_mailer_args
97+
98+
if parameterized_mail?(job)
99+
mailer_args = mailer_args[1..-1] # ignore parameterized params
100+
elsif mailer_args.last.is_a?(Hash) && mailer_args.last.key?(:args)
101+
mailer_args = args.last[:args]
102+
end
103+
104+
verify_signature!(mailer_method, mailer_args)
94105
end
95106

96107
def base_mailer_args

spec/rspec/rails/matchers/have_enqueued_mail_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@ def test_email; end
243243
}.not_to have_enqueued_mail(TestMailer, :email_with_args).with(3, 4)
244244
end
245245

246+
it "fails if the arguments do not match the mailer method's signature" do
247+
expect {
248+
expect {
249+
TestMailer.email_with_args(1).deliver_later
250+
}.to have_enqueued_mail(TestMailer, :email_with_args).with(1)
251+
}.to raise_error(ArgumentError, /Wrong number of arguments/)
252+
end
253+
246254
it "generates a failure message" do
247255
expect {
248256
expect { }.to have_enqueued_email(TestMailer, :test_email)
@@ -388,6 +396,14 @@ def self.name; "NonMailerJob"; end
388396
TestMailer.with('foo' => 'bar').email_with_args(1, 2).deliver_later
389397
}.to have_enqueued_mail(TestMailer, :email_with_args).with({ 'foo' => 'bar' }, 1, 2)
390398
end
399+
400+
it "fails if the arguments do not match the mailer method's signature" do
401+
expect {
402+
expect {
403+
TestMailer.with('foo' => 'bar').email_with_args(1).deliver_later
404+
}.to have_enqueued_mail(TestMailer, :email_with_args).with({ 'foo' => 'bar' }, 1)
405+
}.to raise_error(ArgumentError, /Wrong number of arguments/)
406+
end
391407
end
392408

393409
context 'mailer job is unified', skip: !RSpec::Rails::FeatureCheck.has_action_mailer_unified_delivery? do
@@ -435,6 +451,16 @@ def self.name; "NonMailerJob"; end
435451
UnifiedMailerWithDeliveryJobSubClass.test_email.deliver_later
436452
}.to have_enqueued_mail(UnifiedMailerWithDeliveryJobSubClass, :test_email)
437453
end
454+
455+
it "fails if the arguments do not match the mailer method's signature" do
456+
expect {
457+
expect {
458+
UnifiedMailer.with('foo' => 'bar').email_with_args(1).deliver_later
459+
}.to have_enqueued_mail(UnifiedMailer, :email_with_args).with(
460+
a_hash_including(params: { 'foo' => 'bar' }, args: [1])
461+
)
462+
}.to raise_error(ArgumentError, /Wrong number of arguments/)
463+
end
438464
end
439465
end
440466
end

0 commit comments

Comments
 (0)