diff --git a/lib/courrier/email/options.rb b/lib/courrier/email/options.rb index 1506b6b..b5fb50f 100644 --- a/lib/courrier/email/options.rb +++ b/lib/courrier/email/options.rb @@ -56,7 +56,10 @@ def wrap(content, with_layout:) next wrapped if !layout - layout % {content: wrapped} + # A plain substitution, not `String#%`: an HTML layout routinely carries a + # bare `%` (`width: 100%`, an encoded URL), and `format` raises on those. + # The block form also keeps the content verbatim when it contains `\1`, `\\`, etc. + layout.gsub("%{content}") { wrapped } end end diff --git a/test/courrier/email/options_test.rb b/test/courrier/email/options_test.rb new file mode 100644 index 0000000..b8dbbcd --- /dev/null +++ b/test/courrier/email/options_test.rb @@ -0,0 +1,44 @@ +require "test_helper" + +class Courrier::Email::OptionsTest < Minitest::Test + def test_layout_wraps_the_content_at_the_content_token + options = build_options( + html: "
Hi
", + text: "Hi", + layouts: [{html: "Hi
Hi
", + layouts: [{html: "Hi