From 49fce9929782356e11d086871b54b4b0e23bc219 Mon Sep 17 00:00:00 2001 From: David Runger Date: Wed, 4 Sep 2024 06:08:50 -0500 Subject: [PATCH] Update method name in HaveEnqueuedMail (job_match? to job_matches?) This change fixes a bug wherein a spec that expects no mail to have been enqueued will fail (falsely claiming that a mail _was_ enqueued) if any _non-mail_ job is enqueued, even if indeed no _mail_ job is actually enqueued. This bug was introduced in ab6e6e83 / #2780 , which was first included in the 7.0.0 release. In that change, the `RSpec::Rails::Matchers::ActiveJob::Base` `job_match?` instance method was renamed to `job_matches?`. The problem is that `RSpec::Rails::Matchers::HaveEnqueuedMail`, which inherits from `RSpec::Rails::Matchers::ActiveJob::Base` (via `RSpec::Rails::Matchers::ActiveJob::HaveEnqueuedJob`), intends to override that method, which it does by defining its own `job_match?` instance method. However, because this `job_match?` method name is no longer the same as the (now so called) `job_matches?` method that it intends to override, the `job_match?` method of `RSpec::Rails::Matchers::HaveEnqueuedMail` is no longer having the intended override effect on the behavior of the matcher, producing the aforementioned bug. This change resolves the issue by updating the method name in the `RSpec::Rails::Matchers::HaveEnqueuedMail` subclass from `job_match?` to `job_matches?`, reflecting that renaming that was done in the parent class in ab6e6e83 . --- Changelog.md | 5 +++++ lib/rspec/rails/matchers/have_enqueued_mail.rb | 4 ++-- .../rails/matchers/have_enqueued_mail_spec.rb | 15 +++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index b901ab3b0..e319f865d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,11 @@ ### Development [Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.0.1...main) +Bug Fixes: + +* Fix `have_enqueued_mail` wrongful failure when expecting no enqueued mail but + a non-mail job is enqueued. (David Runger, #2793) + ### 7.0.1 / 2024-09-03 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.0.0...v7.0.1) diff --git a/lib/rspec/rails/matchers/have_enqueued_mail.rb b/lib/rspec/rails/matchers/have_enqueued_mail.rb index 9d2c405b3..85aaea274 100644 --- a/lib/rspec/rails/matchers/have_enqueued_mail.rb +++ b/lib/rspec/rails/matchers/have_enqueued_mail.rb @@ -72,7 +72,7 @@ def mailer_class_name @mailer_class ? @mailer_class.name : 'ActionMailer::Base' end - def job_match?(job) + def job_matches?(job) legacy_mail?(job) || parameterized_mail?(job) || unified_mail?(job) end @@ -123,7 +123,7 @@ def check_active_job_adapter def unmatching_mail_jobs @unmatching_jobs.select do |job| - job_match?(job) + job_matches?(job) end end diff --git a/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb b/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb index 0503080ba..14b886189 100644 --- a/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb +++ b/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb @@ -20,6 +20,10 @@ class AnotherTestMailer < ActionMailer::Base def test_email; end end + class NonMailerJob < ActiveJob::Base + def perform; end + end + if RSpec::Rails::FeatureCheck.has_action_mailer_unified_delivery? class UnifiedMailer < ActionMailer::Base self.delivery_job = ActionMailer::MailDeliveryJob @@ -95,6 +99,10 @@ def test_email; end expect { }.not_to have_enqueued_email end + it "passes when negated with 0 arguments and a non-mailer job is enqueued" do + expect { NonMailerJob.perform_later }.not_to have_enqueued_email + end + it "passes when only given mailer argument" do expect { TestMailer.test_email.deliver_later @@ -305,11 +313,6 @@ def test_email; end end it "generates a failure message with unmatching enqueued mail jobs" do - non_mailer_job = Class.new(ActiveJob::Base) do - def perform; end - def self.name; "NonMailerJob"; end - end - send_time = Date.tomorrow.noon queue = 'urgent_mail' @@ -320,7 +323,7 @@ def self.name; "NonMailerJob"; end expect { expect { - non_mailer_job.perform_later + NonMailerJob.perform_later TestMailer.test_email.deliver_later TestMailer.email_with_args(3, 4).deliver_later(wait_until: send_time, queue: queue) }.to have_enqueued_email(TestMailer, :email_with_args).with(1, 2)