Mercurial > hg > soundsoftware-site
diff test/unit/mail_handler_test.rb @ 1337:077b8890835a cannam
Merge from live branch
author | Chris Cannam |
---|---|
date | Thu, 20 Jun 2013 13:14:02 +0100 |
parents | 433d4f72a19b |
children | 622f24f53b42 261b3d9a4903 |
line wrap: on
line diff
--- a/test/unit/mail_handler_test.rb Fri Jun 14 11:30:07 2013 +0100 +++ b/test/unit/mail_handler_test.rb Thu Jun 20 13:14:02 2013 +0100 @@ -1,7 +1,7 @@ # encoding: utf-8 # # Redmine - project management software -# Copyright (C) 2006-2011 Jean-Philippe Lang +# Copyright (C) 2006-2012 Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -20,25 +20,13 @@ require File.expand_path('../../test_helper', __FILE__) class MailHandlerTest < ActiveSupport::TestCase - fixtures :users, :projects, - :enabled_modules, - :roles, - :members, - :member_roles, - :users, - :issues, - :issue_statuses, - :workflows, - :trackers, - :projects_trackers, - :versions, - :enumerations, - :issue_categories, - :custom_fields, - :custom_fields_trackers, - :custom_fields_projects, - :boards, - :messages + fixtures :users, :projects, :enabled_modules, :roles, + :members, :member_roles, :users, + :issues, :issue_statuses, + :workflows, :trackers, :projects_trackers, + :versions, :enumerations, :issue_categories, + :custom_fields, :custom_fields_trackers, :custom_fields_projects, + :boards, :messages FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' @@ -47,6 +35,10 @@ Setting.notified_events = Redmine::Notifiable.all.collect(&:name) end + def teardown + Setting.clear_cache + end + def test_add_issue ActionMailer::Base.deliveries.clear # This email contains: 'Project: onlinestore' @@ -79,7 +71,10 @@ def test_add_issue_with_default_tracker # This email contains: 'Project: onlinestore' - issue = submit_email('ticket_on_given_project.eml', :issue => {:tracker => 'Support request'}) + issue = submit_email( + 'ticket_on_given_project.eml', + :issue => {:tracker => 'Support request'} + ) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload @@ -97,7 +92,10 @@ end def test_add_issue_with_attributes_override - issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority') + issue = submit_email( + 'ticket_with_attributes.eml', + :allow_override => 'tracker,category,priority' + ) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload @@ -123,7 +121,11 @@ end def test_add_issue_with_partial_attributes_override - issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker']) + issue = submit_email( + 'ticket_with_attributes.eml', + :issue => {:priority => 'High'}, + :allow_override => ['tracker'] + ) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload @@ -137,7 +139,10 @@ end def test_add_issue_with_spaces_between_attribute_and_separator - issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority') + issue = submit_email( + 'ticket_with_spaces_between_attribute_and_separator.eml', + :allow_override => 'tracker,category,priority' + ) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload @@ -172,10 +177,33 @@ assert !issue.new_record? issue.reload assert_equal 'New ticket with custom field values', issue.subject - assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value + assert_equal 'PostgreSQL', issue.custom_field_value(1) + assert_equal 'Value for a custom field', issue.custom_field_value(2) assert !issue.description.match(/^searchable field:/i) end + def test_add_issue_with_version_custom_fields + field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3]) + + issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'ecookbook'}) do |email| + email << "Affected version: 1.0\n" + end + assert issue.is_a?(Issue) + assert !issue.new_record? + issue.reload + assert_equal '2', issue.custom_field_value(field) + end + + def test_add_issue_should_match_assignee_on_display_name + user = User.generate!(:firstname => 'Foo Bar', :lastname => 'Foo Baz') + User.add_to_project(user, Project.find(2)) + issue = submit_email('ticket_on_given_project.eml') do |email| + email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar Foo baz') + end + assert issue.is_a?(Issue) + assert_equal user, issue.assigned_to + end + def test_add_issue_with_cc issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) assert issue.is_a?(Issue) @@ -187,14 +215,22 @@ def test_add_issue_by_unknown_user assert_no_difference 'User.count' do - assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}) + assert_equal false, + submit_email( + 'ticket_by_unknown_user.eml', + :issue => {:project => 'ecookbook'} + ) end end def test_add_issue_by_anonymous_user Role.anonymous.add_permission!(:add_issues) assert_no_difference 'User.count' do - issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept') + issue = submit_email( + 'ticket_by_unknown_user.eml', + :issue => {:project => 'ecookbook'}, + :unknown_user => 'accept' + ) assert issue.is_a?(Issue) assert issue.author.anonymous? end @@ -203,7 +239,11 @@ def test_add_issue_by_anonymous_user_with_no_from_address Role.anonymous.add_permission!(:add_issues) assert_no_difference 'User.count' do - issue = submit_email('ticket_by_empty_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept') + issue = submit_email( + 'ticket_by_empty_user.eml', + :issue => {:project => 'ecookbook'}, + :unknown_user => 'accept' + ) assert issue.is_a?(Issue) assert issue.author.anonymous? end @@ -213,7 +253,12 @@ Role.anonymous.add_permission!(:add_issues) assert_no_difference 'User.count' do assert_no_difference 'Issue.count' do - assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :unknown_user => 'accept') + assert_equal false, + submit_email( + 'ticket_by_unknown_user.eml', + :issue => {:project => 'onlinestore'}, + :unknown_user => 'accept' + ) end end end @@ -221,7 +266,12 @@ def test_add_issue_by_anonymous_user_on_private_project_without_permission_check assert_no_difference 'User.count' do assert_difference 'Issue.count' do - issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :no_permission_check => '1', :unknown_user => 'accept') + issue = submit_email( + 'ticket_by_unknown_user.eml', + :issue => {:project => 'onlinestore'}, + :no_permission_check => '1', + :unknown_user => 'accept' + ) assert issue.is_a?(Issue) assert issue.author.anonymous? assert !issue.project.is_public? @@ -233,7 +283,11 @@ def test_add_issue_by_created_user Setting.default_language = 'en' assert_difference 'User.count' do - issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create') + issue = submit_email( + 'ticket_by_unknown_user.eml', + :issue => {:project => 'ecookbook'}, + :unknown_user => 'create' + ) assert issue.is_a?(Issue) assert issue.author.active? assert_equal 'john.doe@somenet.foo', issue.author.mail @@ -244,8 +298,8 @@ email = ActionMailer::Base.deliveries.first assert_not_nil email assert email.subject.include?('account activation') - login = email.body.match(/\* Login: (.*)$/)[1] - password = email.body.match(/\* Password: (.*)$/)[1] + login = mail_body(email).match(/\* Login: (.*)$/)[1].strip + password = mail_body(email).match(/\* Password: (.*)$/)[1].strip assert_equal issue.author, User.try_to_login(login, password) end end @@ -256,7 +310,10 @@ end def test_add_issue_with_invalid_attributes - issue = submit_email('ticket_with_invalid_attributes.eml', :allow_override => 'tracker,category,priority') + issue = submit_email( + 'ticket_with_invalid_attributes.eml', + :allow_override => 'tracker,category,priority' + ) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload @@ -270,7 +327,10 @@ def test_add_issue_with_localized_attributes User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr' - issue = submit_email('ticket_with_localized_attributes.eml', :allow_override => 'tracker,category,priority') + issue = submit_email( + 'ticket_with_localized_attributes.eml', + :allow_override => 'tracker,category,priority' + ) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload @@ -284,27 +344,186 @@ end def test_add_issue_with_japanese_keywords - tracker = Tracker.create!(:name => '開発') + ja_dev = "\xe9\x96\x8b\xe7\x99\xba" + ja_dev.force_encoding('UTF-8') if ja_dev.respond_to?(:force_encoding) + tracker = Tracker.create!(:name => ja_dev) Project.find(1).trackers << tracker - issue = submit_email('japanese_keywords_iso_2022_jp.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'tracker') + issue = submit_email( + 'japanese_keywords_iso_2022_jp.eml', + :issue => {:project => 'ecookbook'}, + :allow_override => 'tracker' + ) assert_kind_of Issue, issue assert_equal tracker, issue.tracker end def test_add_issue_from_apple_mail - issue = submit_email('apple_mail_with_attachment.eml', :issue => {:project => 'ecookbook'}) + issue = submit_email( + 'apple_mail_with_attachment.eml', + :issue => {:project => 'ecookbook'} + ) assert_kind_of Issue, issue assert_equal 1, issue.attachments.size attachment = issue.attachments.first assert_equal 'paella.jpg', attachment.filename assert_equal 10790, attachment.filesize + assert File.exist?(attachment.diskfile) + assert_equal 10790, File.size(attachment.diskfile) + assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest + end + + def test_thunderbird_with_attachment_ja + issue = submit_email( + 'thunderbird_with_attachment_ja.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + assert_equal 1, issue.attachments.size + ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt" + ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + attachment = issue.attachments.first + assert_equal ja, attachment.filename + assert_equal 5, attachment.filesize + assert File.exist?(attachment.diskfile) + assert_equal 5, File.size(attachment.diskfile) + assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest + end + + def test_gmail_with_attachment_ja + issue = submit_email( + 'gmail_with_attachment_ja.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + assert_equal 1, issue.attachments.size + ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt" + ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + attachment = issue.attachments.first + assert_equal ja, attachment.filename + assert_equal 5, attachment.filesize + assert File.exist?(attachment.diskfile) + assert_equal 5, File.size(attachment.diskfile) + assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest + end + + def test_thunderbird_with_attachment_latin1 + issue = submit_email( + 'thunderbird_with_attachment_iso-8859-1.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + assert_equal 1, issue.attachments.size + u = "" + u.force_encoding('UTF-8') if u.respond_to?(:force_encoding) + u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc" + u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding) + 11.times { u << u1 } + attachment = issue.attachments.first + assert_equal "#{u}.png", attachment.filename + assert_equal 130, attachment.filesize + assert File.exist?(attachment.diskfile) + assert_equal 130, File.size(attachment.diskfile) + assert_equal '4d80e667ac37dddfe05502530f152abb', attachment.digest + end + + def test_gmail_with_attachment_latin1 + issue = submit_email( + 'gmail_with_attachment_iso-8859-1.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + assert_equal 1, issue.attachments.size + u = "" + u.force_encoding('UTF-8') if u.respond_to?(:force_encoding) + u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc" + u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding) + 11.times { u << u1 } + attachment = issue.attachments.first + assert_equal "#{u}.txt", attachment.filename + assert_equal 5, attachment.filesize + assert File.exist?(attachment.diskfile) + assert_equal 5, File.size(attachment.diskfile) + assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest + end + + def test_add_issue_with_iso_8859_1_subject + issue = submit_email( + 'subject_as_iso-8859-1.eml', + :issue => {:project => 'ecookbook'} + ) + str = "Testmail from Webmail: \xc3\xa4 \xc3\xb6 \xc3\xbc..." + str.force_encoding('UTF-8') if str.respond_to?(:force_encoding) + assert_kind_of Issue, issue + assert_equal str, issue.subject + end + + def test_add_issue_with_japanese_subject + issue = submit_email( + 'subject_japanese_1.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" + ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + assert_equal ja, issue.subject + end + + def test_add_issue_with_no_subject_header + issue = submit_email( + 'no_subject_header.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + assert_equal '(no subject)', issue.subject + end + + def test_add_issue_with_mixed_japanese_subject + issue = submit_email( + 'subject_japanese_2.eml', + :issue => {:project => 'ecookbook'} + ) + assert_kind_of Issue, issue + ja = "Re: \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" + ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) + assert_equal ja, issue.subject + end + + def test_should_ignore_emails_from_locked_users + User.find(2).lock! + + MailHandler.any_instance.expects(:dispatch).never + assert_no_difference 'Issue.count' do + assert_equal false, submit_email('ticket_on_given_project.eml') + end end def test_should_ignore_emails_from_emission_address Role.anonymous.add_permission!(:add_issues) assert_no_difference 'User.count' do - assert_equal false, submit_email('ticket_from_emission_address.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create') + assert_equal false, + submit_email( + 'ticket_from_emission_address.eml', + :issue => {:project => 'ecookbook'}, + :unknown_user => 'create' + ) + end + end + + def test_should_ignore_auto_replied_emails + MailHandler.any_instance.expects(:dispatch).never + [ + "X-Auto-Response-Suppress: OOF", + "Auto-Submitted: auto-replied", + "Auto-Submitted: Auto-Replied", + "Auto-Submitted: auto-generated" + ].each do |header| + raw = IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml')) + raw = header + "\n" + raw + + assert_no_difference 'Issue.count' do + assert_equal false, MailHandler.receive(raw), "email with #{header} header was not ignored" + end end end @@ -323,6 +542,7 @@ assert_equal User.find_by_login('jsmith'), journal.user assert_equal Issue.find(2), journal.journalized assert_match /This is reply/, journal.notes + assert_equal false, journal.private_notes assert_equal 'Feature request', journal.issue.tracker.name end @@ -374,13 +594,30 @@ end def test_update_issue_should_not_set_defaults - journal = submit_email('ticket_reply.eml', :issue => {:tracker => 'Support request', :priority => 'High'}) + journal = submit_email( + 'ticket_reply.eml', + :issue => {:tracker => 'Support request', :priority => 'High'} + ) assert journal.is_a?(Journal) assert_match /This is reply/, journal.notes assert_equal 'Feature request', journal.issue.tracker.name assert_equal 'Normal', journal.issue.priority.name end + def test_replying_to_a_private_note_should_add_reply_as_private + private_journal = Journal.create!(:notes => 'Private notes', :journalized => Issue.find(1), :private_notes => true, :user_id => 2) + + assert_difference 'Journal.count' do + journal = submit_email('ticket_reply.eml') do |email| + email.sub! %r{^In-Reply-To:.*$}, "In-Reply-To: <redmine.journal-#{private_journal.id}.20060719210421@osiris>" + end + + assert_kind_of Journal, journal + assert_match /This is reply/, journal.notes + assert_equal true, journal.private_notes + end + end + def test_reply_to_a_message m = submit_email('message_reply.eml') assert m.is_a?(Message) @@ -493,14 +730,13 @@ ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'], ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'], ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'], - ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh'], - ['alongemailaddressthatexceedsloginlength@example.net', 'John Smith'] => ['alongemailaddressthatexceedslo', 'John', 'Smith'] + ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh'] } to_test.each do |attrs, expected| user = MailHandler.new_user_from_attributes(attrs.first, attrs.last) - assert user.valid? + assert user.valid?, user.errors.full_messages.to_s assert_equal attrs.first, user.mail assert_equal expected[0], user.login assert_equal expected[1], user.firstname @@ -515,14 +751,31 @@ assert user.password.length >= 15 end end - + def test_new_user_from_attributes_should_use_default_login_if_invalid - MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-1@example.net').save! - - # another long address that would result in duplicate login - user = MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-2@example.net') + user = MailHandler.new_user_from_attributes('foo+bar@example.net') assert user.valid? assert user.login =~ /^user[a-f0-9]+$/ + assert_equal 'foo+bar@example.net', user.mail + end + + def test_new_user_with_utf8_encoded_fullname_should_be_decoded + assert_difference 'User.count' do + issue = submit_email( + 'fullname_of_sender_as_utf8_encoded.eml', + :issue => {:project => 'ecookbook'}, + :unknown_user => 'create' + ) + end + + user = User.first(:order => 'id DESC') + assert_equal "foo@example.org", user.mail + str1 = "\xc3\x84\xc3\xa4" + str2 = "\xc3\x96\xc3\xb6" + str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding) + str2.force_encoding('UTF-8') if str2.respond_to?(:force_encoding) + assert_equal str1, user.firstname + assert_equal str2, user.lastname end private