class RSpec::Rails::Matchers::HaveEnqueuedMail

Matcher class for `have_enqueued_mail`. Should not be instantiated directly.

rubocop: disable Style/ClassLength @private @see RSpec::Rails::Matchers#have_enqueued_mail

Constants

MAILER_JOB_METHOD

Public Class Methods

new(mailer_class, method_name) click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 17
def initialize(mailer_class, method_name)
  super(mailer_job)
  @mailer_class = mailer_class
  @method_name = method_name
  @mail_args = []
  @args = mailer_args
end

Public Instance Methods

description() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 25
def description
  "enqueues #{@mailer_class.name}.#{@method_name}"
end
failure_message() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 40
def failure_message
  "expected to enqueue #{base_message}".tap do |msg|
    msg << "\n#{unmatching_mail_jobs_message}" if unmatching_mail_jobs.any?
  end
end
failure_message_when_negated() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 46
def failure_message_when_negated
  "expected not to enqueue #{base_message}"
end
matches?(block) click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 34
def matches?(block)
  raise ArgumentError, 'have_enqueued_mail and enqueue_mail only work with block arguments' unless block.respond_to?(:call)
  check_active_job_adapter
  super
end
with(*args, &block) click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 29
def with(*args, &block)
  @mail_args = args
  block.nil? ? super(*mailer_args) : super(*mailer_args, &yield_mail_args(block))
end

Private Instance Methods

base_mailer_args() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 82
def base_mailer_args
  [@mailer_class.name, @method_name.to_s, MAILER_JOB_METHOD]
end
base_message() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 52
def base_message
  "#{@mailer_class.name}.#{@method_name}".tap do |msg|
    msg << " #{expected_count_message}"
    msg << " with #{@mail_args}," if @mail_args.any?
    msg << " on queue #{@queue}," if @queue
    msg << " at #{@at.inspect}," if @at
    msg << " but enqueued #{@matching_jobs.size}"
  end
end
check_active_job_adapter() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 90
def check_active_job_adapter
  return if ::ActiveJob::QueueAdapters::TestAdapter === ::ActiveJob::Base.queue_adapter
  raise StandardError, "To use HaveEnqueuedMail matcher set `ActiveJob::Base.queue_adapter = :test`"
end
expected_count_message() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 62
def expected_count_message
  "#{message_expectation_modifier} #{@expected_number} #{@expected_number == 1 ? 'time' : 'times'}"
end
mail_job_message(job) click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 111
def mail_job_message(job)
  mailer_method = job[:args][0..1].join('.')

  mailer_args = job[:args][3..-1]
  msg_parts = []
  msg_parts << "with #{mailer_args}" if mailer_args.any?
  msg_parts << "on queue #{job[:queue]}" if job[:queue] && job[:queue] != 'mailers'
  msg_parts << "at #{Time.at(job[:at])}" if job[:at]

  "#{mailer_method} #{msg_parts.join(', ')}".strip
end
mailer_args() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 66
def mailer_args
  if @mail_args.any?
    base_mailer_args + @mail_args
  else
    mailer_method_arity = @mailer_class.instance_method(@method_name).arity

    number_of_args = if mailer_method_arity < 0
                       (mailer_method_arity + 1).abs
                     else
                       mailer_method_arity
                     end

    base_mailer_args + Array.new(number_of_args) { anything }
  end
end
mailer_job() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 123
def mailer_job
  ActionMailer::DeliveryJob
end
unmatching_mail_jobs() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 95
def unmatching_mail_jobs
  @unmatching_jobs.select do |job|
    job[:job] == mailer_job
  end
end
unmatching_mail_jobs_message() click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 101
def unmatching_mail_jobs_message
  msg = "Queued deliveries:"

  unmatching_mail_jobs.each do |job|
    msg << "\n  #{mail_job_message(job)}"
  end

  msg
end
yield_mail_args(block) click to toggle source
# File lib/rspec/rails/matchers/have_enqueued_mail.rb, line 86
def yield_mail_args(block)
  Proc.new { |*job_args| block.call(*(job_args - base_mailer_args)) }
end