Skip to content

Commit e21943d

Browse files
author
Joel Lubrano
committed
Move deliver_later gem logic into HaveEnqueuedMail matcher
Moving the internals of https://github.com/jdlubrano/deliver_later_matchers into rspec-rails as a new RSpec::Rails::Matchers::HaveEnqueuedMail class.
1 parent 864d0f1 commit e21943d

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
require "rspec/rails/matchers/active_job"
2+
3+
module RSpec
4+
module Rails
5+
module Matchers
6+
# @api private
7+
#
8+
# Matcher class for `have_enqueued_mail`. Should not be instantiated directly.
9+
#
10+
# @see RSpec::Rails::Matchers#have_enqueued_mail
11+
class HaveEnqueuedMail < RSpec::Matchers::BuiltIn::BaseMatcher
12+
def initialize(mailer_class, method_name)
13+
@mailer_class = mailer_class
14+
@method_name = method_name
15+
@args = []
16+
end
17+
18+
def description
19+
"enqueues #{@mailer_class.name}.#{@method_name}"
20+
end
21+
22+
def matches?(block)
23+
raise ArgumentError, 'have_enqueued_mail and enqueue_mail only work with block arguments' unless block.respond_to?(:call)
24+
check_active_job_adapter
25+
26+
job_matcher = ActiveJob::HaveEnqueuedJob.new(ActionMailer::DeliveryJob)
27+
job_matcher.with(*mailer_args)
28+
job_matcher.matches?(block)
29+
end
30+
31+
def with(*args)
32+
@args = args
33+
self
34+
end
35+
36+
def failure_message
37+
base_message.tap do |msg|
38+
msg << " with #{@args}" if @args.any?
39+
end
40+
end
41+
42+
def supports_block_expectations?
43+
true
44+
end
45+
46+
private
47+
48+
def base_message
49+
"expected to enqueue #{@mailer_class.name}.#{@method_name}"
50+
end
51+
52+
def mailer_args
53+
[@mailer_class.name, @method_name.to_s, 'deliver_now'] + @args
54+
end
55+
56+
def check_active_job_adapter
57+
return if ::ActiveJob::QueueAdapters::TestAdapter === ::ActiveJob::Base.queue_adapter
58+
raise StandardError, "To use HaveEnqueuedMail matcher set `ActiveJob::Base.queue_adapter = :test`"
59+
end
60+
end
61+
62+
# @api public
63+
# Passes if an email has been enqueued inside block. May chain with to specify expected arguments.
64+
#
65+
# @example
66+
# expect {
67+
# MyMailer.welcome(user).deliver_later
68+
# }.to have_enqueued_mail(MyMailer, :welcome)
69+
#
70+
# # Using alias
71+
# expect {
72+
# MyMailer.welcome(user).deliver_later
73+
# }.to enqueue_mail(MyMailer, :welcome)
74+
#
75+
# expect {
76+
# MyMailer.welcome(user).deliver_later
77+
# }.to have_enqueued_mail(MyMailer, :welcome).with(user)
78+
def have_enqueued_mail(mailer_class, mail_method_name)
79+
check_active_job_adapter
80+
HaveEnqueuedMail.new(mailer_class, mail_method_name)
81+
end
82+
alias_method :have_enqueued_email, :have_enqueued_mail
83+
alias_method :enqueue_mail, :have_enqueued_mail
84+
alias_method :enqueue_email, :have_enqueued_mail
85+
end
86+
end
87+
end

0 commit comments

Comments
 (0)