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

allow partial args when using have_enqueued_mail #2118

Merged
merged 1 commit into from May 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 21 additions & 5 deletions lib/rspec/rails/matchers/have_enqueued_mail.rb
Expand Up @@ -22,7 +22,7 @@ def initialize(mailer_class, method_name)
end

def description
"enqueues #{@mailer_class.name}.#{@method_name}"
"enqueues #{mailer_class_name}.#{@method_name}"
end

def with(*args, &block)
Expand Down Expand Up @@ -50,7 +50,7 @@ def failure_message_when_negated
private

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

def mailer_class_name
@mailer_class ? @mailer_class.name : 'ActionMailer::Base'
end

def mailer_args
if @mail_args.any?
base_mailer_args + @mail_args
else
elsif @mailer_class && @method_name
mailer_method_arity = @mailer_class.instance_method(@method_name).arity

number_of_args = if mailer_method_arity < 0
Expand All @@ -76,11 +80,15 @@ def mailer_args
end

base_mailer_args + Array.new(number_of_args) { anything }
elsif @mailer_class
[mailer_class_name, any_args]
else
[]
end
end

def base_mailer_args
[@mailer_class.name, @method_name.to_s, MAILER_JOB_METHOD]
[mailer_class_name, @method_name.to_s, MAILER_JOB_METHOD]
end

def yield_mail_args(block)
Expand Down Expand Up @@ -135,6 +143,14 @@ def mailer_job
# @example
# expect {
# MyMailer.welcome(user).deliver_later
# }.to have_enqueued_mail
#
# expect {
# MyMailer.welcome(user).deliver_later
# }.to have_enqueued_mail(MyMailer)
#
# expect {
# MyMailer.welcome(user).deliver_later
# }.to have_enqueued_mail(MyMailer, :welcome)
#
# # Using alias
Expand Down Expand Up @@ -162,7 +178,7 @@ def mailer_job
# expect {
# MyMailer.welcome(user).deliver_later(queue: :urgent_mail)
# }.to have_enqueued_mail(MyMailer, :welcome).on_queue(:urgent_mail)
def have_enqueued_mail(mailer_class, mail_method_name)
def have_enqueued_mail(mailer_class = nil, mail_method_name = nil)
HaveEnqueuedMail.new(mailer_class, mail_method_name)
end
alias_method :have_enqueued_email, :have_enqueued_mail
Expand Down
44 changes: 44 additions & 0 deletions spec/rspec/rails/matchers/have_enqueued_mail_spec.rb
Expand Up @@ -10,6 +10,10 @@ def test_email; end
def email_with_args(arg1, arg2); end
def email_with_optional_args(required_arg, optional_arg = nil); end
end

class AnotherTestMailer < ActionMailer::Base
def test_email; end
end
end

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

it "passes when given 0 arguments" do
expect {
TestMailer.test_email.deliver_later
}.to have_enqueued_email
end

it "passes when negated with 0 arguments" do
expect { }.not_to have_enqueued_email
end

it "passes when only given mailer argument" do
expect {
TestMailer.test_email.deliver_later
}.to have_enqueued_email(TestMailer)
end

it "passes when negated with only mailer arguments" do
expect { }.not_to have_enqueued_email(TestMailer)
end

it "ensure that the right mailer is enqueued" do
expect {
expect {
AnotherTestMailer.test_email.deliver_later
}.to have_enqueued_mail(TestMailer)
}.to raise_error(/expected to enqueue TestMailer exactly 1 time but enqueued 0/)
end

it "counts only emails enqueued in the block" do
TestMailer.test_email.deliver_later

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

it "generates a failure message when given 0 argument" do
expect {
expect { }.to have_enqueued_mail.at_least(:once)
}.to raise_error(/expected to enqueue ActionMailer::Base at least 1 time but enqueued 0/)
end

it "generates a failure message when given only mailer argument" do
expect {
expect { }.to have_enqueued_mail(TestMailer).at_least(:once)
}.to raise_error(/expected to enqueue TestMailer at least 1 time but enqueued 0/)
end

it "generates a failure message with at least hint" do
expect {
expect { }.to have_enqueued_mail(TestMailer, :test_email).at_least(:once)
Expand Down