diff test/unit/mail_handler_test.rb @ 1526:404aa68d4227

Merge from live branch
author Chris Cannam
date Thu, 11 Sep 2014 12:46:20 +0100
parents dffacf8a6908
children
line wrap: on
line diff
--- a/test/unit/mail_handler_test.rb	Mon Mar 17 08:57:04 2014 +0000
+++ b/test/unit/mail_handler_test.rb	Thu Sep 11 12:46:20 2014 +0100
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2014  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
@@ -41,6 +41,7 @@
 
   def test_add_issue
     ActionMailer::Base.deliveries.clear
+    lft1 = new_issue_lft
     # This email contains: 'Project: onlinestore'
     issue = submit_email('ticket_on_given_project.eml')
     assert issue.is_a?(Issue)
@@ -58,7 +59,7 @@
     assert_equal Version.find_by_name('Alpha'), issue.fixed_version
     assert_equal 2.5, issue.estimated_hours
     assert_equal 30, issue.done_ratio
-    assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
+    assert_equal [issue.id, lft1, lft1 + 1], [issue.root_id, issue.lft, issue.rgt]
     # keywords should be removed from the email body
     assert !issue.description.match(/^Project:/i)
     assert !issue.description.match(/^Status:/i)
@@ -204,6 +205,14 @@
     assert_equal user, issue.assigned_to
   end
 
+  def test_add_issue_should_set_default_start_date
+    with_settings :default_issue_start_date_to_creation_date => '1' do
+      issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
+      assert issue.is_a?(Issue)
+      assert_equal Date.today, issue.start_date
+    end
+  end
+
   def test_add_issue_with_cc
     issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
     assert issue.is_a?(Issue)
@@ -264,6 +273,7 @@
   end
 
   def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
+    lft1 = new_issue_lft
     assert_no_difference 'User.count' do
       assert_difference 'Issue.count' do
         issue = submit_email(
@@ -275,7 +285,7 @@
         assert issue.is_a?(Issue)
         assert issue.author.anonymous?
         assert !issue.project.is_public?
-        assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
+        assert_equal [issue.id, lft1, lft1 + 1], [issue.root_id, issue.lft, issue.rgt]
       end
     end
   end
@@ -304,25 +314,81 @@
     end
   end
 
+  def test_created_user_should_be_added_to_groups
+    group1 = Group.generate!
+    group2 = Group.generate!
+
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :default_group => "#{group1.name},#{group2.name}"
+      )
+    end
+    user = User.order('id DESC').first
+    assert_same_elements [group1, group2], user.groups
+  end
+
+  def test_created_user_should_not_receive_account_information_with_no_account_info_option
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :no_account_notice => '1'
+      )
+    end
+
+    # only 1 email for the new issue notification
+    assert_equal 1, ActionMailer::Base.deliveries.size
+    email = ActionMailer::Base.deliveries.first
+    assert_include 'Ticket by unknown user', email.subject
+  end
+
+  def test_created_user_should_have_mail_notification_to_none_with_no_notification_option
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :no_notification => '1'
+      )
+    end
+    user = User.order('id DESC').first
+    assert_equal 'none', user.mail_notification
+  end
+
   def test_add_issue_without_from_header
     Role.anonymous.add_permission!(:add_issues)
     assert_equal false, submit_email('ticket_without_from_header.eml')
   end
 
   def test_add_issue_with_invalid_attributes
-    issue = submit_email(
-              'ticket_with_invalid_attributes.eml',
-              :allow_override => 'tracker,category,priority'
-            )
+    with_settings :default_issue_start_date_to_creation_date => '0' do
+      issue = submit_email(
+                'ticket_with_invalid_attributes.eml',
+                :allow_override => 'tracker,category,priority'
+              )
+      assert issue.is_a?(Issue)
+      assert !issue.new_record?
+      issue.reload
+      assert_nil issue.assigned_to
+      assert_nil issue.start_date
+      assert_nil issue.due_date
+      assert_equal 0, issue.done_ratio
+      assert_equal 'Normal', issue.priority.to_s
+      assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+    end
+  end
+
+  def test_add_issue_with_invalid_project_should_be_assigned_to_default_project
+    issue = submit_email('ticket_on_given_project.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'project') do |email|
+      email.gsub!(/^Project:.+$/, 'Project: invalid')
+    end
     assert issue.is_a?(Issue)
     assert !issue.new_record?
-    issue.reload
-    assert_nil issue.assigned_to
-    assert_nil issue.start_date
-    assert_nil issue.due_date
-    assert_equal 0, issue.done_ratio
-    assert_equal 'Normal', issue.priority.to_s
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+    assert_equal 'ecookbook', issue.project.identifier
   end
 
   def test_add_issue_with_localized_attributes
@@ -447,6 +513,21 @@
     assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
   end
 
+  def test_multiple_inline_text_parts_should_be_appended_to_issue_description
+    issue = submit_email('multiple_text_parts.eml', :issue => {:project => 'ecookbook'})
+    assert_include 'first', issue.description
+    assert_include 'second', issue.description
+    assert_include 'third', issue.description
+  end
+
+  def test_attachment_text_part_should_be_added_as_issue_attachment
+    issue = submit_email('multiple_text_parts.eml', :issue => {:project => 'ecookbook'})
+    assert_not_include 'Plain text attachment', issue.description
+    attachment = issue.attachments.detect {|a| a.filename == 'textfile.txt'}
+    assert_not_nil attachment
+    assert_include 'Plain text attachment', File.read(attachment.diskfile)
+  end
+
   def test_add_issue_with_iso_8859_1_subject
     issue = submit_email(
               'subject_as_iso-8859-1.eml',
@@ -469,6 +550,23 @@
     assert_equal ja, issue.subject
   end
 
+  def test_add_issue_with_korean_body
+    # Make sure mail bodies with a charset unknown to Ruby
+    # but known to the Mail gem 2.5.4 are handled correctly
+    kr = "\xEA\xB3\xA0\xEB\xA7\x99\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4."
+    if !kr.respond_to?(:force_encoding)
+      puts "\nOn Ruby 1.8, skip Korean encoding mail body test"
+    else
+      kr.force_encoding('UTF-8')
+      issue = submit_email(
+              'body_ks_c_5601-1987.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+      assert_kind_of Issue, issue
+      assert_equal kr, issue.description
+    end
+  end
+
   def test_add_issue_with_no_subject_header
     issue = submit_email(
               'no_subject_header.eml',
@@ -577,7 +675,7 @@
         end
       end
     end
-    journal = Journal.first(:order => 'id DESC')
+    journal = Journal.order('id DESC').first
     assert_equal Issue.find(2), journal.journalized
     assert_equal 1, journal.details.size
 
@@ -646,73 +744,73 @@
     assert_equal 'This is a html-only email.', issue.description
   end
 
-  context "truncate emails based on the Setting" do
-    context "with no setting" do
-      setup do
-        Setting.mail_handler_body_delimiters = ''
-      end
+  test "truncate emails with no setting should add the entire email into the issue" do
+    with_settings :mail_handler_body_delimiters => '' do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('---')
+      assert issue.description.include?('This paragraph is after the delimiter')
+    end
+  end
 
-      should "add the entire email into the issue" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('---')
-        assert issue.description.include?('This paragraph is after the delimiter')
-      end
+  test "truncate emails with a single string should truncate the email at the delimiter for the issue" do
+    with_settings :mail_handler_body_delimiters => '---' do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('This paragraph is before delimiters')
+      assert issue.description.include?('--- This line starts with a delimiter')
+      assert !issue.description.match(/^---$/)
+      assert !issue.description.include?('This paragraph is after the delimiter')
     end
+  end
 
-    context "with a single string" do
-      setup do
-        Setting.mail_handler_body_delimiters = '---'
-      end
-      should "truncate the email at the delimiter for the issue" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('This paragraph is before delimiters')
-        assert issue.description.include?('--- This line starts with a delimiter')
-        assert !issue.description.match(/^---$/)
-        assert !issue.description.include?('This paragraph is after the delimiter')
-      end
+  test "truncate emails with a single quoted reply should truncate the email at the delimiter with the quoted reply symbols (>)" do
+    with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do
+      journal = submit_email('issue_update_with_quoted_reply_above.eml')
+      assert journal.is_a?(Journal)
+      assert journal.notes.include?('An update to the issue by the sender.')
+      assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
+      assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
     end
+  end
 
-    context "with a single quoted reply (e.g. reply to a Redmine email notification)" do
-      setup do
-        Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
-      end
-      should "truncate the email at the delimiter with the quoted reply symbols (>)" do
-        journal = submit_email('issue_update_with_quoted_reply_above.eml')
-        assert journal.is_a?(Journal)
-        assert journal.notes.include?('An update to the issue by the sender.')
-        assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
-        assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
-      end
+  test "truncate emails with multiple quoted replies should truncate the email at the delimiter with the quoted reply symbols (>)" do
+    with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do
+      journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
+      assert journal.is_a?(Journal)
+      assert journal.notes.include?('An update to the issue by the sender.')
+      assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
+      assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
     end
+  end
 
-    context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do
-      setup do
-        Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
-      end
-      should "truncate the email at the delimiter with the quoted reply symbols (>)" do
-        journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
-        assert journal.is_a?(Journal)
-        assert journal.notes.include?('An update to the issue by the sender.')
-        assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
-        assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
-      end
+  test "truncate emails with multiple strings should truncate the email at the first delimiter found (BREAK)" do
+    with_settings :mail_handler_body_delimiters => "---\nBREAK" do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('This paragraph is before delimiters')
+      assert !issue.description.include?('BREAK')
+      assert !issue.description.include?('This paragraph is between delimiters')
+      assert !issue.description.match(/^---$/)
+      assert !issue.description.include?('This paragraph is after the delimiter')
     end
+  end
 
-    context "with multiple strings" do
-      setup do
-        Setting.mail_handler_body_delimiters = "---\nBREAK"
-      end
-      should "truncate the email at the first delimiter found (BREAK)" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('This paragraph is before delimiters')
-        assert !issue.description.include?('BREAK')
-        assert !issue.description.include?('This paragraph is between delimiters')
-        assert !issue.description.match(/^---$/)
-        assert !issue.description.include?('This paragraph is after the delimiter')
-      end
+  def test_attachments_that_match_mail_handler_excluded_filenames_should_be_ignored
+    with_settings :mail_handler_excluded_filenames => '*.vcf, *.jpg' do
+      issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
+      assert issue.is_a?(Issue)
+      assert !issue.new_record?
+      assert_equal 0, issue.reload.attachments.size
+    end
+  end
+
+  def test_attachments_that_do_not_match_mail_handler_excluded_filenames_should_be_attached
+    with_settings :mail_handler_excluded_filenames => '*.vcf, *.gif' do
+      issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
+      assert issue.is_a?(Issue)
+      assert !issue.new_record?
+      assert_equal 1, issue.reload.attachments.size
     end
   end
 
@@ -741,14 +839,7 @@
       assert_equal expected[0], user.login
       assert_equal expected[1], user.firstname
       assert_equal expected[2], user.lastname
-    end
-  end
-
-  def test_new_user_from_attributes_should_respect_minimum_password_length
-    with_settings :password_min_length => 15 do
-      user = MailHandler.new_user_from_attributes('jsmith@example.net')
-      assert user.valid?
-      assert user.password.length >= 15
+      assert_equal 'only_my_events', user.mail_notification
     end
   end
 
@@ -767,8 +858,7 @@
                 :unknown_user => 'create'
               )
     end
-
-    user = User.first(:order => 'id DESC')
+    user = User.order('id DESC').first
     assert_equal "foo@example.org", user.mail
     str1 = "\xc3\x84\xc3\xa4"
     str2 = "\xc3\x96\xc3\xb6"
@@ -778,6 +868,19 @@
     assert_equal str2, user.lastname
   end
 
+  def test_extract_options_from_env_should_return_options
+    options = MailHandler.extract_options_from_env({
+      'tracker' => 'defect',
+      'project' => 'foo',
+      'unknown_user' => 'create'
+    })
+
+    assert_equal({
+      :issue => {:tracker => 'defect', :project => 'foo'},
+      :unknown_user => 'create'
+    }, options)
+  end
+
   private
 
   def submit_email(filename, options={})