diff options
Diffstat (limited to 'actionmailer')
-rw-r--r-- | actionmailer/CHANGELOG.md | 4 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 7 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/inline_preview_interceptor.rb | 6 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/parameterized.rb | 42 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/test_helper.rb | 4 | ||||
-rw-r--r-- | actionmailer/test/base_test.rb | 19 | ||||
-rw-r--r-- | actionmailer/test/parameterized_test.rb | 16 | ||||
-rw-r--r-- | actionmailer/test/test_helper_test.rb | 18 |
8 files changed, 89 insertions, 27 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 54b07a626b..6ec10c7a70 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,3 +1,7 @@ +* Add `:args` to `process.action_mailer` event. + + *Yuji Yaginuma* + * Add parameterized invocation of mailers as a way to share before filters and defaults between actions. See ActionMailer::Parameterized for a full example of the benefit. diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index c0c030ac3e..9b5d39faea 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -428,7 +428,7 @@ module ActionMailer # * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with # <tt>delivery_method :test</tt>. Most useful for unit and functional testing. # - # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>. + # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>. Defaults to +mailers+. class Base < AbstractController::Base include DeliveryMethods include Rescuable @@ -598,7 +598,8 @@ module ActionMailer def process(method_name, *args) #:nodoc: payload = { mailer: self.class.name, - action: method_name + action: method_name, + args: args } ActiveSupport::Notifications.instrument("process.action_mailer", payload) do @@ -971,7 +972,7 @@ module ActionMailer end def instrument_name - "action_mailer" + "action_mailer".freeze end ActiveSupport.run_load_hooks(:action_mailer, self) diff --git a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb index 9087d335fa..980415afe0 100644 --- a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb +++ b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb @@ -26,7 +26,7 @@ module ActionMailer def transform! #:nodoc: return message if html_part.blank? - html_source.gsub!(PATTERN) do |match| + html_part.body = html_part.decoded.gsub(PATTERN) do |match| if part = find_part(match[9..-2]) %[src="#{data_url(part)}"] else @@ -46,10 +46,6 @@ module ActionMailer @html_part ||= message.html_part end - def html_source - html_part.body.raw_source - end - def data_url(part) "data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}" end diff --git a/actionmailer/lib/action_mailer/parameterized.rb b/actionmailer/lib/action_mailer/parameterized.rb index a0a5db7427..3acacc1f14 100644 --- a/actionmailer/lib/action_mailer/parameterized.rb +++ b/actionmailer/lib/action_mailer/parameterized.rb @@ -71,7 +71,7 @@ module ActionMailer # @project = params[:project] # @summarizer = ProjectInvitationSummarizer.new(@project.bucket) # - # mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})" + # mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})" # end # # def bulk_project_invitation @@ -82,9 +82,6 @@ module ActionMailer # end # # InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later - # - # That's a big improvement! It's also fully backwards compatible. So you can start to gradually transition - # mailers that stand to benefit the most from parameterization one by one and leave the others behind. module Parameterized extend ActiveSupport::Concern @@ -92,33 +89,46 @@ module ActionMailer attr_accessor :params end - class_methods do + module ClassMethods + # Provide the parameters to the mailer in order to use them in the instance methods and callbacks. + # + # InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later + # + # See Parameterized documentation for full example. def with(params) ActionMailer::Parameterized::Mailer.new(self, params) end end - class Mailer + class Mailer # :nodoc: def initialize(mailer, params) @mailer, @params = mailer, params end - def method_missing(method_name, *args) - if @mailer.action_methods.include?(method_name.to_s) - ActionMailer::Parameterized::MessageDelivery.new(@mailer, method_name, *args).tap { |pmd| pmd.params = @params } - else - super + private + def method_missing(method_name, *args) + if @mailer.action_methods.include?(method_name.to_s) + ActionMailer::Parameterized::MessageDelivery.new(@mailer, method_name, @params, *args) + else + super + end + end + + def respond_to_missing?(method, include_all = false) + @mailer.respond_to?(method, include_all) end - end end - class MessageDelivery < ActionMailer::MessageDelivery - attr_accessor :params + class MessageDelivery < ActionMailer::MessageDelivery # :nodoc: + def initialize(mailer_class, action, params, *args) + super(mailer_class, action, *args) + @params = params + end private def processed_mailer @processed_mailer ||= @mailer_class.new.tap do |mailer| - mailer.params = params + mailer.params = @params mailer.process @action, *@args end end @@ -134,7 +144,7 @@ module ActionMailer end class DeliveryJob < ActionMailer::DeliveryJob # :nodoc: - def perform(mailer, mail_method, delivery_method, params, *args) #:nodoc: + def perform(mailer, mail_method, delivery_method, params, *args) mailer.constantize.with(params).public_send(mail_method, *args).send(delivery_method) end end diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb index c17ecad4c6..c30fb1fc18 100644 --- a/actionmailer/lib/action_mailer/test_helper.rb +++ b/actionmailer/lib/action_mailer/test_helper.rb @@ -88,7 +88,7 @@ module ActionMailer # end # end def assert_enqueued_emails(number, &block) - assert_enqueued_jobs number, only: ActionMailer::DeliveryJob, &block + assert_enqueued_jobs number, only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block end # Asserts that no emails are enqueued for later delivery. @@ -107,7 +107,7 @@ module ActionMailer # end # end def assert_no_enqueued_emails(&block) - assert_no_enqueued_jobs only: ActionMailer::DeliveryJob, &block + assert_no_enqueued_jobs only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block end end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 490aaf33fc..61960d411d 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -834,6 +834,25 @@ class BaseTest < ActiveSupport::TestCase assert_equal "special indeed!", mail["X-Special-Header"].to_s end + test "notification for process" do + begin + events = [] + ActiveSupport::Notifications.subscribe("process.action_mailer") do |*args| + events << ActiveSupport::Notifications::Event.new(*args) + end + + BaseMailer.welcome(body: "Hello there").deliver_now + + assert_equal 1, events.length + assert_equal "process.action_mailer", events[0].name + assert_equal "BaseMailer", events[0].payload[:mailer] + assert_equal :welcome, events[0].payload[:action] + assert_equal [{ body: "Hello there" }], events[0].payload[:args] + ensure + ActiveSupport::Notifications.unsubscribe "process.action_mailer" + end + end + private # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/parameterized_test.rb b/actionmailer/test/parameterized_test.rb index f52945590b..914ed12312 100644 --- a/actionmailer/test/parameterized_test.rb +++ b/actionmailer/test/parameterized_test.rb @@ -33,9 +33,23 @@ class ParameterizedTest < ActiveSupport::TestCase assert_equal("So says david@basecamp.com", @mail.body.encoded) end - test "should enqueue the email with params" do + test "enqueue the email with params" do assert_performed_with(job: ActionMailer::Parameterized::DeliveryJob, args: ["ParamsMailer", "invitation", "deliver_now", { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" } ]) do @mail.deliver_later end end + + test "respond_to?" do + mailer = ParamsMailer.with(inviter: "david@basecamp.com", invitee: "jason@basecamp.com") + + assert_respond_to mailer, :invitation + assert_not_respond_to mailer, :anything + + invitation = mailer.method(:invitation) + assert_equal Method, invitation.class + + assert_raises(NameError) do + invitation = mailer.method(:anything) + end + end end diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 31ac5a5211..876e9b0634 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -143,6 +143,16 @@ class TestHelperMailerTest < ActionMailer::TestCase end end + def test_assert_enqueued_parameterized_emails + assert_nothing_raised do + assert_enqueued_emails 1 do + silence_stream($stdout) do + TestHelperMailer.with(a: 1).test.deliver_later + end + end + end + end + def test_assert_enqueued_emails_too_few_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_enqueued_emails 2 do @@ -176,6 +186,14 @@ class TestHelperMailerTest < ActionMailer::TestCase end end + def test_assert_no_enqueued_parameterized_emails + assert_nothing_raised do + assert_no_enqueued_emails do + TestHelperMailer.with(a: 1).test.deliver_now + end + end + end + def test_assert_no_enqueued_emails_failure error = assert_raise ActiveSupport::TestCase::Assertion do assert_no_enqueued_emails do |