From f338fe9075e16de82a3bcbc860675d3404e8a774 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Wed, 8 Mar 2017 19:55:56 +0000 Subject: [PATCH] Allow to set multiple values in emails for list custom fields (#16549). git-svn-id: http://svn.redmine.org/redmine/trunk@16380 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- lib/redmine/field_format.rb | 48 +++++++++++++++---- .../ticket_with_custom_fields.eml | 1 + .../field_format/enumeration_format_test.rb | 9 ++++ .../redmine/field_format/list_format_test.rb | 20 ++++++++ .../field_format/user_field_format_test.rb | 18 +++++++ test/unit/mail_handler_test.rb | 5 +- 6 files changed, 90 insertions(+), 11 deletions(-) diff --git a/lib/redmine/field_format.rb b/lib/redmine/field_format.rb index cfdab0e21..c1ce0055c 100644 --- a/lib/redmine/field_format.rb +++ b/lib/redmine/field_format.rb @@ -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) diff --git a/test/fixtures/mail_handler/ticket_with_custom_fields.eml b/test/fixtures/mail_handler/ticket_with_custom_fields.eml index 58dde7e0f..177ec5f2f 100644 --- a/test/fixtures/mail_handler/ticket_with_custom_fields.eml +++ b/test/fixtures/mail_handler/ticket_with_custom_fields.eml @@ -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 diff --git a/test/unit/lib/redmine/field_format/enumeration_format_test.rb b/test/unit/lib/redmine/field_format/enumeration_format_test.rb index 467c1ed9d..457a48194 100644 --- a/test/unit/lib/redmine/field_format/enumeration_format_test.rb +++ b/test/unit/lib/redmine/field_format/enumeration_format_test.rb @@ -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 diff --git a/test/unit/lib/redmine/field_format/list_format_test.rb b/test/unit/lib/redmine/field_format/list_format_test.rb index af44cc59f..1677aea8e 100644 --- a/test/unit/lib/redmine/field_format/list_format_test.rb +++ b/test/unit/lib/redmine/field_format/list_format_test.rb @@ -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 diff --git a/test/unit/lib/redmine/field_format/user_field_format_test.rb b/test/unit/lib/redmine/field_format/user_field_format_test.rb index 6aa751be8..ca35746dc 100644 --- a/test/unit/lib/redmine/field_format/user_field_format_test.rb +++ b/test/unit/lib/redmine/field_format/user_field_format_test.rb @@ -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 diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb index 5f0b3e3e0..e6c20481e 100644 --- a/test/unit/mail_handler_test.rb +++ b/test/unit/mail_handler_test.rb @@ -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 -- 2.39.5