4
4
require "rspec/mocks/argument_matchers"
5
5
require "rspec/rails/matchers/active_job"
6
6
7
+ # rubocop: disable Metrics/ClassLength
7
8
module RSpec
8
9
module Rails
9
10
module Matchers
@@ -12,6 +13,7 @@ module Matchers
12
13
# @private
13
14
# @see RSpec::Rails::Matchers#have_enqueued_mail
14
15
class HaveEnqueuedMail < ActiveJob ::HaveEnqueuedJob
16
+
15
17
MAILER_JOB_METHOD = 'deliver_now' . freeze
16
18
17
19
include RSpec ::Mocks ::ArgumentMatchers
@@ -76,7 +78,7 @@ def job_match?(job)
76
78
def arguments_match? ( job )
77
79
@args =
78
80
if @mail_args . any?
79
- base_mailer_args + process_arguments ( job , @mail_args )
81
+ base_mailer_args + @mail_args
80
82
elsif @mailer_class && @method_name
81
83
base_mailer_args + [ any_args ]
82
84
elsif @mailer_class
@@ -88,38 +90,12 @@ def arguments_match?(job)
88
90
super ( job )
89
91
end
90
92
91
- def process_arguments ( job , given_mail_args )
92
- # Old matcher behavior working with all builtin classes but ActionMailer::MailDeliveryJob
93
- return given_mail_args if use_given_mail_args? ( job )
94
-
95
- # If matching args starts with a hash and job instance has params match with them
96
- if given_mail_args . first . is_a? ( Hash ) && job [ :args ] [ 3 ] [ 'params' ] . present?
97
- [ hash_including ( params : given_mail_args [ 0 ] , args : given_mail_args . drop ( 1 ) ) ]
98
- else
99
- [ hash_including ( args : given_mail_args ) ]
100
- end
101
- end
102
-
103
- def use_given_mail_args? ( job )
104
- return true if FeatureCheck . has_action_mailer_parameterized? && job [ :job ] <= ActionMailer ::Parameterized ::DeliveryJob
105
- return false if FeatureCheck . ruby_3_1?
106
-
107
- !( FeatureCheck . has_action_mailer_unified_delivery? && job [ :job ] <= ActionMailer ::MailDeliveryJob )
108
- end
109
-
110
93
def base_mailer_args
111
94
[ mailer_class_name , @method_name . to_s , MAILER_JOB_METHOD ]
112
95
end
113
96
114
97
def yield_mail_args ( block )
115
- proc do |*job_args |
116
- mailer_args = job_args - base_mailer_args
117
- if mailer_args . first . is_a? ( Hash )
118
- block . call ( *mailer_args . first [ :args ] )
119
- else
120
- block . call ( *mailer_args )
121
- end
122
- end
98
+ proc { |*job_args | block . call ( *( job_args - base_mailer_args ) ) }
123
99
end
124
100
125
101
def check_active_job_adapter
@@ -145,22 +121,41 @@ def unmatching_mail_jobs_message
145
121
end
146
122
147
123
def mail_job_message ( job )
148
- mailer_method = job [ :args ] [ 0 ..1 ] . join ( '.' )
149
- mailer_args = deserialize_arguments ( job ) [ 3 ..-1 ]
150
- mailer_args = mailer_args . first [ :args ] if unified_mail? ( job )
124
+ job_args = deserialize_arguments ( job )
125
+
126
+ mailer_method = job_args [ 0 ..1 ] . join ( '.' )
127
+ mailer_args = job_args [ 3 ..-1 ]
128
+
151
129
msg_parts = [ ]
152
- display_args = display_mailer_args ( mailer_args )
153
- msg_parts << "with #{ display_args } " if display_args . any?
130
+ msg_parts << "with #{ mailer_args } " if mailer_args . any?
154
131
msg_parts << "on queue #{ job [ :queue ] } " if job [ :queue ] && job [ :queue ] != 'mailers'
155
132
msg_parts << "at #{ Time . at ( job [ :at ] ) } " if job [ :at ]
156
133
157
134
"#{ mailer_method } #{ msg_parts . join ( ', ' ) } " . strip
158
135
end
159
136
160
- def display_mailer_args ( mailer_args )
161
- return mailer_args unless mailer_args . first . is_a? ( Hash ) && mailer_args . first . key? ( :args )
137
+ # Ruby 3.1 changed how params were serialized on Rails 6.1
138
+ # so we override the active job implementation and customise it here.
139
+ def deserialize_arguments ( job )
140
+ args = super
141
+
142
+ return args unless Hash === args . last
143
+
144
+ hash = args . pop
162
145
163
- mailer_args . first [ :args ]
146
+ if hash . key? ( "_aj_ruby2_keywords" )
147
+ keywords = hash [ "_aj_ruby2_keywords" ]
148
+
149
+ original_hash = keywords . each_with_object ( { } ) { |new_hash , keyword | new_hash [ keyword . to_sym ] = hash [ keyword ] }
150
+
151
+ args + [ original_hash ]
152
+ elsif hash . key? ( :args ) && hash . key? ( :params )
153
+ args + [ hash ]
154
+ elsif hash . key? ( :args )
155
+ args + hash [ :args ]
156
+ else
157
+ args + [ hash ]
158
+ end
164
159
end
165
160
166
161
def legacy_mail? ( job )
@@ -174,6 +169,7 @@ def parameterized_mail?(job)
174
169
def unified_mail? ( job )
175
170
RSpec ::Rails ::FeatureCheck . has_action_mailer_unified_delivery? && job [ :job ] <= ActionMailer ::MailDeliveryJob
176
171
end
172
+
177
173
end
178
174
# @api public
179
175
# Passes if an email has been enqueued inside block.
@@ -229,3 +225,4 @@ def have_enqueued_mail(mailer_class = nil, mail_method_name = nil)
229
225
end
230
226
end
231
227
end
228
+ # rubocop: enable Metrics/ClassLength
0 commit comments