]> source.dussan.org Git - redmine.git/commitdiff
Allow to set multiple values in emails for list custom fields (#16549).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Wed, 8 Mar 2017 19:55:56 +0000 (19:55 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Wed, 8 Mar 2017 19:55:56 +0000 (19:55 +0000)
git-svn-id: http://svn.redmine.org/redmine/trunk@16380 e93f8b46-1217-0410-a6f0-8f06a7374b81

lib/redmine/field_format.rb
test/fixtures/mail_handler/ticket_with_custom_fields.eml
test/unit/lib/redmine/field_format/enumeration_format_test.rb
test/unit/lib/redmine/field_format/list_format_test.rb
test/unit/lib/redmine/field_format/user_field_format_test.rb
test/unit/mail_handler_test.rb

index cfdab0e21c5672f36172ebb90252855cf7125fcb..c1ce0055c05e332d12f4fc01f24550d46132277f 100644 (file)
@@ -167,12 +167,13 @@ module Redmine
       def value_from_keyword(custom_field, keyword, object)
         possible_values_options = possible_values_options(custom_field, object)
         if possible_values_options.present?
-          keyword = keyword.to_s
-          if v = possible_values_options.detect {|text, id| keyword.casecmp(text)  == 0}
-            if v.is_a?(Array)
-              v.last
-            else
-              v
+          parse_keyword(custom_field, keyword) do |k|
+            if v = possible_values_options.detect {|text, id| k.casecmp(text) == 0}
+              if v.is_a?(Array)
+                v.last
+              else
+                v
+              end
             end
           end
         else
@@ -180,6 +181,31 @@ module Redmine
         end
       end
 
+      def parse_keyword(custom_field, keyword, &block)
+        separator = Regexp.escape ","
+        keyword = keyword.to_s
+
+        if custom_field.multiple?
+          values = []
+          while keyword.length > 0
+            k = keyword.dup
+            loop do
+              if value = yield(k.strip)
+                values << value
+                break
+              elsif k.slice!(/#{separator}([^#{separator}]*)\Z/).nil?
+                break
+              end
+            end
+            keyword.slice!(/\A#{Regexp.escape k}#{separator}?/)
+          end
+          values
+        else
+          yield keyword.strip
+        end
+      end
+      protected :parse_keyword
+
       # Returns the validation errors for custom_field
       # Should return an empty array if custom_field is valid
       def validate_custom_field(custom_field)
@@ -766,8 +792,9 @@ module Redmine
       end
 
       def value_from_keyword(custom_field, keyword, object)
-        value = custom_field.enumerations.where("LOWER(name) LIKE LOWER(?)", keyword).first
-        value ? value.id : nil
+        parse_keyword(custom_field, keyword) do |k|
+          custom_field.enumerations.where("LOWER(name) LIKE LOWER(?)", k).first.try(:id)
+        end
       end
     end
 
@@ -800,8 +827,9 @@ module Redmine
 
       def value_from_keyword(custom_field, keyword, object)
         users = possible_values_records(custom_field, object).to_a
-        user = Principal.detect_by_keyword(users, keyword)
-        user ? user.id : nil
+        parse_keyword(custom_field, keyword) do |k|
+          Principal.detect_by_keyword(users, k).try(:id)
+        end
       end
 
       def before_custom_field_save(custom_field)
index 58dde7e0f9cc7163d11a7c9032906c34f28ed906..177ec5f2f0aae016b7e2673fd60d8f02b3103bbe 100644 (file)
@@ -40,3 +40,4 @@ pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
 category: Stock management
 searchable field: Value for a custom field
 Database:  postgresql
+OS: Mac OS X  ,windows
index 467c1ed9d87f3503a12ae1d98da5f81341f99009..457a48194acc2845dc28a36ea7cf49941544e7ea 100644 (file)
@@ -87,5 +87,14 @@ class Redmine::EnumerationFieldFormatTest < ActionView::TestCase
 
   def test_value_from_keyword_should_return_enumeration_id
     assert_equal @foo.id, @field.value_from_keyword('foo', nil)
+    assert_nil @field.value_from_keyword('baz', nil)
+  end
+
+  def test_value_from_keyword_for_multiple_custom_field_should_return_enumeration_ids
+    @field.multiple = true
+    @field.save!
+    assert_equal [@foo.id, @bar.id], @field.value_from_keyword('foo, bar', nil)
+    assert_equal [@foo.id], @field.value_from_keyword('foo, baz', nil)
+    assert_equal [], @field.value_from_keyword('baz', nil)
   end
 end
index af44cc59f661806bf657b8ccf99cd620f53d4b8d..1677aea8e150a279eca1986ff8865e03eb537455 100644 (file)
@@ -165,4 +165,24 @@ class Redmine::ListFieldFormatTest < ActionView::TestCase
       end
     end
   end
+
+  def test_value_from_keyword_should_return_value
+    field = GroupCustomField.create!(:name => 'List', :field_format => 'list', :possible_values => ['Foo', 'Bar', 'Baz,qux'])
+
+    assert_equal 'Foo', field.value_from_keyword('foo', nil)
+    assert_equal 'Baz,qux', field.value_from_keyword('baz,qux', nil)
+    assert_nil field.value_from_keyword('invalid', nil)
+  end
+
+  def test_value_from_keyword_for_multiple_custom_field_should_return_values
+    field = GroupCustomField.create!(:name => 'List', :field_format => 'list', :possible_values => ['Foo', 'Bar', 'Baz,qux'], :multiple => true)
+
+    assert_equal ['Foo','Bar'], field.value_from_keyword('foo,bar', nil)
+    assert_equal ['Baz,qux'], field.value_from_keyword('baz,qux', nil)
+    assert_equal ['Baz,qux', 'Foo'], field.value_from_keyword('baz,qux,foo', nil)
+    assert_equal ['Foo'], field.value_from_keyword('foo,invalid', nil)
+    assert_equal ['Foo'], field.value_from_keyword(',foo,', nil)
+    assert_equal ['Foo'], field.value_from_keyword(',foo, ,,', nil)
+    assert_equal [], field.value_from_keyword('invalid', nil)
+  end
 end
index 6aa751be8b93d334653078cd4d6e24565143472b..ca35746dc692c6427be90dc97675dc764983081c 100644 (file)
@@ -58,4 +58,22 @@ class Redmine::UserFieldFormatTest < ActionView::TestCase
 
     assert_equal ['Dave Lopper'], field.possible_values_options(project).map(&:first)
   end
+
+  def test_value_from_keyword_should_return_user_id
+    field = IssueCustomField.new(:field_format => 'user')
+    project = Project.find(1)
+
+    assert_equal 2, field.value_from_keyword('jsmith', project)
+    assert_equal 3, field.value_from_keyword('Dave Lopper', project)
+    assert_nil field.value_from_keyword('Unknown User', project)
+  end
+
+  def test_value_from_keyword_for_multiple_custom_field_should_return_enumeration_ids
+    field = IssueCustomField.new(:field_format => 'user', :multiple => true)
+    project = Project.find(1)
+
+    assert_equal [2, 3], field.value_from_keyword('jsmith, Dave Lopper', project)
+    assert_equal [2], field.value_from_keyword('jsmith', project)
+    assert_equal [], field.value_from_keyword('Unknown User', project)
+  end
 end
index 5f0b3e3e0947515f0884a5e6c228ed527c07dc79..e6c20481e4a0d232f9d14bfaeb8d91f47b1a2f03 100644 (file)
@@ -232,8 +232,10 @@ class MailHandlerTest < ActiveSupport::TestCase
   end
 
   def test_add_issue_with_custom_fields
+    mutiple = IssueCustomField.generate!(:field_format => 'list', :name => 'OS', :multiple => true, :possible_values => ['Linux', 'Windows', 'Mac OS X'])
+
     issue = submit_email('ticket_with_custom_fields.eml',
-      :issue => {:project => 'onlinestore'}, :allow_override => ['database', 'Searchable_field']
+      :issue => {:project => 'onlinestore'}, :allow_override => ['database', 'Searchable_field', 'OS']
     )
     assert issue.is_a?(Issue)
     assert !issue.new_record?
@@ -241,6 +243,7 @@ class MailHandlerTest < ActiveSupport::TestCase
     assert_equal 'New ticket with custom field values', issue.subject
     assert_equal 'PostgreSQL', issue.custom_field_value(1)
     assert_equal 'Value for a custom field', issue.custom_field_value(2)
+    assert_equal ['Mac OS X', 'Windows'], issue.custom_field_value(mutiple.id).sort
     assert !issue.description.match(/^searchable field:/i)
   end