diff options
Diffstat (limited to 'spec/lib')
-rw-r--r-- | spec/lib/i18n_interpolation.rb | 41 | ||||
-rw-r--r-- | spec/lib/mail_handler/mail_handler_spec.rb | 387 | ||||
-rw-r--r-- | spec/lib/sendmail_return_path_spec.rb | 4 | ||||
-rw-r--r-- | spec/lib/timezone_fixes_spec.rb | 37 | ||||
-rw-r--r-- | spec/lib/tmail_extensions_spec.rb | 45 |
5 files changed, 435 insertions, 79 deletions
diff --git a/spec/lib/i18n_interpolation.rb b/spec/lib/i18n_interpolation.rb index 8c86413ad..e8d046757 100644 --- a/spec/lib/i18n_interpolation.rb +++ b/spec/lib/i18n_interpolation.rb @@ -1,6 +1,3 @@ -# This is a test of the set_content_type monkey patch in -# lib/tmail_extensions.rb - require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "when using i18n" do @@ -11,5 +8,43 @@ describe "when using i18n" do result = _('Hello {{dip}}', :dip => 'hummus') result.should == 'Hello hummus' end + + it "should assume that simple translations are always html safe" do + _("Hello").should be_html_safe + end + end +describe "gettext_interpolate" do + context "html unsafe string" do + let(:string) { "Hello {{a}}" } + + it "should give an unsafe result" do + result = gettext_interpolate(string, :a => "foo") + result.should == "Hello foo" + result.should_not be_html_safe + end + + it "should give an unsafe result" do + result = gettext_interpolate(string, :a => "foo".html_safe) + result.should == "Hello foo" + result.should_not be_html_safe + end + end + + context "html safe string" do + let(:string) { "Hello {{a}}".html_safe } + + it "should quote the input if it's unsafe" do + result = gettext_interpolate(string, :a => "foo&") + result.should == "Hello foo&" + result.should be_html_safe + end + + it "should not quote the input if it's safe" do + result = gettext_interpolate(string, :a => "foo&".html_safe) + result.should == "Hello foo&" + result.should be_html_safe + end + end +end diff --git a/spec/lib/mail_handler/mail_handler_spec.rb b/spec/lib/mail_handler/mail_handler_spec.rb new file mode 100644 index 000000000..48c32e2bc --- /dev/null +++ b/spec/lib/mail_handler/mail_handler_spec.rb @@ -0,0 +1,387 @@ +# coding: utf-8 +require File.expand_path(File.dirname(__FILE__) + '../../../spec_helper') + +def create_message_from(from_field) + mail_data = load_file_fixture('incoming-request-plain.email') + mail_data.gsub!('EMAIL_FROM', from_field) + mail = MailHandler.mail_from_raw_email(mail_data) +end + +describe 'when creating a mail object from raw data' do + + it 'should correctly parse a multipart email with a linebreak in the boundary' do + mail = get_fixture_mail('space-boundary.email') + mail.parts.size.should == 2 + mail.multipart?.should == true + end + + it 'should parse multiple to addresses with unqoted display names' do + mail = get_fixture_mail('multiple-unquoted-display-names.email') + mail.to.should == ["request-66666-caa77777@whatdotheyknow.com", "foi@example.com"] + end + + it 'should convert an iso8859 email to utf8' do + mail = get_fixture_mail('iso8859_2_raw_email.email') + mail.subject.should have_text(/gjatë/u) + MailHandler.get_part_body(mail).is_utf8?.should == true + end + +end + +describe 'when asked for the from name' do + + it 'should return nil if there is a blank "From" field' do + mail = create_message_from('') + MailHandler.get_from_name(mail).should == nil + end + + it 'should correctly return an encoded name from the from field' do + mail = get_fixture_mail('quoted-subject-iso8859-1.email') + MailHandler.get_from_name(mail).should == 'Coordenação de Relacionamento, Pesquisa e Informação/CEDI' + end + + it 'should get a name from a "From" field with a name and address' do + mail = get_fixture_mail('incoming-request-oft-attachments.email') + MailHandler.get_from_name(mail).should == 'Public Authority' + end + + it 'should return nil from a "From" field that is just a name'do + mail = get_fixture_mail('track-response-webshield-bounce.email') + MailHandler.get_from_name(mail).should == nil + end + +end + +describe 'when asked for the from address' do + + it 'should return nil if there is a blank "From" field' do + mail = create_message_from('') + MailHandler.get_from_address(mail).should == nil + end + + it 'should correctly return an address from a mail that has an encoded name in the from field' do + mail = get_fixture_mail('quoted-subject-iso8859-1.email') + MailHandler.get_from_address(mail).should == 'geraldinequango@localhost' + end + + it 'should return nil if there is no address in the "From" field' do + mail = get_fixture_mail('track-response-webshield-bounce.email') + MailHandler.get_from_address(mail).should == nil + end + + it 'should return the "From" email address if there is one' do + mail = get_fixture_mail('track-response-abcmail-oof.email') + MailHandler.get_from_address(mail).should == 'Name.Removed@example.gov.uk' + end + + it 'should get an address from a "From" field with a name and address' do + mail = get_fixture_mail('incoming-request-oft-attachments.email') + MailHandler.get_from_address(mail).should == 'public@authority.gov.uk' + end +end + +describe 'when asked for all the addresses a mail has been sent to' do + + it 'should return an array containing the envelope-to address and the to address, and the cc address if there is one' do + mail_data = load_file_fixture('humberside-police-odd-mime-type.email') + mail_data.gsub!('Envelope-to: request-5335-xxxxxxxx@whatdotheyknow.com', + 'Envelope-to: request-5555-xxxxxxxx@whatdotheyknow.com') + mail_data.gsub!('Cc: request-5335-xxxxxxxx@whatdotheyknow.com', + 'Cc: request-3333-xxxxxxxx@whatdotheyknow.com') + mail = MailHandler.mail_from_raw_email(mail_data) + MailHandler.get_all_addresses(mail).should == ['request-5335-xxxxxxxx@whatdotheyknow.com', + 'request-3333-xxxxxxxx@whatdotheyknow.com', + 'request-5555-xxxxxxxx@whatdotheyknow.com'] + end + + it 'should only return unique values' do + # envelope-to and to fields are the same + mail = get_fixture_mail('humberside-police-odd-mime-type.email') + MailHandler.get_all_addresses(mail).should == ['request-5335-xxxxxxxx@whatdotheyknow.com'] + end + + it 'should handle the absence of an envelope-to or cc field' do + mail_data = load_file_fixture('autoresponse-header.email') + mail_data.gsub!('To: FOI Person <EMAIL_TO>', + 'To: FOI Person <request-5555-xxxxxxxx@whatdotheyknow.com>') + mail = MailHandler.mail_from_raw_email(mail_data) + MailHandler.get_all_addresses(mail).should == ["request-5555-xxxxxxxx@whatdotheyknow.com"] + end +end + +describe 'when asked for auto_submitted' do + + it 'should return a string value for an email with an auto-submitted header' do + mail = get_fixture_mail('autoresponse-header.email') + MailHandler.get_auto_submitted(mail).should == 'auto-replied' + end + + it 'should return a nil value for an email with no auto-submitted header' do + mail = get_fixture_mail('incoming-request-plain.email') + MailHandler.get_auto_submitted(mail).should == nil + end + +end + +describe 'when asked if there is an empty return path' do + + it 'should return true if there is an empty return-path specified' do + mail = get_fixture_mail('empty-return-path.email') + MailHandler.empty_return_path?(mail).should == true + end + + it 'should return false if there is no return-path header' do + mail = get_fixture_mail('incoming-request-attach-attachments.email') + MailHandler.empty_return_path?(mail).should == false + end + + it 'should return false if there is a return path address' do + mail = get_fixture_mail('autoresponse-header.email') + MailHandler.empty_return_path?(mail).should == false + end +end + +describe 'when deriving a name, email and formatted address from a message from a line' do + + def should_render_from_address(from_line, expected_result) + mail = create_message_from(from_line) + name = MailHandler.get_from_name(mail) + email = MailHandler.get_from_address(mail) + address = MailHandler.address_from_name_and_email(name, email).to_s + [name, email, address].should == expected_result + end + + it 'should correctly render a name with quoted commas' do + should_render_from_address('"Clare College, Cambridge" <test@test.test>', + ['Clare College, Cambridge', + 'test@test.test', + '"Clare College, Cambridge" <test@test.test>']) + end + + it 'should correctly reproduce a simple name and email that does not need quotes' do + should_render_from_address('"FOI Person" <foiperson@localhost>', + ['FOI Person', + 'foiperson@localhost', + 'FOI Person <foiperson@localhost>']) + end + + it 'should render an address with no name' do + should_render_from_address("foiperson@localhost", + [nil, + "foiperson@localhost", + "foiperson@localhost"]) + end + + it 'should quote a name with a square bracked in it' do + should_render_from_address('"FOI [ Person" <foiperson@localhost>', + ['FOI [ Person', + 'foiperson@localhost', + '"FOI [ Person" <foiperson@localhost>']) + end + + it 'should quote a name with an @ in it' do + should_render_from_address('"FOI @ Person" <foiperson@localhost>', + ['FOI @ Person', + 'foiperson@localhost', + '"FOI @ Person" <foiperson@localhost>']) + end + + + it 'should quote a name with quotes in it' do + should_render_from_address('"FOI \" Person" <foiperson@localhost>', + ['FOI " Person', + 'foiperson@localhost', + '"FOI \" Person" <foiperson@localhost>']) + end + +end + +describe 'when getting the content type of a mail part' do + + def expect_content_type(fixture_file, content_type) + mail = get_fixture_mail(fixture_file) + MailHandler.get_content_type(mail).should == content_type + end + + it 'should correctly return a type of "multipart/report"' do + expect_content_type('track-response-multipart-report.email', 'multipart/report') + end + + it 'should correctly return a type of "text/plain"' do + expect_content_type('track-response-abcmail-oof.email', 'text/plain') + end + + it 'should correctly return a type of "multipart/mixed"' do + expect_content_type('track-response-messageclass-oof.email', 'multipart/mixed') + end + + it 'should correctly return the types in an example bounce report' do + mail = get_fixture_mail('track-response-ms-bounce.email') + report = mail.parts.detect{ |part| MailHandler.get_content_type(part) == 'multipart/report'} + MailHandler.get_content_type(report.parts[0]).should == 'text/plain' + MailHandler.get_content_type(report.parts[1]).should == 'message/delivery-status' + MailHandler.get_content_type(report.parts[2]).should == 'message/rfc822' + end + +end + +describe 'when getting header strings' do + + def expect_header_string(fixture_file, header, header_string) + mail = get_fixture_mail(fixture_file) + MailHandler.get_header_string(header, mail).should == header_string + end + + it 'should return the contents of a "Subject" header' do + expect_header_string('track-response-ms-bounce.email', + 'Subject', + 'Delivery Status Notification (Delay)') + end + + it 'should return the contents of an "X-Failed-Recipients" header' do + expect_header_string('autoresponse-header.email', + 'X-Failed-Recipients', + 'enquiries@cheese.com') + end + + it 'should return the contents of an example "" header' do + expect_header_string('track-response-messageclass-oof.email', + 'X-POST-MessageClass', + '9; Autoresponder') + end + +end + +describe "when parsing HTML mail" do + it "should display UTF-8 characters in the plain text version correctly" do + html = "<html><b>foo</b> është" + plain_text = MailHandler.get_attachment_text_one_file('text/html', html) + plain_text.should match(/është/) + end + +end + +describe "when getting the attachment text" do + it "should not raise an error if the expansion of a zip file raises an error" do + mock_entry = mock('ZipFile entry', :file? => true) + mock_entries = [mock_entry] + mock_entries.stub!(:close) + mock_entry.stub!(:get_input_stream).and_raise("invalid distance too far back") + Zip::ZipFile.stub!(:open).and_return(mock_entries) + MailHandler.get_attachment_text_one_file('application/zip', "some string") + end + +end + +describe 'when getting attachment attributes' do + + it 'should get two attachment parts from a multipart mail with text and html alternatives + and an image' do + mail = get_fixture_mail('quoted-subject-iso8859-1.email') + attributes = MailHandler.get_attachment_attributes(mail) + attributes.size.should == 2 + end + + it 'should expand a mail attached as text' do + # Note that this spec will only pass using Tmail in the timezone set as datetime headers + # are rendered out in the local time - using the Mail gem this is not necessary + with_env_tz('London') do + mail = get_fixture_mail('rfc822-attachment.email') + attributes = MailHandler.get_attachment_attributes(mail) + attributes.size.should == 2 + rfc_attachment = attributes[1] + rfc_attachment[:within_rfc822_subject].should == 'Freedom of Information request' + headers = ['Date: Thu, 13 Mar 2008 16:57:33 +0000', + 'Subject: Freedom of Information request', + 'From: An FOI Officer <foi.officer@example.com>', + 'To: request-bounce-xx-xxxxx@whatdotheyno.com'] + rfc_attachment[:body].should == "#{headers.join("\n")}\n\nsome example text" + end + end + + it 'should handle a mail which causes Tmail to generate a blank header value' do + mail = get_fixture_mail('many-attachments-date-header.email') + attributes = MailHandler.get_attachment_attributes(mail) + end + + it 'should produce a consistent set of url_part_numbers, content_types, within_rfc822_subjects + and filenames from an example mail with lots of attachments' do + mail = get_fixture_mail('many-attachments-date-header.email') + attributes = MailHandler.get_attachment_attributes(mail) + + expected_attributes = [ { :content_type=>"text/plain", + :url_part_number=>1, + :within_rfc822_subject=>nil, + :filename=>nil}, + { :content_type=>"text/plain", + :url_part_number=>2, + :within_rfc822_subject=>"Re: xxx", + :filename=>nil}, + { :content_type=>"text/html", + :url_part_number=>4, + :within_rfc822_subject=>"example", + :filename=>nil}, + { :content_type=>"image/gif", :url_part_number=>5, + :within_rfc822_subject=>"example", + :filename=>"image001.gif"}, + { :content_type=>"application/vnd.ms-excel", + :url_part_number=>6, + :within_rfc822_subject=>"example", + :filename=>"particpant list.xls"}, + { :content_type=>"text/plain", + :url_part_number=>7, + :within_rfc822_subject=>"RE: example", + :filename=>nil}, + { :content_type=>"text/html", + :url_part_number=>9, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>nil}, + { :content_type=>"image/gif", + :url_part_number=>10, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>"image001.gif"}, + { :content_type=>"application/vnd.ms-word", + :url_part_number=>11, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>"Participant List.doc"}, + { :content_type=>"application/vnd.ms-word", + :url_part_number=>12, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>"Information & Booking Form.doc"}, + { :content_type=>"text/plain", + :url_part_number=>13, + :within_rfc822_subject=>"Re: As promised - info (example)", + :filename=>nil}, + { :content_type=>"text/html", + :url_part_number=>15, + :within_rfc822_subject=>"Thank you from example", + :filename=>nil}, + { :content_type=>"image/gif", + :url_part_number=>16, + :within_rfc822_subject=>"Thank you from example", + :filename=>"image001.gif"}, + { :content_type=>"text/plain", + :url_part_number=>17, + :within_rfc822_subject=>"example - Meeting - Tuesday 2nd March", + :filename=>nil}, + { :content_type=>"text/plain", + :url_part_number=>18, + :within_rfc822_subject=>"example - Help needed", + :filename=>nil}, + { :content_type=>"application/pdf", + :url_part_number=>19, + :within_rfc822_subject=>"example - Help needed", + :filename=>"Information Pack.pdf"}, + { :content_type=>"text/plain", + :url_part_number=>20, + :within_rfc822_subject=>"Re: As promised - info (example)", + :filename=>nil} ] + + attributes.each_with_index do |attr, index| + attr.delete(:charset) + attr.delete(:body) + attr.delete(:hexdigest) + attr.should == expected_attributes[index] + end + end +end diff --git a/spec/lib/sendmail_return_path_spec.rb b/spec/lib/sendmail_return_path_spec.rb index 7708edb35..137869b6e 100644 --- a/spec/lib/sendmail_return_path_spec.rb +++ b/spec/lib/sendmail_return_path_spec.rb @@ -28,7 +28,7 @@ describe "when sending email with an altered return path" do Net::SMTP.stub!(:new).and_return(mock_smtp) with_delivery_method :smtp do - ContactMailer.deliver_message( + ContactMailer.deliver_to_admin_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 ) @@ -42,7 +42,7 @@ describe "when sending email with an altered return path" 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( + ContactMailer.deliver_to_admin_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 ) diff --git a/spec/lib/timezone_fixes_spec.rb b/spec/lib/timezone_fixes_spec.rb index a2bea5f64..9d6ade526 100644 --- a/spec/lib/timezone_fixes_spec.rb +++ b/spec/lib/timezone_fixes_spec.rb @@ -11,14 +11,13 @@ describe "when doing things with timezones" do with_active_record_default_timezone :utc do time = Time.local(2000) mail_server_log_done = MailServerLogDone.create('last_stat' => time, 'filename' => 'dummy') - raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).read_attribute(:last_stat) + raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).attributes_before_type_cast["last_stat"] saved_time = MailServerLogDone.find(mail_server_log_done.id).last_stat assert_equal time, saved_time - assert_equal saved_time, raw_saved_time # Time is created in EST by local method (using ENV['TZ']) assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "EST"], time.to_a # Due to :utc active_record_default_timezone, everything saved as UTC - assert_equal [0, 0, 5, 1, 1, 2000, 6, 1, false, "UTC"], raw_saved_time.to_a + assert_equal "2000-01-01 05:00:00", raw_saved_time # As config.time_zone is UTC (from config default), times returned in UTC assert_equal [0, 0, 5, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a end @@ -33,14 +32,12 @@ describe "when doing things with timezones" do Time.use_zone 'Central Time (US & Canada)' do time = Time.zone.local(2000) mail_server_log_done = MailServerLogDone.create('last_stat' => time, 'filename' => 'dummy') - raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).read_attribute(:last_stat) + raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).attributes_before_type_cast["last_stat"] saved_time = MailServerLogDone.find(mail_server_log_done.id).last_stat - assert_equal time, saved_time - assert_equal saved_time, raw_saved_time # Time is created in CST by Time.local (as Time.zone has been set) assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a # Due to :utc active_record_default_timezone, everything saved as UTC - assert_equal [0, 0, 6, 1, 1, 2000, 6, 1, false, "UTC"], raw_saved_time.to_a + assert_equal "2000-01-01 06:00:00", raw_saved_time # Times returned in CST due to Time.use_zone and ActiveRecord::time_zone_aware_attributes # being true assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], saved_time.to_a @@ -55,14 +52,13 @@ describe "when doing things with timezones" do with_active_record_default_timezone :local do time = Time.utc(2000) mail_server_log_done = MailServerLogDone.create('last_stat' => time, 'filename' => 'dummy') - raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).read_attribute(:last_stat) + raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).attributes_before_type_cast["last_stat"] saved_time = MailServerLogDone.find(mail_server_log_done.id).last_stat assert_equal time, saved_time - assert_equal saved_time, raw_saved_time # Time is created in UTC by Time.utc method assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], time.to_a # Due to :local active_record_default_timezone, saved as EST - assert_equal [0, 0, 19, 31, 12, 1999, 5, 365, false, "EST"], raw_saved_time.to_a + assert_equal "1999-12-31 19:00:00", raw_saved_time # As config.time_zone is UTC (from config default), times returned in UTC assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a end @@ -76,14 +72,13 @@ describe "when doing things with timezones" do Time.use_zone 'Central Time (US & Canada)' do time = Time.zone.local(2000) mail_server_log_done = MailServerLogDone.create('last_stat' => time, 'filename' => 'dummy') - raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).read_attribute(:last_stat) + raw_saved_time = MailServerLogDone.find(mail_server_log_done.id).attributes_before_type_cast["last_stat"] saved_time = MailServerLogDone.find(mail_server_log_done.id).last_stat assert_equal time, saved_time - assert_equal saved_time, raw_saved_time # Time is created in CST by Time.zone.local assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a # Due to :local active_record_default_timezone, saved as EST - assert_equal [0, 0, 1, 1, 1, 2000, 6, 1, false, "EST"], raw_saved_time.to_a + assert_equal "2000-01-01 01:00:00", raw_saved_time # Due to Time.use_zone, and ActiveRecord::time_zone_aware_attributes # being true, time returned in CST assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], saved_time.to_a @@ -92,22 +87,6 @@ describe "when doing things with timezones" do end end - - protected - - def with_env_tz(new_tz = 'US/Eastern') - old_tz, ENV['TZ'] = ENV['TZ'], new_tz - yield - ensure - old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ') - end - - def with_active_record_default_timezone(zone) - old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone - yield - ensure - ActiveRecord::Base.default_timezone = old_zone - end end diff --git a/spec/lib/tmail_extensions_spec.rb b/spec/lib/tmail_extensions_spec.rb deleted file mode 100644 index bd89e6a84..000000000 --- a/spec/lib/tmail_extensions_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# coding: utf-8 -# This is a test of the set_content_type monkey patch in -# lib/tmail_extensions.rb - -require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') - -describe "when using TMail" do - - before(:each) do - ActionMailer::Base.deliveries.clear - end - - it "should load an email with funny MIME settings" do - # just send it to the holding pen - InfoRequest.holding_pen_request.incoming_messages.size.should == 0 - receive_incoming_mail("humberside-police-odd-mime-type.email", 'dummy') - InfoRequest.holding_pen_request.incoming_messages.size.should == 1 - - # clear the notification of new message in holding pen - deliveries = ActionMailer::Base.deliveries - deliveries.size.should == 1 - deliveries.clear - - incoming_message = InfoRequest.holding_pen_request.incoming_messages[0] - - # This will raise an error if the bug in TMail hasn't been fixed - incoming_message.get_body_for_html_display() - end - - it 'should parse multiple to addresses with unqoted display names' do - mail = TMail::Mail.parse(load_file_fixture('multiple-unquoted-display-names.email')) - mail.to.should == ["request-66666-caa77777@whatdotheyknow.com", "foi@example.com"] - end - - it 'should convert to utf8' do - # NB this isn't actually a TMail extension, but is core TMail; - # this was just a convenient place to assert the UTF8 - # conversion is working - mail = TMail::Mail.parse(load_file_fixture('iso8859_2_raw_email.email')) - mail.subject.should have_text(/gjatë/u) - mail.body.is_utf8?.should == true - end - -end - |