diff options
-rw-r--r-- | config/environment.rb | 1 | ||||
-rw-r--r-- | lib/sendmail_return_path.rb | 21 | ||||
-rw-r--r-- | spec/lib/sendmail_return_path_spec.rb | 72 |
3 files changed, 94 insertions, 0 deletions
diff --git a/config/environment.rb b/config/environment.rb index 00508dacc..6d0c2f5c0 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -100,6 +100,7 @@ require 'use_spans_for_errors.rb' require 'make_html_4_compliant.rb' require 'activerecord_errors_extensions.rb' require 'willpaginate_hack.rb' +require 'sendmail_return_path.rb' # XXX temp debug for SQL logging production sites #ActiveRecord::Base.logger = Logger.new(STDOUT) diff --git a/lib/sendmail_return_path.rb b/lib/sendmail_return_path.rb new file mode 100644 index 000000000..f9ddba5b4 --- /dev/null +++ b/lib/sendmail_return_path.rb @@ -0,0 +1,21 @@ +# Monkeypatch! +# Grrr, semantics of smtp and sendmail send should be the same with regard to setting return path + +# See test in spec/lib/sendmail_return_path.rb + +module ActionMailer + class Base + def perform_delivery_sendmail(mail) + sender = (mail['return-path'] && mail['return-path'].spec) || mail.from + + sendmail_args = sendmail_settings[:arguments].dup + sendmail_args += " -f \"#{sender}\"" + + IO.popen("#{sendmail_settings[:location]} #{sendmail_args}","w+") do |sm| + sm.print(mail.encoded.gsub(/\r/, '')) + sm.flush + end + end + end +end + diff --git a/spec/lib/sendmail_return_path_spec.rb b/spec/lib/sendmail_return_path_spec.rb new file mode 100644 index 000000000..d279c5a0b --- /dev/null +++ b/spec/lib/sendmail_return_path_spec.rb @@ -0,0 +1,72 @@ +# This is a test of the monkey patches in sendmail_return_path.rb + +require File.dirname(__FILE__) + '/../spec_helper' + +describe "when sending email with an altered return path" do + + it "should default to delivery method test" do + ActionMailer::Base.delivery_method.should == :test + end + + it "should let the helper change the method" do + with_delivery_method :smtp do + ActionMailer::Base.delivery_method.should == :smtp + end + ActionMailer::Base.delivery_method.should == :test + end + + # Documentation for fancy mock functions: http://rspec.info/documentation/mocks/message_expectations.html + it "should set the return path when sending email using SMTP" do + mock_smtp = mock("smtp") + mock_smtp_session = mock("smtp_session") + + mock_smtp.should_receive(:start).once.and_yield(mock_smtp_session) + # the second parameter to the SMTP session is the sender (return path) + mock_smtp_session.should_receive(:sendmail).once.with(anything(), ["test@localhost"], anything()) + + Net::SMTP.stub!(:new).and_return(mock_smtp) + + with_delivery_method :smtp do + ContactMailer.deliver_message( + "Mr. Test", "test@localhost", "Test script spec/lib/sendmail_return_path_spec.rb", + "This is just a test for a test script", nil, nil, nil + ) + end + end + + it "should set the return path when sending email using sendmail" do + with_stub_popen do + IO.should_receive(:popen).once.with('/usr/sbin/sendmail -i -t -f "test@localhost"', "w+") + with_delivery_method :sendmail do + ContactMailer.deliver_message( + "Mr. Test", "test@localhost", "Test script spec/lib/sendmail_return_path_spec.rb", + "This is just a test for a test script", nil, nil, nil + ) + end + end + end + + + protected + # Change the way Rails delivers memory, just for current scope + def with_delivery_method(new_delivery_method) + old_delivery_method, ActionMailer::Base.delivery_method = ActionMailer::Base.delivery_method, new_delivery_method + yield + ensure + ActionMailer::Base.delivery_method = old_delivery_method + end + + # By default, we can't stub popen, presumably because it is a builtin written in C. + # Replace it entirely with a dummy function that just returns nil, so we can stub it. + def with_stub_popen() + old_popen = IO.method(:popen).unbind + IO.class_eval "def self.popen(a, b); nil; end" + yield + ensure + old_popen.bind(IO) + end + + +end + + |