Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for parameterized mailer when RAILS_VERSION > 5.1 #2121

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/rspec/rails/feature_check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ def has_action_mailer_show_preview?
::ActionMailer::Base.respond_to?(:show_previews=)
end

def has_action_mailer_parameterized?
has_action_mailer? && defined?(::ActionMailer::Parameterized)
end

def has_action_mailbox?
defined?(::ActionMailbox)
end
Expand Down
7 changes: 5 additions & 2 deletions lib/rspec/rails/matchers/active_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def supports_block_expectations?

def check(jobs)
@matching_jobs, @unmatching_jobs = jobs.partition do |job|
if arguments_match?(job) && other_attributes_match?(job)
if job_match?(job) && arguments_match?(job) && other_attributes_match?(job)
args = deserialize_arguments(job)
@block.call(*args)
true
Expand Down Expand Up @@ -134,6 +134,10 @@ def base_job_message(job)
end
end

def job_match?(job)
@job ? @job == job[:job] : true
benoittgt marked this conversation as resolved.
Show resolved Hide resolved
end

def arguments_match?(job)
if @args.any?
deserialized_args = deserialize_arguments(job)
Expand All @@ -151,7 +155,6 @@ def serialized_attributes
{}.tap do |attributes|
attributes[:at] = serialized_at if @at
attributes[:queue] = @queue if @queue
attributes[:job] = @job if @job
end
end

Expand Down
25 changes: 20 additions & 5 deletions lib/rspec/rails/matchers/have_enqueued_mail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def initialize(mailer_class, method_name)
@mailer_class = mailer_class
@method_name = method_name
@mail_args = []
@args = mailer_args
@args = []
end

def description
Expand All @@ -27,7 +27,7 @@ def description

def with(*args, &block)
@mail_args = args
block.nil? ? super(*mailer_args) : super(*mailer_args, &yield_mail_args(block))
block.nil? ? super : super(&yield_mail_args(block))
end

def matches?(block)
Expand Down Expand Up @@ -63,9 +63,17 @@ def expected_count_message
"#{message_expectation_modifier} #{@expected_number} #{@expected_number == 1 ? 'time' : 'times'}"
end

def mailer_args
def job_match?(job)
super(job) || parameterized_mail?(job)
end

def parameterized_mail?(job)
RSpec::Rails::FeatureCheck.has_action_mailer_parameterized? && job[:job] == parameterized_mailer_job
end

def arguments_match?(job)
if @mail_args.any?
base_mailer_args + @mail_args
@args = base_mailer_args + @mail_args
else
mailer_method_arity = @mailer_class.instance_method(@method_name).arity

Expand All @@ -74,9 +82,12 @@ def mailer_args
else
mailer_method_arity
end
number_of_args += 1 if parameterized_mail?(job)

base_mailer_args + Array.new(number_of_args) { anything }
@args = base_mailer_args + Array.new(number_of_args) { anything }
end

super(job)
end

def base_mailer_args
Expand Down Expand Up @@ -124,6 +135,10 @@ def mail_job_message(job)
def mailer_job
ActionMailer::DeliveryJob
end

def parameterized_mailer_job
ActionMailer::Parameterized::DeliveryJob
end
end
# @api public
# Passes if an email has been enqueued inside block.
Expand Down
25 changes: 25 additions & 0 deletions spec/rspec/rails/matchers/have_enqueued_mail_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,30 @@ def self.name; "NonMailerJob"; end
expect(second_arg).to eq('noon')
}
end

context 'when parameterized', :skip => !RSpec::Rails::FeatureCheck.has_action_mailer_parameterized? do
it "passes when mailer is parameterized" do
expect {
TestMailer.with('foo' => 'bar').test_email.deliver_later
}.to have_enqueued_mail(TestMailer, :test_email)
end

it "passes when mixing parameterized and non-parameterized emails" do
expect {
TestMailer.with('foo' => 'bar').test_email.deliver_later
TestMailer.email_with_args(1, 2).deliver_later
}.to have_enqueued_mail(TestMailer, :test_email).and have_enqueued_mail(TestMailer, :email_with_args)
end

it "passes with provided argument matchers" do
expect {
TestMailer.with('foo' => 'bar').test_email.deliver_later
}.to have_enqueued_mail(TestMailer, :test_email).with('foo' => 'bar')

expect {
TestMailer.with('foo' => 'bar').email_with_args(1, 2).deliver_later
}.to have_enqueued_mail(TestMailer, :email_with_args).with({ 'foo' => 'bar' }, 1, 2)
end
end
end
end