rspec-rails 3.0.2 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +3 -1
  5. data/Capybara.md +6 -55
  6. data/Changelog.md +805 -47
  7. data/{License.txt → LICENSE.md} +5 -3
  8. data/README.md +278 -444
  9. data/lib/generators/rspec/channel/channel_generator.rb +12 -0
  10. data/lib/generators/rspec/{observer/templates/observer_spec.rb → channel/templates/channel_spec.rb.erb} +1 -1
  11. data/lib/generators/rspec/controller/controller_generator.rb +24 -7
  12. data/lib/generators/rspec/controller/templates/controller_spec.rb +3 -3
  13. data/lib/generators/rspec/controller/templates/request_spec.rb +19 -0
  14. data/lib/generators/rspec/controller/templates/routing_spec.rb +13 -0
  15. data/lib/generators/rspec/controller/templates/view_spec.rb +1 -1
  16. data/lib/generators/rspec/feature/feature_generator.rb +15 -2
  17. data/lib/generators/rspec/feature/templates/feature_singular_spec.rb +5 -0
  18. data/lib/generators/rspec/feature/templates/feature_spec.rb +1 -1
  19. data/lib/generators/rspec/generator/generator_generator.rb +24 -0
  20. data/lib/generators/rspec/generator/templates/generator_spec.rb +5 -0
  21. data/lib/generators/rspec/helper/helper_generator.rb +2 -2
  22. data/lib/generators/rspec/helper/templates/helper_spec.rb +1 -1
  23. data/lib/generators/rspec/install/install_generator.rb +41 -7
  24. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +63 -22
  25. data/lib/generators/rspec/job/job_generator.rb +13 -0
  26. data/lib/generators/rspec/job/templates/job_spec.rb.erb +7 -0
  27. data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
  28. data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
  29. data/lib/generators/rspec/mailer/mailer_generator.rb +12 -3
  30. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +2 -2
  31. data/lib/generators/rspec/mailer/templates/preview.rb +13 -0
  32. data/lib/generators/rspec/model/model_generator.rb +20 -6
  33. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  34. data/lib/generators/rspec/model/templates/model_spec.rb +1 -1
  35. data/lib/generators/rspec/request/request_generator.rb +17 -0
  36. data/lib/generators/rspec/request/templates/request_spec.rb +10 -0
  37. data/lib/generators/rspec/scaffold/scaffold_generator.rb +90 -113
  38. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +129 -0
  39. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  40. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +46 -64
  41. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +11 -7
  42. data/lib/generators/rspec/scaffold/templates/index_spec.rb +4 -3
  43. data/lib/generators/rspec/scaffold/templates/new_spec.rb +4 -4
  44. data/lib/generators/rspec/scaffold/templates/request_spec.rb +138 -0
  45. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +18 -11
  46. data/lib/generators/rspec/scaffold/templates/show_spec.rb +3 -3
  47. data/lib/generators/rspec/system/system_generator.rb +24 -0
  48. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  49. data/lib/generators/rspec/view/templates/view_spec.rb +1 -1
  50. data/lib/generators/rspec/view/view_generator.rb +4 -4
  51. data/lib/generators/rspec.rb +30 -11
  52. data/lib/rspec/rails/active_record.rb +25 -0
  53. data/lib/rspec/rails/adapters.rb +46 -29
  54. data/lib/rspec/rails/configuration.rb +165 -41
  55. data/lib/rspec/rails/example/channel_example_group.rb +93 -0
  56. data/lib/rspec/rails/example/controller_example_group.rb +185 -149
  57. data/lib/rspec/rails/example/feature_example_group.rb +43 -23
  58. data/lib/rspec/rails/example/helper_example_group.rb +28 -25
  59. data/lib/rspec/rails/example/job_example_group.rb +23 -0
  60. data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
  61. data/lib/rspec/rails/example/mailer_example_group.rb +27 -22
  62. data/lib/rspec/rails/example/model_example_group.rb +9 -6
  63. data/lib/rspec/rails/example/rails_example_group.rb +9 -2
  64. data/lib/rspec/rails/example/request_example_group.rb +21 -17
  65. data/lib/rspec/rails/example/routing_example_group.rb +47 -39
  66. data/lib/rspec/rails/example/system_example_group.rb +180 -0
  67. data/lib/rspec/rails/example/view_example_group.rb +179 -134
  68. data/lib/rspec/rails/example.rb +4 -0
  69. data/lib/rspec/rails/extensions/active_record/proxy.rb +5 -11
  70. data/lib/rspec/rails/feature_check.rb +51 -0
  71. data/lib/rspec/rails/file_fixture_support.rb +18 -0
  72. data/lib/rspec/rails/fixture_file_upload_support.rb +45 -0
  73. data/lib/rspec/rails/fixture_support.rb +70 -14
  74. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +180 -0
  75. data/lib/rspec/rails/matchers/action_cable/have_streams.rb +58 -0
  76. data/lib/rspec/rails/matchers/action_cable.rb +70 -0
  77. data/lib/rspec/rails/matchers/action_mailbox.rb +73 -0
  78. data/lib/rspec/rails/matchers/active_job.rb +526 -0
  79. data/lib/rspec/rails/matchers/base_matcher.rb +179 -0
  80. data/lib/rspec/rails/matchers/be_a_new.rb +70 -64
  81. data/lib/rspec/rails/matchers/be_new_record.rb +25 -20
  82. data/lib/rspec/rails/matchers/be_valid.rb +39 -34
  83. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +259 -0
  84. data/lib/rspec/rails/matchers/have_http_status.rb +359 -333
  85. data/lib/rspec/rails/matchers/have_rendered.rb +55 -32
  86. data/lib/rspec/rails/matchers/redirect_to.rb +30 -27
  87. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  88. data/lib/rspec/rails/matchers/routing_matchers.rb +107 -101
  89. data/lib/rspec/rails/matchers/send_email.rb +122 -0
  90. data/lib/rspec/rails/matchers.rb +21 -12
  91. data/lib/rspec/rails/tasks/rspec.rake +9 -17
  92. data/lib/rspec/rails/vendor/capybara.rb +10 -11
  93. data/lib/rspec/rails/version.rb +1 -1
  94. data/lib/rspec/rails/view_assigns.rb +1 -20
  95. data/lib/rspec/rails/view_path_builder.rb +29 -0
  96. data/lib/rspec/rails/view_rendering.rb +89 -27
  97. data/lib/rspec/rails/view_spec_methods.rb +56 -0
  98. data/lib/rspec/rails.rb +9 -1
  99. data/lib/rspec-rails.rb +83 -3
  100. data.tar.gz.sig +0 -0
  101. metadata +108 -78
  102. metadata.gz.sig +3 -2
  103. data/lib/generators/rspec/integration/integration_generator.rb +0 -17
  104. data/lib/generators/rspec/integration/templates/request_spec.rb +0 -10
  105. data/lib/generators/rspec/observer/observer_generator.rb +0 -13
@@ -1,77 +1,83 @@
1
- module RSpec::Rails::Matchers
2
- # @api private
3
- #
4
- # Matcher class for `be_a_new`. Should not be instantiated directly.
5
- #
6
- # @see RSpec::Rails::Matchers#be_a_new
7
- class BeANew < RSpec::Matchers::BuiltIn::BaseMatcher
8
- # @private
9
- def initialize(expected)
10
- @expected = expected
11
- end
12
-
13
- # @private
14
- def matches?(actual)
15
- @actual = actual
16
- actual.is_a?(expected) && actual.new_record? && attributes_match?(actual)
17
- end
1
+ module RSpec
2
+ module Rails
3
+ module Matchers
4
+ # @api private
5
+ #
6
+ # Matcher class for `be_a_new`. Should not be instantiated directly.
7
+ #
8
+ # @see RSpec::Rails::Matchers#be_a_new
9
+ class BeANew < RSpec::Rails::Matchers::BaseMatcher
10
+ # @private
11
+ def initialize(expected)
12
+ @expected = expected
13
+ end
18
14
 
19
- # @api public
20
- # @see RSpec::Rails::Matchers#be_a_new
21
- def with(expected_attributes)
22
- attributes.merge!(expected_attributes)
23
- self
24
- end
15
+ # @private
16
+ def matches?(actual)
17
+ @actual = actual
18
+ actual.is_a?(expected) && actual.new_record? && attributes_match?(actual)
19
+ end
25
20
 
26
- # @private
27
- def failure_message
28
- [].tap do |message|
29
- unless actual.is_a?(expected) && actual.new_record?
30
- message << "expected #{actual.inspect} to be a new #{expected.inspect}"
21
+ # @api public
22
+ # @see RSpec::Rails::Matchers#be_a_new
23
+ def with(expected_attributes)
24
+ attributes.merge!(expected_attributes)
25
+ self
31
26
  end
32
- unless attributes_match?(actual)
33
- if unmatched_attributes.size > 1
34
- message << "attributes #{unmatched_attributes.inspect} were not set on #{actual.inspect}"
35
- else
36
- message << "attribute #{unmatched_attributes.inspect} was not set on #{actual.inspect}"
37
- end
27
+
28
+ # @private
29
+ def failure_message
30
+ [].tap do |message|
31
+ unless actual.is_a?(expected) && actual.new_record?
32
+ message << "expected #{actual.inspect} to be a new #{expected.inspect}"
33
+ end
34
+ unless attributes_match?(actual)
35
+ describe_unmatched_attributes = surface_descriptions_in(unmatched_attributes)
36
+ if unmatched_attributes.size > 1
37
+ message << "attributes #{describe_unmatched_attributes.inspect} were not set on #{actual.inspect}"
38
+ else
39
+ message << "attribute #{describe_unmatched_attributes.inspect} was not set on #{actual.inspect}"
40
+ end
41
+ end
42
+ end.join(' and ')
38
43
  end
39
- end.join(' and ')
40
- end
41
44
 
42
- private
45
+ private
43
46
 
44
- def attributes
45
- @attributes ||= {}
46
- end
47
+ def attributes
48
+ @attributes ||= {}
49
+ end
47
50
 
48
- def attributes_match?(actual)
49
- attributes.stringify_keys.all? do |key, value|
50
- actual.attributes[key].eql?(value)
51
+ def attributes_match?(actual)
52
+ attributes.stringify_keys.all? do |key, value|
53
+ values_match?(value, actual.attributes[key])
54
+ end
55
+ end
56
+
57
+ def unmatched_attributes
58
+ attributes.stringify_keys.reject do |key, value|
59
+ values_match?(value, actual.attributes[key])
60
+ end
61
+ end
51
62
  end
52
- end
53
63
 
54
- def unmatched_attributes
55
- attributes.stringify_keys.reject do |key, value|
56
- actual.attributes[key].eql?(value)
64
+ # @api public
65
+ # Passes if actual is an instance of `model_class` and returns `true` for
66
+ # `new_record?`. Typically used to specify instance variables assigned to
67
+ # views by controller actions
68
+ #
69
+ # Use the `with` method to specify the specific attributes to match on the
70
+ # new record.
71
+ #
72
+ # @example
73
+ # get :new
74
+ # assigns(:thing).should be_a_new(Thing)
75
+ #
76
+ # post :create, :thing => { :name => "Illegal Value" }
77
+ # assigns(:thing).should be_a_new(Thing).with(:name => nil)
78
+ def be_a_new(model_class)
79
+ BeANew.new(model_class)
57
80
  end
58
81
  end
59
82
  end
60
-
61
- # Passes if actual is an instance of `model_class` and returns `false` for
62
- # `persisted?`. Typically used to specify instance variables assigned to
63
- # views by controller actions
64
- #
65
- # Use the `with` method to specify the specific attributes to match on the
66
- # new record.
67
- #
68
- # @example
69
- # get :new
70
- # assigns(:thing).should be_a_new(Thing)
71
- #
72
- # post :create, :thing => { :name => "Illegal Value" }
73
- # assigns(:thing).should be_a_new(Thing).with(:name => nil)
74
- def be_a_new(model_class)
75
- BeANew.new(model_class)
76
- end
77
83
  end
@@ -1,25 +1,30 @@
1
- module RSpec::Rails::Matchers
2
- # @private
3
- class BeANewRecord < RSpec::Matchers::BuiltIn::BaseMatcher
4
- def matches?(actual)
5
- !actual.persisted?
6
- end
1
+ module RSpec
2
+ module Rails
3
+ module Matchers
4
+ # @private
5
+ class BeANewRecord < RSpec::Rails::Matchers::BaseMatcher
6
+ def matches?(actual)
7
+ actual.new_record?
8
+ end
7
9
 
8
- def failure_message
9
- "expected #{actual.inspect} to be a new record, but was persisted"
10
- end
10
+ def failure_message
11
+ "expected #{actual.inspect} to be a new record, but was persisted"
12
+ end
11
13
 
12
- def failure_message_when_negated
13
- "expected #{actual.inspect} to be persisted, but was a new record"
14
- end
15
- end
14
+ def failure_message_when_negated
15
+ "expected #{actual.inspect} to be persisted, but was a new record"
16
+ end
17
+ end
16
18
 
17
- # Passes if actual returns `false` for `persisted?`.
18
- #
19
- # @example
20
- # get :new
21
- # expect(assigns(:thing)).to be_new_record
22
- def be_new_record
23
- BeANewRecord.new
19
+ # @api public
20
+ # Passes if actual returns `true` for `new_record?`.
21
+ #
22
+ # @example
23
+ # get :new
24
+ # expect(assigns(:thing)).to be_new_record
25
+ def be_new_record
26
+ BeANewRecord.new
27
+ end
28
+ end
24
29
  end
25
30
  end
@@ -1,44 +1,49 @@
1
- module RSpec::Rails::Matchers
2
- # @private
3
- class BeValid < RSpec::Matchers::BuiltIn::Be
4
- def initialize(*args)
5
- @args = args
6
- end
1
+ module RSpec
2
+ module Rails
3
+ module Matchers
4
+ # @private
5
+ class BeValid < RSpec::Matchers::BuiltIn::Be
6
+ def initialize(*args)
7
+ @args = args
8
+ end
7
9
 
8
- def matches?(actual)
9
- @actual = actual
10
- actual.valid?(*@args)
11
- end
10
+ def matches?(actual)
11
+ @actual = actual
12
+ actual.valid?(*@args)
13
+ end
14
+
15
+ def failure_message
16
+ message = "expected #{actual.inspect} to be valid"
17
+
18
+ if actual.respond_to?(:errors) && actual.method(:errors).arity < 1
19
+ errors = if actual.errors.respond_to?(:full_messages)
20
+ actual.errors.full_messages
21
+ else
22
+ actual.errors
23
+ end
12
24
 
13
- def failure_message
14
- message = "expected #{actual.inspect} to be valid"
25
+ message << ", but got errors: #{errors.map(&:to_s).join(', ')}"
26
+ end
15
27
 
16
- if actual.respond_to?(:errors)
17
- errors = if actual.errors.respond_to?(:full_messages)
18
- actual.errors.full_messages
19
- else
20
- actual.errors
28
+ message
21
29
  end
22
30
 
23
- message << ", but got errors: #{errors.map(&:to_s).join(', ')}"
31
+ def failure_message_when_negated
32
+ "expected #{actual.inspect} not to be valid"
33
+ end
24
34
  end
25
35
 
26
- message
27
- end
28
-
29
- def failure_message_when_negated
30
- "expected #{actual.inspect} not to be valid"
36
+ # @api public
37
+ # Passes if the given model instance's `valid?` method is true, meaning
38
+ # all of the `ActiveModel::Validations` passed and no errors exist. If a
39
+ # message is not given, a default message is shown listing each error.
40
+ #
41
+ # @example
42
+ # thing = Thing.new
43
+ # expect(thing).to be_valid
44
+ def be_valid(*args)
45
+ BeValid.new(*args)
46
+ end
31
47
  end
32
48
  end
33
-
34
- # Passes if the given model instance's `valid?` method is true, meaning all
35
- # of the `ActiveModel::Validations` passed and no errors exist. If a message
36
- # is not given, a default message is shown listing each error.
37
- #
38
- # @example
39
- # thing = Thing.new
40
- # expect(thing).to be_valid
41
- def be_valid(*args)
42
- BeValid.new(*args)
43
- end
44
49
  end
@@ -0,0 +1,259 @@
1
+ # We require the minimum amount of rspec-mocks possible to avoid
2
+ # conflicts with other mocking frameworks.
3
+ # See: https://github.com/rspec/rspec-rails/issues/2252
4
+ require "rspec/mocks/argument_matchers"
5
+ require "rspec/rails/matchers/active_job"
6
+
7
+ # rubocop: disable Metrics/ClassLength
8
+ module RSpec
9
+ module Rails
10
+ module Matchers
11
+ # Matcher class for `have_enqueued_mail`. Should not be instantiated directly.
12
+ #
13
+ # @private
14
+ # @see RSpec::Rails::Matchers#have_enqueued_mail
15
+ class HaveEnqueuedMail < ActiveJob::HaveEnqueuedJob
16
+ MAILER_JOB_METHOD = 'deliver_now'.freeze
17
+
18
+ include RSpec::Mocks::ArgumentMatchers
19
+
20
+ def initialize(mailer_class, method_name)
21
+ super(nil)
22
+ @mailer_class = mailer_class
23
+ @method_name = method_name
24
+ @mail_args = []
25
+ end
26
+
27
+ def description
28
+ "enqueues #{mailer_class_name}.#{@method_name}"
29
+ end
30
+
31
+ def with(*args, &block)
32
+ @mail_args = args
33
+ block.nil? ? super : super(&yield_mail_args(block))
34
+ end
35
+
36
+ def matches?(block)
37
+ raise ArgumentError, 'have_enqueued_mail and enqueue_mail only work with block arguments' unless block.respond_to?(:call)
38
+
39
+ check_active_job_adapter
40
+ super
41
+ end
42
+
43
+ def failure_message
44
+ return @failure_message if defined?(@failure_message)
45
+
46
+ "expected to enqueue #{base_message}".tap do |msg|
47
+ msg << "\n#{unmatching_mail_jobs_message}" if unmatching_mail_jobs.any?
48
+ end
49
+ end
50
+
51
+ def failure_message_when_negated
52
+ "expected not to enqueue #{base_message}"
53
+ end
54
+
55
+ private
56
+
57
+ def base_message
58
+ [mailer_class_name, @method_name].compact.join('.').tap do |msg|
59
+ msg << " #{expected_count_message}"
60
+ msg << " with #{@mail_args}," if @mail_args.any?
61
+ msg << " on queue #{@queue}," if @queue
62
+ msg << " at #{@at.inspect}," if @at
63
+ msg << " but enqueued #{@matching_jobs.size}"
64
+ end
65
+ end
66
+
67
+ def expected_count_message
68
+ "#{message_expectation_modifier} #{@expected_number} #{@expected_number == 1 ? 'time' : 'times'}"
69
+ end
70
+
71
+ def mailer_class_name
72
+ @mailer_class ? @mailer_class.name : 'ActionMailer::Base'
73
+ end
74
+
75
+ def job_matches?(job)
76
+ legacy_mail?(job) || parameterized_mail?(job) || unified_mail?(job)
77
+ end
78
+
79
+ def arguments_match?(job)
80
+ @args =
81
+ if @mail_args.any?
82
+ base_mailer_args + @mail_args
83
+ elsif @mailer_class && @method_name
84
+ base_mailer_args + [any_args]
85
+ elsif @mailer_class
86
+ [mailer_class_name, any_args]
87
+ else
88
+ []
89
+ end
90
+
91
+ super(job)
92
+ end
93
+
94
+ def detect_args_signature_mismatch(jobs)
95
+ return if @method_name.nil?
96
+ return if skip_signature_verification?
97
+
98
+ mailer_class = mailer_class_name.constantize
99
+
100
+ jobs.each do |job|
101
+ mailer_args = extract_args_without_parameterized_params(job)
102
+
103
+ if (signature_mismatch = check_args_signature_mismatch(mailer_class, @method_name, mailer_args))
104
+ return signature_mismatch
105
+ end
106
+ end
107
+
108
+ nil
109
+ end
110
+
111
+ def base_mailer_args
112
+ [mailer_class_name, @method_name.to_s, MAILER_JOB_METHOD]
113
+ end
114
+
115
+ def yield_mail_args(block)
116
+ proc { |*job_args| block.call(*(job_args - base_mailer_args)) }
117
+ end
118
+
119
+ def check_active_job_adapter
120
+ return if ::ActiveJob::QueueAdapters::TestAdapter === ::ActiveJob::Base.queue_adapter
121
+
122
+ raise StandardError, "To use HaveEnqueuedMail matcher set `ActiveJob::Base.queue_adapter = :test`"
123
+ end
124
+
125
+ def unmatching_mail_jobs
126
+ @unmatching_jobs.select do |job|
127
+ job_matches?(job)
128
+ end
129
+ end
130
+
131
+ def unmatching_mail_jobs_message
132
+ messages = ["Queued deliveries:"]
133
+
134
+ unmatching_mail_jobs.each do |job|
135
+ messages << " #{mail_job_message(job)}"
136
+ end
137
+
138
+ messages.join("\n")
139
+ end
140
+
141
+ def mail_job_message(job)
142
+ job_args = deserialize_arguments(job)
143
+
144
+ mailer_method = job_args[0..1].join('.')
145
+ mailer_args = job_args[3..-1]
146
+
147
+ msg_parts = []
148
+ msg_parts << "with #{mailer_args}" if mailer_args.any?
149
+ msg_parts << "on queue #{job[:queue]}" if job[:queue] && job[:queue] != 'mailers'
150
+ msg_parts << "at #{Time.at(job[:at])}" if job[:at]
151
+
152
+ "#{mailer_method} #{msg_parts.join(', ')}".strip
153
+ end
154
+
155
+ # Ruby 3.1 changed how params were serialized on Rails 6.1
156
+ # so we override the active job implementation and customize it here.
157
+ def deserialize_arguments(job)
158
+ args = super
159
+
160
+ return args unless Hash === args.last
161
+
162
+ hash = args.pop
163
+
164
+ if hash.key?("_aj_ruby2_keywords")
165
+ keywords = hash["_aj_ruby2_keywords"]
166
+
167
+ original_hash = keywords.each_with_object({}) { |keyword, new_hash| new_hash[keyword.to_sym] = hash[keyword] }
168
+
169
+ args + [original_hash]
170
+ elsif hash.key?(:args) && hash.key?(:params)
171
+ args + [hash]
172
+ elsif hash.key?(:args)
173
+ args + hash[:args]
174
+ else
175
+ args + [hash]
176
+ end
177
+ end
178
+
179
+ def extract_args_without_parameterized_params(job)
180
+ args = deserialize_arguments(job)
181
+ mailer_args = args - base_mailer_args
182
+
183
+ if parameterized_mail?(job)
184
+ mailer_args = mailer_args[1..-1] # ignore parameterized params
185
+ elsif mailer_args.last.is_a?(Hash) && mailer_args.last.key?(:args)
186
+ mailer_args = args.last[:args]
187
+ end
188
+
189
+ mailer_args
190
+ end
191
+
192
+ def legacy_mail?(job)
193
+ RSpec::Rails::FeatureCheck.has_action_mailer_legacy_delivery_job? && job[:job] <= ActionMailer::DeliveryJob
194
+ end
195
+
196
+ def parameterized_mail?(job)
197
+ RSpec::Rails::FeatureCheck.has_action_mailer_parameterized? && job[:job] <= ActionMailer::Parameterized::DeliveryJob
198
+ end
199
+
200
+ def unified_mail?(job)
201
+ RSpec::Rails::FeatureCheck.has_action_mailer_unified_delivery? && job[:job] <= ActionMailer::MailDeliveryJob
202
+ end
203
+ end
204
+
205
+ # @api public
206
+ # Passes if an email has been enqueued inside block.
207
+ # May chain with to specify expected arguments.
208
+ # May chain at_least, at_most or exactly to specify a number of times.
209
+ # May chain at to specify a send time.
210
+ # May chain on_queue to specify a queue.
211
+ #
212
+ # @example
213
+ # expect {
214
+ # MyMailer.welcome(user).deliver_later
215
+ # }.to have_enqueued_mail
216
+ #
217
+ # expect {
218
+ # MyMailer.welcome(user).deliver_later
219
+ # }.to have_enqueued_mail(MyMailer)
220
+ #
221
+ # expect {
222
+ # MyMailer.welcome(user).deliver_later
223
+ # }.to have_enqueued_mail(MyMailer, :welcome)
224
+ #
225
+ # # Using alias
226
+ # expect {
227
+ # MyMailer.welcome(user).deliver_later
228
+ # }.to enqueue_mail(MyMailer, :welcome)
229
+ #
230
+ # expect {
231
+ # MyMailer.welcome(user).deliver_later
232
+ # }.to have_enqueued_mail(MyMailer, :welcome).with(user)
233
+ #
234
+ # expect {
235
+ # MyMailer.welcome(user).deliver_later
236
+ # MyMailer.welcome(user).deliver_later
237
+ # }.to have_enqueued_mail(MyMailer, :welcome).at_least(:once)
238
+ #
239
+ # expect {
240
+ # MyMailer.welcome(user).deliver_later
241
+ # }.to have_enqueued_mail(MyMailer, :welcome).at_most(:twice)
242
+ #
243
+ # expect {
244
+ # MyMailer.welcome(user).deliver_later(wait_until: Date.tomorrow.noon)
245
+ # }.to have_enqueued_mail(MyMailer, :welcome).at(Date.tomorrow.noon)
246
+ #
247
+ # expect {
248
+ # MyMailer.welcome(user).deliver_later(queue: :urgent_mail)
249
+ # }.to have_enqueued_mail(MyMailer, :welcome).on_queue(:urgent_mail)
250
+ def have_enqueued_mail(mailer_class = nil, mail_method_name = nil)
251
+ HaveEnqueuedMail.new(mailer_class, mail_method_name)
252
+ end
253
+ alias_method :have_enqueued_email, :have_enqueued_mail
254
+ alias_method :enqueue_mail, :have_enqueued_mail
255
+ alias_method :enqueue_email, :have_enqueued_mail
256
+ end
257
+ end
258
+ end
259
+ # rubocop: enable Metrics/ClassLength