actionmailer 5.2.6.3 → 6.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -44
- data/MIT-LICENSE +1 -2
- data/README.rdoc +5 -39
- data/lib/action_mailer/base.rb +99 -59
- data/lib/action_mailer/delivery_job.rb +9 -0
- data/lib/action_mailer/delivery_methods.rb +1 -1
- data/lib/action_mailer/gem_version.rb +4 -4
- data/lib/action_mailer/inline_preview_interceptor.rb +1 -3
- data/lib/action_mailer/log_subscriber.rb +6 -8
- data/lib/action_mailer/mail_delivery_job.rb +43 -0
- data/lib/action_mailer/mail_with_error_handling.rb +10 -0
- data/lib/action_mailer/message_delivery.rb +37 -3
- data/lib/action_mailer/parameterized.rb +25 -7
- data/lib/action_mailer/preview.rb +22 -6
- data/lib/action_mailer/railtie.rb +18 -12
- data/lib/action_mailer/test_case.rb +0 -2
- data/lib/action_mailer/test_helper.rb +33 -15
- data/lib/action_mailer.rb +4 -2
- data/lib/rails/generators/mailer/USAGE +2 -3
- data/lib/rails/generators/mailer/mailer_generator.rb +1 -1
- metadata +39 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edfeee145ed34cf3ca475a7fe83a825ac0723ab3ab30b17628d1b56a7a426ab7
|
4
|
+
data.tar.gz: 169d5c4dee4e8a19991a9a230a7568d4e4f73af6e3563b3396d39a7ee752fed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d95e0699d28e598fdb358f9fb00a469c2bf35731d09d257a085b9e751791712e9b3983b314a87d7f82ba40ea3eeb6e81e8a85aaaf03961f44f780a85bc85fcf0
|
7
|
+
data.tar.gz: eba41291a5d4414ba58350f61f436f220f7139eb482e6a47b5e15a51c089be1eb3f4c31ed274085b220fb8fb723f93574dcdf7bfb3b881b4be7b84eb8d123a36
|
data/CHANGELOG.md
CHANGED
@@ -1,114 +1,98 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 6.1.5 (March 09, 2022) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails
|
6
|
+
## Rails 6.1.4.7 (March 08, 2022) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails
|
11
|
+
## Rails 6.1.4.6 (February 11, 2022) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails
|
16
|
+
## Rails 6.1.4.5 (February 11, 2022) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails
|
21
|
+
## Rails 6.1.4.4 (December 15, 2021) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails
|
26
|
+
## Rails 6.1.4.3 (December 14, 2021) ##
|
27
27
|
|
28
28
|
* No changes.
|
29
29
|
|
30
30
|
|
31
|
-
## Rails
|
31
|
+
## Rails 6.1.4.2 (December 14, 2021) ##
|
32
32
|
|
33
33
|
* No changes.
|
34
34
|
|
35
35
|
|
36
|
-
## Rails
|
36
|
+
## Rails 6.1.4.1 (August 19, 2021) ##
|
37
37
|
|
38
38
|
* No changes.
|
39
39
|
|
40
40
|
|
41
|
-
## Rails
|
41
|
+
## Rails 6.1.4 (June 24, 2021) ##
|
42
42
|
|
43
43
|
* No changes.
|
44
44
|
|
45
45
|
|
46
|
-
## Rails
|
46
|
+
## Rails 6.1.3.2 (May 05, 2021) ##
|
47
47
|
|
48
48
|
* No changes.
|
49
49
|
|
50
50
|
|
51
|
-
## Rails
|
51
|
+
## Rails 6.1.3.1 (March 26, 2021) ##
|
52
52
|
|
53
53
|
* No changes.
|
54
54
|
|
55
55
|
|
56
|
-
## Rails
|
56
|
+
## Rails 6.1.3 (February 17, 2021) ##
|
57
57
|
|
58
58
|
* No changes.
|
59
59
|
|
60
60
|
|
61
|
-
## Rails
|
61
|
+
## Rails 6.1.2.1 (February 10, 2021) ##
|
62
62
|
|
63
63
|
* No changes.
|
64
64
|
|
65
65
|
|
66
|
-
## Rails
|
66
|
+
## Rails 6.1.2 (February 09, 2021) ##
|
67
67
|
|
68
68
|
* No changes.
|
69
69
|
|
70
70
|
|
71
|
-
## Rails
|
71
|
+
## Rails 6.1.1 (January 07, 2021) ##
|
72
72
|
|
73
|
-
*
|
74
|
-
|
75
|
-
|
76
|
-
## Rails 5.2.1.1 (November 27, 2018) ##
|
77
|
-
|
78
|
-
* No changes.
|
79
|
-
|
80
|
-
|
81
|
-
## Rails 5.2.1 (August 07, 2018) ##
|
82
|
-
|
83
|
-
* Ensure mail gem is eager autoloaded when eager load is true to prevent thread deadlocks.
|
84
|
-
|
85
|
-
*Samuel Cochran*
|
73
|
+
* Sets default mailer queue to `"default"` in the mail assertions.
|
86
74
|
|
75
|
+
*Paul Keen*
|
87
76
|
|
88
|
-
## Rails 5.2.0 (April 09, 2018) ##
|
89
77
|
|
90
|
-
|
91
|
-
since it was supported in Rails 5.0 but not deprecated.
|
78
|
+
## Rails 6.1.0 (December 09, 2020) ##
|
92
79
|
|
93
|
-
|
80
|
+
* Change default queue name of the deliver (`:mailers`) job to be the job adapter's
|
81
|
+
default (`:default`).
|
94
82
|
|
95
|
-
*
|
83
|
+
*Rafael Mendonça França*
|
96
84
|
|
97
|
-
|
98
|
-
ContactMailer.welcome.deliver_later
|
99
|
-
end
|
85
|
+
* Remove deprecated `ActionMailer::Base.receive` in favor of [Action Mailbox](https://github.com/rails/rails/tree/master/actionmailbox).
|
100
86
|
|
101
|
-
*
|
87
|
+
*Rafael Mendonça França*
|
102
88
|
|
103
|
-
*
|
89
|
+
* Fix ActionMailer assertions don't work for parameterized mail with legacy delivery job.
|
104
90
|
|
105
|
-
|
106
|
-
self.delivery_job = MyCustomDeliveryJob
|
91
|
+
*bogdanvlviv*
|
107
92
|
|
108
|
-
|
109
|
-
end
|
93
|
+
* Added `email_address_with_name` to properly escape addresses with names.
|
110
94
|
|
111
|
-
*
|
95
|
+
*Sunny Ripert*
|
112
96
|
|
113
97
|
|
114
|
-
Please check [
|
98
|
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actionmailer/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2004-
|
1
|
+
Copyright (c) 2004-2022 David Heinemeier Hansson
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -18,4 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
-
|
data/README.rdoc
CHANGED
@@ -13,6 +13,8 @@ Additionally, an Action Mailer class can be used to process incoming email,
|
|
13
13
|
such as allowing a blog to accept new posts from an email (which could even
|
14
14
|
have been sent from a phone).
|
15
15
|
|
16
|
+
You can read more about Action Mailer in the {Action Mailer Basics}[https://edgeguides.rubyonrails.org/action_mailer_basics.html] guide.
|
17
|
+
|
16
18
|
== Sending emails
|
17
19
|
|
18
20
|
The framework works by initializing any instance variables you want to be
|
@@ -93,42 +95,6 @@ Example:
|
|
93
95
|
.....
|
94
96
|
end
|
95
97
|
|
96
|
-
== Receiving emails
|
97
|
-
|
98
|
-
To receive emails, you need to implement a public instance method called
|
99
|
-
+receive+ that takes an email object as its single parameter. The Action Mailer
|
100
|
-
framework has a corresponding class method, which is also called +receive+, that
|
101
|
-
accepts a raw, unprocessed email as a string, which it then turns into the email
|
102
|
-
object and calls the receive instance method.
|
103
|
-
|
104
|
-
Example:
|
105
|
-
|
106
|
-
class Mailman < ActionMailer::Base
|
107
|
-
def receive(email)
|
108
|
-
page = Page.find_by(address: email.to.first)
|
109
|
-
page.emails.create(
|
110
|
-
subject: email.subject, body: email.body
|
111
|
-
)
|
112
|
-
|
113
|
-
if email.has_attachments?
|
114
|
-
email.attachments.each do |attachment|
|
115
|
-
page.attachments.create({
|
116
|
-
file: attachment, description: email.subject
|
117
|
-
})
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
This Mailman can be the target for Postfix or other MTAs. In Rails, you would use
|
124
|
-
the runner in the trivial case like this:
|
125
|
-
|
126
|
-
rails runner 'Mailman.receive(STDIN.read)'
|
127
|
-
|
128
|
-
However, invoking Rails in the runner for each mail to be received is very
|
129
|
-
resource intensive. A single instance of Rails should be run within a daemon, if
|
130
|
-
it is going to process more than just a limited amount of email.
|
131
|
-
|
132
98
|
== Configuration
|
133
99
|
|
134
100
|
The Base class has the full list of configuration options. Here's an example:
|
@@ -150,7 +116,7 @@ The latest version of Action Mailer can be installed with RubyGems:
|
|
150
116
|
|
151
117
|
Source code can be downloaded as part of the Rails project on GitHub:
|
152
118
|
|
153
|
-
* https://github.com/rails/rails/tree/
|
119
|
+
* https://github.com/rails/rails/tree/main/actionmailer
|
154
120
|
|
155
121
|
|
156
122
|
== License
|
@@ -164,7 +130,7 @@ Action Mailer is released under the MIT license:
|
|
164
130
|
|
165
131
|
API documentation is at
|
166
132
|
|
167
|
-
*
|
133
|
+
* https://api.rubyonrails.org
|
168
134
|
|
169
135
|
Bug reports for the Ruby on Rails project can be filed here:
|
170
136
|
|
@@ -172,4 +138,4 @@ Bug reports for the Ruby on Rails project can be filed here:
|
|
172
138
|
|
173
139
|
Feature requests should be discussed on the rails-core mailing list here:
|
174
140
|
|
175
|
-
* https://
|
141
|
+
* https://discuss.rubyonrails.org/c/rubyonrails-core
|
data/lib/action_mailer/base.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "action_mailer/mail_with_error_handling"
|
4
4
|
require "action_mailer/collector"
|
5
5
|
require "active_support/core_ext/string/inflections"
|
6
6
|
require "active_support/core_ext/hash/except"
|
@@ -16,11 +16,11 @@ module ActionMailer
|
|
16
16
|
#
|
17
17
|
# To use Action Mailer, you need to create a mailer model.
|
18
18
|
#
|
19
|
-
# $ rails generate mailer Notifier
|
19
|
+
# $ bin/rails generate mailer Notifier
|
20
20
|
#
|
21
21
|
# The generated model inherits from <tt>ApplicationMailer</tt> which in turn
|
22
22
|
# inherits from <tt>ActionMailer::Base</tt>. A mailer model defines methods
|
23
|
-
# used to generate an email message. In these methods, you can
|
23
|
+
# used to generate an email message. In these methods, you can set up variables to be used in
|
24
24
|
# the mailer views, options on the mail itself such as the <tt>:from</tt> address, and attachments.
|
25
25
|
#
|
26
26
|
# class ApplicationMailer < ActionMailer::Base
|
@@ -408,7 +408,7 @@ module ActionMailer
|
|
408
408
|
# really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
|
409
409
|
# of an OpenSSL verify constant (<tt>'none'</tt> or <tt>'peer'</tt>) or directly the constant
|
410
410
|
# (<tt>OpenSSL::SSL::VERIFY_NONE</tt> or <tt>OpenSSL::SSL::VERIFY_PEER</tt>).
|
411
|
-
#
|
411
|
+
# * <tt>:ssl/:tls</tt> Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)
|
412
412
|
#
|
413
413
|
# * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
|
414
414
|
# * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
|
@@ -455,10 +455,6 @@ module ActionMailer
|
|
455
455
|
|
456
456
|
PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout]
|
457
457
|
|
458
|
-
def _protected_ivars # :nodoc:
|
459
|
-
PROTECTED_IVARS
|
460
|
-
end
|
461
|
-
|
462
458
|
helper ActionMailer::MailHelper
|
463
459
|
|
464
460
|
class_attribute :delivery_job, default: ::ActionMailer::DeliveryJob
|
@@ -475,11 +471,21 @@ module ActionMailer
|
|
475
471
|
observers.flatten.compact.each { |observer| register_observer(observer) }
|
476
472
|
end
|
477
473
|
|
474
|
+
# Unregister one or more previously registered Observers.
|
475
|
+
def unregister_observers(*observers)
|
476
|
+
observers.flatten.compact.each { |observer| unregister_observer(observer) }
|
477
|
+
end
|
478
|
+
|
478
479
|
# Register one or more Interceptors which will be called before mail is sent.
|
479
480
|
def register_interceptors(*interceptors)
|
480
481
|
interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
|
481
482
|
end
|
482
483
|
|
484
|
+
# Unregister one or more previously registered Interceptors.
|
485
|
+
def unregister_interceptors(*interceptors)
|
486
|
+
interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
|
487
|
+
end
|
488
|
+
|
483
489
|
# Register an Observer which will be notified when mail is delivered.
|
484
490
|
# Either a class, string or symbol can be passed in as the Observer.
|
485
491
|
# If a string or symbol is passed in it will be camelized and constantized.
|
@@ -487,6 +493,13 @@ module ActionMailer
|
|
487
493
|
Mail.register_observer(observer_class_for(observer))
|
488
494
|
end
|
489
495
|
|
496
|
+
# Unregister a previously registered Observer.
|
497
|
+
# Either a class, string or symbol can be passed in as the Observer.
|
498
|
+
# If a string or symbol is passed in it will be camelized and constantized.
|
499
|
+
def unregister_observer(observer)
|
500
|
+
Mail.unregister_observer(observer_class_for(observer))
|
501
|
+
end
|
502
|
+
|
490
503
|
# Register an Interceptor which will be called before mail is sent.
|
491
504
|
# Either a class, string or symbol can be passed in as the Interceptor.
|
492
505
|
# If a string or symbol is passed in it will be camelized and constantized.
|
@@ -494,6 +507,13 @@ module ActionMailer
|
|
494
507
|
Mail.register_interceptor(observer_class_for(interceptor))
|
495
508
|
end
|
496
509
|
|
510
|
+
# Unregister a previously registered Interceptor.
|
511
|
+
# Either a class, string or symbol can be passed in as the Interceptor.
|
512
|
+
# If a string or symbol is passed in it will be camelized and constantized.
|
513
|
+
def unregister_interceptor(interceptor)
|
514
|
+
Mail.unregister_interceptor(observer_class_for(interceptor))
|
515
|
+
end
|
516
|
+
|
497
517
|
def observer_class_for(value) # :nodoc:
|
498
518
|
case value
|
499
519
|
when String, Symbol
|
@@ -527,27 +547,6 @@ module ActionMailer
|
|
527
547
|
# config.action_mailer.default_options = { from: "no-reply@example.org" }
|
528
548
|
alias :default_options= :default
|
529
549
|
|
530
|
-
# Receives a raw email, parses it into an email object, decodes it,
|
531
|
-
# instantiates a new mailer, and passes the email object to the mailer
|
532
|
-
# object's +receive+ method.
|
533
|
-
#
|
534
|
-
# If you want your mailer to be able to process incoming messages, you'll
|
535
|
-
# need to implement a +receive+ method that accepts the raw email string
|
536
|
-
# as a parameter:
|
537
|
-
#
|
538
|
-
# class MyMailer < ActionMailer::Base
|
539
|
-
# def receive(mail)
|
540
|
-
# # ...
|
541
|
-
# end
|
542
|
-
# end
|
543
|
-
def receive(raw_mail)
|
544
|
-
ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
|
545
|
-
mail = Mail.new(raw_mail)
|
546
|
-
set_payload_for_mail(payload, mail)
|
547
|
-
new.receive(mail)
|
548
|
-
end
|
549
|
-
end
|
550
|
-
|
551
550
|
# Wraps an email delivery inside of <tt>ActiveSupport::Notifications</tt> instrumentation.
|
552
551
|
#
|
553
552
|
# This method is actually called by the <tt>Mail::Message</tt> object itself
|
@@ -561,18 +560,26 @@ module ActionMailer
|
|
561
560
|
end
|
562
561
|
end
|
563
562
|
|
564
|
-
|
563
|
+
# Returns an email in the format "Name <email@example.com>".
|
564
|
+
def email_address_with_name(address, name)
|
565
|
+
Mail::Address.new.tap do |builder|
|
566
|
+
builder.address = address
|
567
|
+
builder.display_name = name
|
568
|
+
end.to_s
|
569
|
+
end
|
565
570
|
|
571
|
+
private
|
566
572
|
def set_payload_for_mail(payload, mail)
|
567
|
-
payload[:
|
568
|
-
payload[:
|
569
|
-
payload[:
|
570
|
-
payload[:
|
571
|
-
payload[:
|
572
|
-
payload[:
|
573
|
-
payload[:
|
574
|
-
payload[:
|
575
|
-
payload[:
|
573
|
+
payload[:mail] = mail.encoded
|
574
|
+
payload[:mailer] = name
|
575
|
+
payload[:message_id] = mail.message_id
|
576
|
+
payload[:subject] = mail.subject
|
577
|
+
payload[:to] = mail.to
|
578
|
+
payload[:from] = mail.from
|
579
|
+
payload[:bcc] = mail.bcc if mail.bcc.present?
|
580
|
+
payload[:cc] = mail.cc if mail.cc.present?
|
581
|
+
payload[:date] = mail.date
|
582
|
+
payload[:perform_deliveries] = mail.perform_deliveries
|
576
583
|
end
|
577
584
|
|
578
585
|
def method_missing(method_name, *args)
|
@@ -582,6 +589,7 @@ module ActionMailer
|
|
582
589
|
super
|
583
590
|
end
|
584
591
|
end
|
592
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
585
593
|
|
586
594
|
def respond_to_missing?(method, include_all = false)
|
587
595
|
action_methods.include?(method.to_s) || super
|
@@ -627,6 +635,11 @@ module ActionMailer
|
|
627
635
|
self.class.mailer_name
|
628
636
|
end
|
629
637
|
|
638
|
+
# Returns an email in the format "Name <email@example.com>".
|
639
|
+
def email_address_with_name(address, name)
|
640
|
+
self.class.email_address_with_name(address, name)
|
641
|
+
end
|
642
|
+
|
630
643
|
# Allows you to pass random and unusual headers to the new <tt>Mail::Message</tt>
|
631
644
|
# object which will add them to itself.
|
632
645
|
#
|
@@ -708,7 +721,7 @@ module ActionMailer
|
|
708
721
|
end
|
709
722
|
|
710
723
|
class LateAttachmentsProxy < SimpleDelegator
|
711
|
-
def inline;
|
724
|
+
def inline; self end
|
712
725
|
def []=(_name, _content); _raise_error end
|
713
726
|
|
714
727
|
private
|
@@ -829,8 +842,9 @@ module ActionMailer
|
|
829
842
|
@_mail_was_called = true
|
830
843
|
|
831
844
|
create_parts_from_responses(message, responses)
|
845
|
+
wrap_inline_attachments(message)
|
832
846
|
|
833
|
-
#
|
847
|
+
# Set up content type, reapply charset and handle parts order
|
834
848
|
message.content_type = set_content_type(message, content_type, headers[:content_type])
|
835
849
|
message.charset = charset
|
836
850
|
|
@@ -843,7 +857,6 @@ module ActionMailer
|
|
843
857
|
end
|
844
858
|
|
845
859
|
private
|
846
|
-
|
847
860
|
# Used by #mail to set the content type of the message.
|
848
861
|
#
|
849
862
|
# It will use the given +user_content_type+, or multipart if the mail
|
@@ -859,7 +872,7 @@ module ActionMailer
|
|
859
872
|
when user_content_type.present?
|
860
873
|
user_content_type
|
861
874
|
when m.has_attachments?
|
862
|
-
if m.attachments.
|
875
|
+
if m.attachments.all?(&:inline?)
|
863
876
|
["multipart", "related", params]
|
864
877
|
else
|
865
878
|
["multipart", "mixed", params]
|
@@ -877,7 +890,7 @@ module ActionMailer
|
|
877
890
|
# If the subject has interpolations, you can pass them through the +interpolations+ parameter.
|
878
891
|
def default_i18n_subject(interpolations = {}) # :doc:
|
879
892
|
mailer_scope = self.class.mailer_name.tr("/", ".")
|
880
|
-
I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
|
893
|
+
I18n.t(:subject, **interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
|
881
894
|
end
|
882
895
|
|
883
896
|
# Emails do not support relative path links.
|
@@ -886,12 +899,9 @@ module ActionMailer
|
|
886
899
|
end
|
887
900
|
|
888
901
|
def apply_defaults(headers)
|
889
|
-
default_values = self.class.default.
|
890
|
-
|
891
|
-
|
892
|
-
compute_default(value)
|
893
|
-
]
|
894
|
-
end.to_h
|
902
|
+
default_values = self.class.default.transform_values do |value|
|
903
|
+
compute_default(value)
|
904
|
+
end
|
895
905
|
|
896
906
|
headers_with_defaults = headers.reverse_merge(default_values)
|
897
907
|
headers_with_defaults[:subject] ||= default_i18n_subject
|
@@ -914,11 +924,9 @@ module ActionMailer
|
|
914
924
|
assignable.each { |k, v| message[k] = v }
|
915
925
|
end
|
916
926
|
|
917
|
-
def collect_responses(headers)
|
927
|
+
def collect_responses(headers, &block)
|
918
928
|
if block_given?
|
919
|
-
|
920
|
-
yield(collector)
|
921
|
-
collector.responses
|
929
|
+
collect_responses_from_block(headers, &block)
|
922
930
|
elsif headers[:body]
|
923
931
|
collect_responses_from_text(headers)
|
924
932
|
else
|
@@ -926,6 +934,13 @@ module ActionMailer
|
|
926
934
|
end
|
927
935
|
end
|
928
936
|
|
937
|
+
def collect_responses_from_block(headers)
|
938
|
+
templates_name = headers[:template_name] || action_name
|
939
|
+
collector = ActionMailer::Collector.new(lookup_context) { render(templates_name) }
|
940
|
+
yield(collector)
|
941
|
+
collector.responses
|
942
|
+
end
|
943
|
+
|
929
944
|
def collect_responses_from_text(headers)
|
930
945
|
[{
|
931
946
|
body: headers.delete(:body),
|
@@ -938,10 +953,10 @@ module ActionMailer
|
|
938
953
|
templates_name = headers[:template_name] || action_name
|
939
954
|
|
940
955
|
each_template(Array(templates_path), templates_name).map do |template|
|
941
|
-
|
956
|
+
format = template.format || self.formats.first
|
942
957
|
{
|
943
|
-
body: render(template: template),
|
944
|
-
content_type:
|
958
|
+
body: render(template: template, formats: [format]),
|
959
|
+
content_type: Mime[format].to_s
|
945
960
|
}
|
946
961
|
end
|
947
962
|
end
|
@@ -951,7 +966,28 @@ module ActionMailer
|
|
951
966
|
if templates.empty?
|
952
967
|
raise ActionView::MissingTemplate.new(paths, name, paths, false, "mailer")
|
953
968
|
else
|
954
|
-
templates.uniq(&:
|
969
|
+
templates.uniq(&:format).each(&block)
|
970
|
+
end
|
971
|
+
end
|
972
|
+
|
973
|
+
def wrap_inline_attachments(message)
|
974
|
+
# If we have both types of attachment, wrap all the inline attachments
|
975
|
+
# in multipart/related, but not the actual attachments
|
976
|
+
if message.attachments.detect(&:inline?) && message.attachments.detect { |a| !a.inline? }
|
977
|
+
related = Mail::Part.new
|
978
|
+
related.content_type = "multipart/related"
|
979
|
+
mixed = [ related ]
|
980
|
+
|
981
|
+
message.parts.each do |p|
|
982
|
+
if p.attachment? && !p.inline?
|
983
|
+
mixed << p
|
984
|
+
else
|
985
|
+
related.add_part(p)
|
986
|
+
end
|
987
|
+
end
|
988
|
+
|
989
|
+
message.parts.clear
|
990
|
+
mixed.each { |c| message.add_part(c) }
|
955
991
|
end
|
956
992
|
end
|
957
993
|
|
@@ -983,7 +1019,11 @@ module ActionMailer
|
|
983
1019
|
end
|
984
1020
|
|
985
1021
|
def instrument_name
|
986
|
-
"action_mailer"
|
1022
|
+
"action_mailer"
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def _protected_ivars
|
1026
|
+
PROTECTED_IVARS
|
987
1027
|
end
|
988
1028
|
|
989
1029
|
ActiveSupport.run_load_hooks(:action_mailer, self)
|
@@ -12,9 +12,18 @@ module ActionMailer
|
|
12
12
|
|
13
13
|
rescue_from StandardError, with: :handle_exception_with_mailer_class
|
14
14
|
|
15
|
+
before_perform do
|
16
|
+
ActiveSupport::Deprecation.warn <<~MSG.squish
|
17
|
+
Sending mail with DeliveryJob and Parameterized::DeliveryJob
|
18
|
+
is deprecated and will be removed in Rails 7.0.
|
19
|
+
Please use MailDeliveryJob instead.
|
20
|
+
MSG
|
21
|
+
end
|
22
|
+
|
15
23
|
def perform(mailer, mail_method, delivery_method, *args) #:nodoc:
|
16
24
|
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
|
17
25
|
end
|
26
|
+
ruby2_keywords(:perform) if respond_to?(:ruby2_keywords, true)
|
18
27
|
|
19
28
|
private
|
20
29
|
# "Deserialize" the mailer class name by hand in case another argument
|
@@ -49,7 +49,7 @@ module ActionMailer
|
|
49
49
|
# arguments: '-i'
|
50
50
|
def add_delivery_method(symbol, klass, default_options = {})
|
51
51
|
class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
|
52
|
-
|
52
|
+
public_send(:"#{symbol}_settings=", default_options)
|
53
53
|
self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
|
54
54
|
end
|
55
55
|
|
@@ -9,19 +9,17 @@ module ActionMailer
|
|
9
9
|
# An email was delivered.
|
10
10
|
def deliver(event)
|
11
11
|
info do
|
12
|
-
|
13
|
-
|
12
|
+
perform_deliveries = event.payload[:perform_deliveries]
|
13
|
+
if perform_deliveries
|
14
|
+
"Delivered mail #{event.payload[:message_id]} (#{event.duration.round(1)}ms)"
|
15
|
+
else
|
16
|
+
"Skipped delivery of mail #{event.payload[:message_id]} as `perform_deliveries` is false"
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
debug { event.payload[:mail] }
|
17
21
|
end
|
18
22
|
|
19
|
-
# An email was received.
|
20
|
-
def receive(event)
|
21
|
-
info { "Received mail (#{event.duration.round(1)}ms)" }
|
22
|
-
debug { event.payload[:mail] }
|
23
|
-
end
|
24
|
-
|
25
23
|
# An email was generated.
|
26
24
|
def process(event)
|
27
25
|
debug do
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_job"
|
4
|
+
|
5
|
+
module ActionMailer
|
6
|
+
# The <tt>ActionMailer::MailDeliveryJob</tt> class is used when you
|
7
|
+
# want to send emails outside of the request-response cycle. It supports
|
8
|
+
# sending either parameterized or normal mail.
|
9
|
+
#
|
10
|
+
# Exceptions are rescued and handled by the mailer class.
|
11
|
+
class MailDeliveryJob < ActiveJob::Base # :nodoc:
|
12
|
+
queue_as { ActionMailer::Base.deliver_later_queue_name }
|
13
|
+
|
14
|
+
rescue_from StandardError, with: :handle_exception_with_mailer_class
|
15
|
+
|
16
|
+
def perform(mailer, mail_method, delivery_method, args:, kwargs: nil, params: nil)
|
17
|
+
mailer_class = params ? mailer.constantize.with(params) : mailer.constantize
|
18
|
+
message = if kwargs
|
19
|
+
mailer_class.public_send(mail_method, *args, **kwargs)
|
20
|
+
else
|
21
|
+
mailer_class.public_send(mail_method, *args)
|
22
|
+
end
|
23
|
+
message.send(delivery_method)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
# "Deserialize" the mailer class name by hand in case another argument
|
28
|
+
# (like a Global ID reference) raised DeserializationError.
|
29
|
+
def mailer_class
|
30
|
+
if mailer = Array(@serialized_arguments).first || Array(arguments).first
|
31
|
+
mailer.constantize
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_exception_with_mailer_class(exception)
|
36
|
+
if klass = mailer_class
|
37
|
+
klass.handle_exception exception
|
38
|
+
else
|
39
|
+
raise exception
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "mail"
|
5
|
+
rescue LoadError => error
|
6
|
+
if error.message.match?(/net-smtp/)
|
7
|
+
$stderr.puts "You don't have net-smtp installed in your application. Please add it to your Gemfile and run bundle install"
|
8
|
+
raise
|
9
|
+
end
|
10
|
+
end
|
@@ -23,13 +23,14 @@ module ActionMailer
|
|
23
23
|
@processed_mailer = nil
|
24
24
|
@mail_message = nil
|
25
25
|
end
|
26
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
26
27
|
|
27
28
|
# Method calls are delegated to the Mail::Message that's ready to deliver.
|
28
29
|
def __getobj__ #:nodoc:
|
29
30
|
@mail_message ||= processed_mailer.message
|
30
31
|
end
|
31
32
|
|
32
|
-
# Unused except for delegator internals (dup,
|
33
|
+
# Unused except for delegator internals (dup, marshalling).
|
33
34
|
def __setobj__(mail_message) #:nodoc:
|
34
35
|
@mail_message = mail_message
|
35
36
|
end
|
@@ -52,12 +53,14 @@ module ActionMailer
|
|
52
53
|
# Notifier.welcome(User.first).deliver_later!
|
53
54
|
# Notifier.welcome(User.first).deliver_later!(wait: 1.hour)
|
54
55
|
# Notifier.welcome(User.first).deliver_later!(wait_until: 10.hours.from_now)
|
56
|
+
# Notifier.welcome(User.first).deliver_later!(priority: 10)
|
55
57
|
#
|
56
58
|
# Options:
|
57
59
|
#
|
58
60
|
# * <tt>:wait</tt> - Enqueue the email to be delivered with a delay
|
59
61
|
# * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time
|
60
62
|
# * <tt>:queue</tt> - Enqueue the email on the specified queue
|
63
|
+
# * <tt>:priority</tt> - Enqueues the email with the specified priority
|
61
64
|
#
|
62
65
|
# By default, the email will be enqueued using <tt>ActionMailer::DeliveryJob</tt>. Each
|
63
66
|
# <tt>ActionMailer::Base</tt> class can specify the job to use by setting the class variable
|
@@ -76,12 +79,14 @@ module ActionMailer
|
|
76
79
|
# Notifier.welcome(User.first).deliver_later
|
77
80
|
# Notifier.welcome(User.first).deliver_later(wait: 1.hour)
|
78
81
|
# Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now)
|
82
|
+
# Notifier.welcome(User.first).deliver_later(priority: 10)
|
79
83
|
#
|
80
84
|
# Options:
|
81
85
|
#
|
82
86
|
# * <tt>:wait</tt> - Enqueue the email to be delivered with a delay.
|
83
87
|
# * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time.
|
84
88
|
# * <tt>:queue</tt> - Enqueue the email on the specified queue.
|
89
|
+
# * <tt>:priority</tt> - Enqueues the email with the specified priority
|
85
90
|
#
|
86
91
|
# By default, the email will be enqueued using <tt>ActionMailer::DeliveryJob</tt>. Each
|
87
92
|
# <tt>ActionMailer::Base</tt> class can specify the job to use by setting the class variable
|
@@ -135,9 +140,38 @@ module ActionMailer
|
|
135
140
|
"#deliver_later, 2. only touch the message *within your mailer " \
|
136
141
|
"method*, or 3. use a custom Active Job instead of #deliver_later."
|
137
142
|
else
|
138
|
-
args = @mailer_class.name, @action.to_s, delivery_method.to_s, *@args
|
139
143
|
job = @mailer_class.delivery_job
|
140
|
-
|
144
|
+
|
145
|
+
if use_new_args?(job)
|
146
|
+
job.set(options).perform_later(
|
147
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, args: @args)
|
148
|
+
elsif job <= DeliveryJob
|
149
|
+
job.set(options).perform_later(
|
150
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, *@args)
|
151
|
+
else
|
152
|
+
ActiveSupport::Deprecation.warn(<<~EOM)
|
153
|
+
In Rails 7.0, Action Mailer will pass the mail arguments inside the `:args` keyword argument.
|
154
|
+
The `perform` method of the #{job} needs to change and forward the mail arguments
|
155
|
+
from the `args` keyword argument.
|
156
|
+
|
157
|
+
The `perform` method should now look like:
|
158
|
+
|
159
|
+
`def perform(mailer, mail_method, delivery, args:)`
|
160
|
+
EOM
|
161
|
+
|
162
|
+
job.set(options).perform_later(
|
163
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, *@args)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def use_new_args?(job)
|
169
|
+
parameters = job.public_instance_method(:perform).parameters
|
170
|
+
|
171
|
+
parameters.find do |key, name|
|
172
|
+
return true if key == :keyreq && name == :args
|
173
|
+
|
174
|
+
key == :keyrest and name != :**
|
141
175
|
end
|
142
176
|
end
|
143
177
|
end
|
@@ -115,17 +115,26 @@ module ActionMailer
|
|
115
115
|
super
|
116
116
|
end
|
117
117
|
end
|
118
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
118
119
|
|
119
120
|
def respond_to_missing?(method, include_all = false)
|
120
121
|
@mailer.respond_to?(method, include_all)
|
121
122
|
end
|
122
123
|
end
|
123
124
|
|
125
|
+
class DeliveryJob < ActionMailer::DeliveryJob # :nodoc:
|
126
|
+
def perform(mailer, mail_method, delivery_method, params, *args)
|
127
|
+
mailer.constantize.with(params).public_send(mail_method, *args).send(delivery_method)
|
128
|
+
end
|
129
|
+
ruby2_keywords(:perform) if respond_to?(:ruby2_keywords, true)
|
130
|
+
end
|
131
|
+
|
124
132
|
class MessageDelivery < ActionMailer::MessageDelivery # :nodoc:
|
125
133
|
def initialize(mailer_class, action, params, *args)
|
126
134
|
super(mailer_class, action, *args)
|
127
135
|
@params = params
|
128
136
|
end
|
137
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
129
138
|
|
130
139
|
private
|
131
140
|
def processed_mailer
|
@@ -139,16 +148,25 @@ module ActionMailer
|
|
139
148
|
if processed?
|
140
149
|
super
|
141
150
|
else
|
142
|
-
|
143
|
-
|
151
|
+
job = delivery_job_class
|
152
|
+
|
153
|
+
if job <= MailDeliveryJob
|
154
|
+
job.set(options).perform_later(
|
155
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, params: @params, args: @args)
|
156
|
+
else
|
157
|
+
job.set(options).perform_later(
|
158
|
+
@mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args)
|
159
|
+
end
|
144
160
|
end
|
145
161
|
end
|
146
|
-
end
|
147
162
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
163
|
+
def delivery_job_class
|
164
|
+
if @mailer_class.delivery_job <= MailDeliveryJob
|
165
|
+
@mailer_class.delivery_job
|
166
|
+
else
|
167
|
+
Parameterized::DeliveryJob
|
168
|
+
end
|
169
|
+
end
|
152
170
|
end
|
153
171
|
end
|
154
172
|
end
|
@@ -31,22 +31,38 @@ module ActionMailer
|
|
31
31
|
interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
|
32
32
|
end
|
33
33
|
|
34
|
+
# Unregister one or more previously registered Interceptors.
|
35
|
+
def unregister_preview_interceptors(*interceptors)
|
36
|
+
interceptors.flatten.compact.each { |interceptor| unregister_preview_interceptor(interceptor) }
|
37
|
+
end
|
38
|
+
|
34
39
|
# Register an Interceptor which will be called before mail is previewed.
|
35
40
|
# Either a class or a string can be passed in as the Interceptor. If a
|
36
41
|
# string is passed in it will be constantized.
|
37
42
|
def register_preview_interceptor(interceptor)
|
38
|
-
preview_interceptor =
|
43
|
+
preview_interceptor = interceptor_class_for(interceptor)
|
44
|
+
|
45
|
+
unless preview_interceptors.include?(preview_interceptor)
|
46
|
+
preview_interceptors << preview_interceptor
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Unregister a previously registered Interceptor.
|
51
|
+
# Either a class or a string can be passed in as the Interceptor. If a
|
52
|
+
# string is passed in it will be constantized.
|
53
|
+
def unregister_preview_interceptor(interceptor)
|
54
|
+
preview_interceptors.delete(interceptor_class_for(interceptor))
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def interceptor_class_for(interceptor)
|
39
59
|
case interceptor
|
40
60
|
when String, Symbol
|
41
61
|
interceptor.to_s.camelize.constantize
|
42
62
|
else
|
43
63
|
interceptor
|
44
64
|
end
|
45
|
-
|
46
|
-
unless preview_interceptors.include?(preview_interceptor)
|
47
|
-
preview_interceptors << preview_interceptor
|
48
65
|
end
|
49
|
-
end
|
50
66
|
end
|
51
67
|
end
|
52
68
|
|
@@ -98,7 +114,7 @@ module ActionMailer
|
|
98
114
|
|
99
115
|
# Returns the underscored name of the mailer preview without the suffix.
|
100
116
|
def preview_name
|
101
|
-
name.
|
117
|
+
name.delete_suffix("Preview").underscore
|
102
118
|
end
|
103
119
|
|
104
120
|
private
|
@@ -18,11 +18,6 @@ module ActionMailer
|
|
18
18
|
paths = app.config.paths
|
19
19
|
options = app.config.action_mailer
|
20
20
|
|
21
|
-
if app.config.force_ssl
|
22
|
-
options.default_url_options ||= {}
|
23
|
-
options.default_url_options[:protocol] ||= "https"
|
24
|
-
end
|
25
|
-
|
26
21
|
options.assets_dir ||= paths["public"].first
|
27
22
|
options.javascripts_dir ||= paths["public/javascripts"].first
|
28
23
|
options.stylesheets_dir ||= paths["public/stylesheets"].first
|
@@ -46,10 +41,25 @@ module ActionMailer
|
|
46
41
|
register_preview_interceptors(options.delete(:preview_interceptors))
|
47
42
|
register_observers(options.delete(:observers))
|
48
43
|
|
44
|
+
if delivery_job = options.delete(:delivery_job)
|
45
|
+
self.delivery_job = delivery_job.constantize
|
46
|
+
end
|
47
|
+
|
49
48
|
options.each { |k, v| send("#{k}=", v) }
|
50
49
|
end
|
51
50
|
|
52
|
-
ActiveSupport.on_load(:action_dispatch_integration_test)
|
51
|
+
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
52
|
+
include ActionMailer::TestHelper
|
53
|
+
include ActionMailer::TestCase::ClearTestDeliveries
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
initializer "action_mailer.set_autoload_paths" do |app|
|
58
|
+
options = app.config.action_mailer
|
59
|
+
|
60
|
+
if options.show_previews && options.preview_path
|
61
|
+
ActiveSupport::Dependencies.autoload_paths << options.preview_path
|
62
|
+
end
|
53
63
|
end
|
54
64
|
|
55
65
|
initializer "action_mailer.compile_config_methods" do
|
@@ -69,12 +79,8 @@ module ActionMailer
|
|
69
79
|
|
70
80
|
if options.show_previews
|
71
81
|
app.routes.prepend do
|
72
|
-
get "/rails/mailers"
|
73
|
-
get "/rails/mailers/*path"
|
74
|
-
end
|
75
|
-
|
76
|
-
if options.preview_path
|
77
|
-
ActiveSupport::Dependencies.autoload_paths << options.preview_path
|
82
|
+
get "/rails/mailers" => "rails/mailers#index", internal: true
|
83
|
+
get "/rails/mailers/*path" => "rails/mailers#preview", internal: true
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
@@ -22,7 +22,6 @@ module ActionMailer
|
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
|
-
|
26
25
|
def clear_test_deliveries
|
27
26
|
if ActionMailer::Base.delivery_method == :test
|
28
27
|
ActionMailer::Base.deliveries.clear
|
@@ -76,7 +75,6 @@ module ActionMailer
|
|
76
75
|
end
|
77
76
|
|
78
77
|
private
|
79
|
-
|
80
78
|
def initialize_test_deliveries
|
81
79
|
set_delivery_method :test
|
82
80
|
@old_perform_deliveries = ActionMailer::Base.perform_deliveries
|
@@ -28,13 +28,13 @@ module ActionMailer
|
|
28
28
|
#
|
29
29
|
# assert_emails 2 do
|
30
30
|
# ContactMailer.welcome.deliver_now
|
31
|
-
# ContactMailer.welcome.
|
31
|
+
# ContactMailer.welcome.deliver_later
|
32
32
|
# end
|
33
33
|
# end
|
34
|
-
def assert_emails(number)
|
34
|
+
def assert_emails(number, &block)
|
35
35
|
if block_given?
|
36
36
|
original_count = ActionMailer::Base.deliveries.size
|
37
|
-
|
37
|
+
perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, &block)
|
38
38
|
new_count = ActionMailer::Base.deliveries.size
|
39
39
|
assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
|
40
40
|
else
|
@@ -90,10 +90,23 @@ module ActionMailer
|
|
90
90
|
# end
|
91
91
|
# end
|
92
92
|
def assert_enqueued_emails(number, &block)
|
93
|
-
assert_enqueued_jobs
|
93
|
+
assert_enqueued_jobs(number, only: ->(job) { delivery_job_filter(job) }, &block)
|
94
94
|
end
|
95
95
|
|
96
|
-
# Asserts that
|
96
|
+
# Asserts that a specific email has been enqueued, optionally
|
97
|
+
# matching arguments.
|
98
|
+
#
|
99
|
+
# def test_email
|
100
|
+
# ContactMailer.welcome.deliver_later
|
101
|
+
# assert_enqueued_email_with ContactMailer, :welcome
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# def test_email_with_arguments
|
105
|
+
# ContactMailer.welcome("Hello", "Goodbye").deliver_later
|
106
|
+
# assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# If a block is passed, that block should cause the specified email
|
97
110
|
# to be enqueued.
|
98
111
|
#
|
99
112
|
# def test_email_in_block
|
@@ -106,20 +119,17 @@ module ActionMailer
|
|
106
119
|
#
|
107
120
|
# def test_parameterized_email
|
108
121
|
# assert_enqueued_email_with ContactMailer, :welcome,
|
109
|
-
# args: {email: 'user@example.com} do
|
122
|
+
# args: {email: 'user@example.com'} do
|
110
123
|
# ContactMailer.with(email: 'user@example.com').welcome.deliver_later
|
111
124
|
# end
|
112
125
|
# end
|
113
|
-
def assert_enqueued_email_with(mailer, method, args: nil, queue: "
|
114
|
-
if args.is_a?
|
115
|
-
|
116
|
-
args = [mailer.to_s, method.to_s, "deliver_now", args]
|
126
|
+
def assert_enqueued_email_with(mailer, method, args: nil, queue: ActionMailer::Base.deliver_later_queue_name || "default", &block)
|
127
|
+
args = if args.is_a?(Hash)
|
128
|
+
[mailer.to_s, method.to_s, "deliver_now", params: args, args: []]
|
117
129
|
else
|
118
|
-
|
119
|
-
args = [mailer.to_s, method.to_s, "deliver_now", *args]
|
130
|
+
[mailer.to_s, method.to_s, "deliver_now", args: Array(args)]
|
120
131
|
end
|
121
|
-
|
122
|
-
assert_enqueued_with(job: job, args: args, queue: queue, &block)
|
132
|
+
assert_enqueued_with(job: mailer.delivery_job, args: args, queue: queue.to_s, &block)
|
123
133
|
end
|
124
134
|
|
125
135
|
# Asserts that no emails are enqueued for later delivery.
|
@@ -138,7 +148,15 @@ module ActionMailer
|
|
138
148
|
# end
|
139
149
|
# end
|
140
150
|
def assert_no_enqueued_emails(&block)
|
141
|
-
|
151
|
+
assert_enqueued_emails 0, &block
|
142
152
|
end
|
153
|
+
|
154
|
+
private
|
155
|
+
def delivery_job_filter(job)
|
156
|
+
job_class = job.is_a?(Hash) ? job.fetch(:job) : job.class
|
157
|
+
|
158
|
+
Base.descendants.map(&:delivery_job).include?(job_class) ||
|
159
|
+
ActionMailer::Parameterized::DeliveryJob == job_class
|
160
|
+
end
|
143
161
|
end
|
144
162
|
end
|
data/lib/action_mailer.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2022 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -52,11 +52,12 @@ module ActionMailer
|
|
52
52
|
autoload :TestHelper
|
53
53
|
autoload :MessageDelivery
|
54
54
|
autoload :DeliveryJob
|
55
|
+
autoload :MailDeliveryJob
|
55
56
|
|
56
57
|
def self.eager_load!
|
57
58
|
super
|
58
59
|
|
59
|
-
require "
|
60
|
+
require "action_mailer/mail_with_error_handling"
|
60
61
|
Mail.eager_autoload!
|
61
62
|
end
|
62
63
|
end
|
@@ -66,4 +67,5 @@ autoload :Mime, "action_dispatch/http/mime_type"
|
|
66
67
|
ActiveSupport.on_load(:action_view) do
|
67
68
|
ActionView::Base.default_formats ||= Mime::SET.symbols
|
68
69
|
ActionView::Template::Types.delegate_to Mime
|
70
|
+
ActionView::LookupContext::DetailsKey.clear
|
69
71
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Description:
|
2
2
|
============
|
3
|
-
|
3
|
+
Generates a new mailer and its views. Passes the mailer name, either
|
4
4
|
CamelCased or under_scored, and an optional list of emails as arguments.
|
5
5
|
|
6
6
|
This generates a mailer class in app/mailers and invokes your template
|
@@ -8,10 +8,9 @@ Description:
|
|
8
8
|
|
9
9
|
Example:
|
10
10
|
========
|
11
|
-
rails generate mailer Notifications signup forgot_password invoice
|
11
|
+
bin/rails generate mailer Notifications signup forgot_password invoice
|
12
12
|
|
13
13
|
creates a Notifications mailer class, views, and test:
|
14
14
|
Mailer: app/mailers/notifications_mailer.rb
|
15
15
|
Views: app/views/notifications_mailer/signup.text.erb [...]
|
16
16
|
Test: test/mailers/notifications_mailer_test.rb
|
17
|
-
|
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionmailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.1.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.1.5
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: actionpack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - '='
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
33
|
+
version: 6.1.5
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
38
|
- - '='
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
40
|
+
version: 6.1.5
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: actionview
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - '='
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
47
|
+
version: 6.1.5
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
52
|
- - '='
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
54
|
+
version: 6.1.5
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: activejob
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - '='
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
61
|
+
version: 6.1.5
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - '='
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
68
|
+
version: 6.1.5
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: mail
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,8 +100,8 @@ dependencies:
|
|
86
100
|
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
102
|
version: '2.0'
|
89
|
-
description: Email on Rails. Compose, deliver,
|
90
|
-
|
103
|
+
description: Email on Rails. Compose, deliver, and test emails using the familiar
|
104
|
+
controller/view pattern. First-class support for multipart email and attachments.
|
91
105
|
email: david@loudthinking.com
|
92
106
|
executables: []
|
93
107
|
extensions: []
|
@@ -104,7 +118,9 @@ files:
|
|
104
118
|
- lib/action_mailer/gem_version.rb
|
105
119
|
- lib/action_mailer/inline_preview_interceptor.rb
|
106
120
|
- lib/action_mailer/log_subscriber.rb
|
121
|
+
- lib/action_mailer/mail_delivery_job.rb
|
107
122
|
- lib/action_mailer/mail_helper.rb
|
123
|
+
- lib/action_mailer/mail_with_error_handling.rb
|
108
124
|
- lib/action_mailer/message_delivery.rb
|
109
125
|
- lib/action_mailer/parameterized.rb
|
110
126
|
- lib/action_mailer/preview.rb
|
@@ -117,13 +133,17 @@ files:
|
|
117
133
|
- lib/rails/generators/mailer/mailer_generator.rb
|
118
134
|
- lib/rails/generators/mailer/templates/application_mailer.rb.tt
|
119
135
|
- lib/rails/generators/mailer/templates/mailer.rb.tt
|
120
|
-
homepage:
|
136
|
+
homepage: https://rubyonrails.org
|
121
137
|
licenses:
|
122
138
|
- MIT
|
123
139
|
metadata:
|
124
|
-
|
125
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
126
|
-
|
140
|
+
bug_tracker_uri: https://github.com/rails/rails/issues
|
141
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.5/actionmailer/CHANGELOG.md
|
142
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.5/
|
143
|
+
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
144
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.5/actionmailer
|
145
|
+
rubygems_mfa_required: 'true'
|
146
|
+
post_install_message:
|
127
147
|
rdoc_options: []
|
128
148
|
require_paths:
|
129
149
|
- lib
|
@@ -131,7 +151,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
151
|
requirements:
|
132
152
|
- - ">="
|
133
153
|
- !ruby/object:Gem::Version
|
134
|
-
version: 2.
|
154
|
+
version: 2.5.0
|
135
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
156
|
requirements:
|
137
157
|
- - ">="
|
@@ -139,8 +159,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
159
|
version: '0'
|
140
160
|
requirements:
|
141
161
|
- none
|
142
|
-
rubygems_version: 3.
|
143
|
-
signing_key:
|
162
|
+
rubygems_version: 3.3.7
|
163
|
+
signing_key:
|
144
164
|
specification_version: 4
|
145
|
-
summary: Email composition
|
165
|
+
summary: Email composition and delivery framework (part of Rails).
|
146
166
|
test_files: []
|