From efeddb08dae3dc6240118444234e3acdcfdffaa1 Mon Sep 17 00:00:00 2001
From: Isaac Betesh <iybetesh@gmail.com>
Date: Thu, 9 May 2019 12:38:58 -0700
Subject: Prevent reading inline attachments after `mail` was called from
 raising an inaccurate exception

Without this change, `attachments.inline['my_attachment'].present?`, for example,
would raise the exception `Can't add attachments after mail was called`.

I first brought this issue up at https://github.com/rails/rails/issues/16163#issuecomment-437378347.

Note that this commit addresses only one of the 2 problems I described in that comment.
The other problem is that using `attachments.inline['my_attachment']` for reading an
attachment is unnecessary--it's the same as `attachments['my_attachment']`--even before
`mail` is called.  We could add a warning about the unnecessary use of `inline` but I'm
saving that for a later PR since my comment has not received any feedback yet.
---
 actionmailer/lib/action_mailer/base.rb |  2 +-
 actionmailer/test/base_test.rb         | 11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index c1ac9c2ad1..93e7a30e4f 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -738,7 +738,7 @@ module ActionMailer
     end
 
     class LateAttachmentsProxy < SimpleDelegator
-      def inline; _raise_error end
+      def inline; self end
       def []=(_name, _content); _raise_error end
 
       private
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb
index c07fca5b5e..0bfd12cd3e 100644
--- a/actionmailer/test/base_test.rb
+++ b/actionmailer/test/base_test.rb
@@ -267,6 +267,17 @@ class BaseTest < ActiveSupport::TestCase
     assert_match(/Can't add attachments after `mail` was called./, e.message)
   end
 
+  test "accessing inline attachments after mail was called works" do
+    class LateInlineAttachmentMailer < ActionMailer::Base
+      def welcome
+        mail body: "yay", from: "welcome@example.com", to: "to@example.com"
+        attachments.inline["invoice.pdf"]
+      end
+    end
+
+    assert_nothing_raised { LateInlineAttachmentMailer.welcome.message }
+  end
+
   test "adding inline attachments while rendering mail works" do
     class LateInlineAttachmentMailer < ActionMailer::Base
       def on_render
-- 
cgit v1.2.3