diff --git a/Gemfile.lock b/Gemfile.lock index 2c82dd0..81b2490 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,7 +10,10 @@ GEM mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) + metaclass (0.0.1) mime-types (1.23) + mocha (0.14.0) + metaclass (~> 0.0.1) polyglot (0.3.3) rack (1.5.2) rack-test (0.6.2) @@ -28,6 +31,7 @@ PLATFORMS DEPENDENCIES mail (~> 2.2) mail_view! + mocha rack-test (~> 0.6) rake tmail (~> 1.2) diff --git a/README.md b/README.md index 379c2a2..137c733 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ And run `bundle install`. Usage ----- -Since most emails do something interesting with database data, you'll need to write some scenarios to load messages with fake data. Its similar to writing mailer unit tests but you see a visual representation of the output instead. +Since most emails do something interesting with database data, you'll need to write some scenarios to load messages with fake data. It's similar to writing mailer unit tests but you see a visual representation of the output instead. ```ruby # app/mailers/mail_preview.rb or lib/mail_preview.rb @@ -49,6 +49,8 @@ Since most emails do something interesting with database data, you'll need to wr Methods must return a [Mail][1] or [TMail][2] object. Using ActionMailer, call `Notifier.create_action_name(args)` to return a compatible TMail object. Now on ActionMailer 3.x, `Notifier.action_name(args)` will return a Mail object. +To also mail an actual email, just add "?email=your.email@address.com" to the URL query string. For example, if "http://.../invitation" is a MailPreview path, then "http://.../invitation?email=julia@email.com" will display the MailPreview AND send an actual email to julia@email.com. (Unless overridden, the email's from and to addresses will be the specified address.) + Routing ------- diff --git a/lib/mail_view.rb b/lib/mail_view.rb index b9e77bf..3ca8974 100644 --- a/lib/mail_view.rb +++ b/lib/mail_view.rb @@ -39,6 +39,14 @@ def call(env) if actions.include?(name) && !missing_format mail = build_mail(name) + email_addr = get_email_address(request.params["email"]) + if email_addr + sendable = mail.dup + sendable[:to] = email_addr + sendable[:from] ||= email_addr + sendable.deliver + end + # Requested a specific bare MIME part. Render it verbatim. if part_type = request.params['part'] if part = find_part(mail, part_type) @@ -126,4 +134,12 @@ def find_part(mail, matching_content_type) mail end end + + def get_email_address(params_email) + email_regex.match(params_email) ? params_email : nil + end + + def email_regex + /.+@.+\..+/ + end end diff --git a/mail_view.gemspec b/mail_view.gemspec index 5645a28..9741a2d 100644 --- a/mail_view.gemspec +++ b/mail_view.gemspec @@ -12,6 +12,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'mail', '~> 2.2' s.add_development_dependency 'tmail', '~> 1.2' s.add_development_dependency 'rake' + s.add_development_dependency 'mocha' s.files = %w(init.rb) + Dir['lib/**/*'] end diff --git a/test/test_mail_view.rb b/test/test_mail_view.rb index 33c2b54..a2053d9 100644 --- a/test/test_mail_view.rb +++ b/test/test_mail_view.rb @@ -1,6 +1,7 @@ require 'test/unit' require 'rack/test' +require 'mocha/setup' require 'mail_view' require 'mail' require 'tmail' @@ -197,8 +198,7 @@ def test_message_header_uses_full_display_names assert_match 'Another Peek ', unescaped_body end - def test_html_message - get '/html_message' + def html_message_asserts assert last_response.ok? assert_match iframe_src_match('text/html'), last_response.body assert_no_match %r(View as), last_response.body @@ -208,8 +208,21 @@ def test_html_message assert_equal '

Hello

', last_response.body end - def test_nested_multipart_message - get '/nested_multipart_message' + def test_html_message + Net::SMTP.expects(:new).never + get '/html_message' + html_message_asserts + end + + def test_html_message_with_email_addr + mock_smtp = mock() + Net::SMTP.expects(:new).returns(mock_smtp) + mock_smtp.expects(:start) + get '/html_message?email=barack@whitehouse.gov' + html_message_asserts + end + + def nested_multipart_message_asserts assert last_response.ok? assert_match iframe_src_match('text/html'), last_response.body assert_match %r(View as), last_response.body @@ -219,8 +232,21 @@ def test_nested_multipart_message assert_equal '

Hello

', last_response.body end - def test_multipart_alternative - get '/multipart_alternative' + def test_nested_multipart_message + Net::SMTP.expects(:new).never + get '/nested_multipart_message' + nested_multipart_message_asserts + end + + def test_nested_multipart_message_with_email_addr + mock_smtp = mock() + Net::SMTP.expects(:new).returns(mock_smtp) + mock_smtp.expects(:start) + get '/nested_multipart_message?email=abe.lincoln@whitehouse.gov' + nested_multipart_message_asserts + end + + def multipart_alternative_asserts assert last_response.ok? assert_match iframe_src_match('text/html'), last_response.body assert_match 'View as', last_response.body @@ -230,8 +256,21 @@ def test_multipart_alternative assert_equal '

This is HTML

', last_response.body end - def test_multipart_alternative_as_html - get '/multipart_alternative.html' + def test_multipart_alternative + Net::SMTP.expects(:new).never + get '/multipart_alternative' + multipart_alternative_asserts + end + + def test_multipart_alternative_with_email_addr + mock_smtp = mock() + Net::SMTP.expects(:new).returns(mock_smtp) + mock_smtp.expects(:start) + get '/multipart_alternative?email=g.washington@presidentshouse.gov' + multipart_alternative_asserts + end + + def multipart_alternative_as_html_asserts assert last_response.ok? assert_match iframe_src_match('text/html'), last_response.body assert_match 'View as', last_response.body @@ -241,8 +280,21 @@ def test_multipart_alternative_as_html assert_equal '

This is HTML

', last_response.body end - def test_multipart_alternative_as_text - get '/multipart_alternative.txt' + def test_multipart_alternative_as_html + Net::SMTP.expects(:new).never + get '/multipart_alternative.html' + multipart_alternative_as_html_asserts + end + + def test_multipart_alternative_as_html_with_email_addr + mock_smtp = mock() + Net::SMTP.expects(:new).returns(mock_smtp) + mock_smtp.expects(:start) + get '/multipart_alternative.html?email=jfk@whitehouse.gov' + multipart_alternative_as_html_asserts + end + + def multipart_alternative_as_text_asserts assert last_response.ok? assert_match iframe_src_match('text/plain'), last_response.body assert_match 'View as', last_response.body @@ -252,6 +304,20 @@ def test_multipart_alternative_as_text assert_equal 'This is plain text', last_response.body end + def test_multipart_alternative_as_text + Net::SMTP.expects(:new).never + get '/multipart_alternative.txt' + multipart_alternative_as_text_asserts + end + + def test_multipart_alternative_as_text_with_email_addr + mock_smtp = mock() + Net::SMTP.expects(:new).returns(mock_smtp) + mock_smtp.expects(:start) + get '/multipart_alternative.txt?email=fdr@whitehouse.gov' + multipart_alternative_as_text_asserts + end + def test_multipart_alternative_text_as_default get '/multipart_alternative_text_default' assert last_response.ok?