class DeliverLaterMatchers::DeliverLater

Public Class Methods

new(mailer_class, method_name) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 5
def initialize(mailer_class, method_name)
  @mailer_class = mailer_class
  @method_name = method_name
  @args = []
end

Public Instance Methods

description() click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 11
def description
  "deliver #{@mailer_class.name}.#{@method_name} later"
end
failure_message(block) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 31
def failure_message(block)
  "expected #{@mailer_class.name}.#{@method_name} to be delivered later"
end
matches?(block) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 15
def matches?(block)
  raise ArgumentError, 'DeliverLater only works with block arguments' unless block.respond_to?(:call)
  check_job_adapter

  existing_jobs_count = enqueued_jobs.size
  block.call
  jobs_from_block = enqueued_jobs[existing_jobs_count..-1]

  matching_job_exists?(jobs_from_block)
end
with(*args) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 26
def with(*args)
  @args = args
  self
end

Private Instance Methods

arguments_match?(job) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 45
def arguments_match?(job)
  RSpec::Mocks::ArgumentListMatcher.new(*mailer_args).args_match?(*job_args(job))
end
check_job_adapter() click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 69
def check_job_adapter
  return if queue_adapter.is_a?(::ActiveJob::QueueAdapters::TestAdapter)

  raise RuntimeError, "To use DeliverLaterMatchers, set `ActiveJob::Base.queue_adapter = :test`."
end
enqueued_jobs() click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 61
def enqueued_jobs
  queue_adapter.enqueued_jobs
end
job_args(job) click to toggle source

In the case where we match a mailer method that accepts arguments but the test does not call `with` on the matcher, we want to ignore the extra arguments passed to ActiveJob when we are trying to find our `deliver_later` job.

# File lib/deliver_later_matchers/deliver_later.rb, line 53
def job_args(job)
  ::ActiveJob::Arguments.deserialize(job[:args])[0...mailer_args.size]
end
mailer_args() click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 57
def mailer_args
  [@mailer_class.name, @method_name.to_s, 'deliver_now'] + @args
end
mailer_job?(job) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 41
def mailer_job?(job)
  job[:job] == ActionMailer::DeliveryJob
end
matching_job_exists?(jobs) click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 37
def matching_job_exists?(jobs)
  jobs.any? { |job| mailer_job?(job) && arguments_match?(job) }
end
queue_adapter() click to toggle source
# File lib/deliver_later_matchers/deliver_later.rb, line 65
def queue_adapter
  ::ActiveJob::Base.queue_adapter
end