Feature #21026 » 0001-Add-an-option-to-allow-groups-in-user-custom-fields-.patch
| app/models/custom_field.rb | ||
|---|---|---|
| 99 | 99 |
'text_formatting', |
| 100 | 100 |
'edit_tag_style', |
| 101 | 101 |
'user_role', |
| 102 |
'possible_principals', |
|
| 102 | 103 |
'version_status', |
| 103 | 104 |
'extensions_allowed', |
| 104 | 105 |
'full_width_layout', |
| app/models/group.rb | ||
|---|---|---|
| 118 | 118 |
Issue.where(['assigned_to_id = ?', id]).update_all('assigned_to_id = NULL')
|
| 119 | 119 |
Watcher.where('user_id = ?', id).delete_all
|
| 120 |
remove_user_custom_field_references |
|
| 120 | 121 |
end |
| 121 | 122 |
end |
| app/models/principal.rb | ||
|---|---|---|
| 211 | 211 |
Project.where(default_assigned_to: self).update_all(default_assigned_to_id: nil) |
| 212 | 212 |
end |
| 213 |
# Removes the values of user custom fields that reference the principal |
|
| 214 |
def remove_user_custom_field_references |
|
| 215 |
user_custom_field_ids = CustomField.where(field_format: 'user').ids |
|
| 216 |
if user_custom_field_ids.any? |
|
| 217 |
CustomValue.where(custom_field_id: user_custom_field_ids, value: id.to_s).delete_all |
|
| 218 |
end |
|
| 219 |
end |
|
| 220 | ||
| 213 | 221 |
protected |
| 214 | 222 |
# Make sure we don't try to insert NULL values (see #4632) |
| app/models/query.rb | ||
|---|---|---|
| 1173 | 1173 |
if filter[:field].format.target_class && filter[:field].format.target_class <= User |
| 1174 | 1174 |
if value.delete('me')
|
| 1175 | 1175 |
value.push User.current.id.to_s |
| 1176 |
if filter[:field].format.try(:selectable_principal_types, filter[:field])&.include?('Group')
|
|
| 1177 |
value += User.current.group_ids.map(&:to_s) |
|
| 1178 |
end |
|
| 1176 | 1179 |
end |
| 1177 | 1180 |
end |
| 1178 | 1181 |
not_in = nil |
| app/models/user.rb | ||
|---|---|---|
| 1016 | 1016 |
Watcher.where('user_id = ?', id).delete_all
|
| 1017 | 1017 |
WikiContent.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) |
| 1018 | 1018 |
WikiContentVersion.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id]) |
| 1019 |
user_custom_field_ids = CustomField.where(field_format: 'user').ids |
|
| 1020 |
if user_custom_field_ids.any? |
|
| 1021 |
CustomValue.where(custom_field_id: user_custom_field_ids, value: self.id.to_s).delete_all |
|
| 1022 |
end |
|
| 1019 |
remove_user_custom_field_references |
|
| 1023 | 1020 |
end |
| 1024 | 1021 |
# Singleton class method is public |
| app/views/custom_fields/formats/_user.html.erb | ||
|---|---|---|
| 1 |
<p><%= f.select :possible_principals, |
|
| 2 |
[ |
|
| 3 |
[l(:label_user_plural), 'user'], |
|
| 4 |
[l(:label_users_and_groups), 'user_group'], |
|
| 5 |
[l(:label_group_plural), 'group'] |
|
| 6 |
], |
|
| 7 |
:label => :field_possible_values %></p> |
|
| 1 | 8 |
<p> |
| 2 | 9 |
<label><%= l(:label_role) %></label> |
| 3 | 10 |
<label class="block"> |
| config/locales/en.yml | ||
|---|---|---|
| 633 | 633 |
label_user: User |
| 634 | 634 |
label_user_plural: Users |
| 635 |
label_users_and_groups: Users and groups |
|
| 635 | 636 |
label_user_new: New user |
| 636 | 637 |
label_user_anonymous: Anonymous |
| 637 | 638 |
label_project: Project |
| config/locales/ja.yml | ||
|---|---|---|
| 471 | 471 |
label_user: ユーザー |
| 472 | 472 |
label_user_plural: ユーザー |
| 473 |
label_users_and_groups: ユーザーとグループ |
|
| 473 | 474 |
label_user_new: 新しいユーザー |
| 474 | 475 |
label_user_anonymous: 匿名ユーザー |
| 475 | 476 |
label_profile: プロフィール |
| lib/redmine/field_format.rb | ||
|---|---|---|
| 613 | 613 |
opts = [] |
| 614 | 614 |
opts << [l(:label_no_change_option), ''] unless custom_field.multiple? |
| 615 | 615 |
opts << [l(:label_none), '__none__'] unless custom_field.is_required? |
| 616 |
opts += possible_values_options(custom_field, objects) |
|
| 617 | 616 |
view.select_tag( |
| 618 | 617 |
tag_name, |
| 619 |
view.options_for_select(opts, value), |
|
| 618 |
view.options_for_select(opts, value) + bulk_edit_tag_options(view, custom_field, objects, value),
|
|
| 620 | 619 |
options.merge(:multiple => custom_field.multiple?) |
| 621 | 620 |
) |
| 622 | 621 |
end |
| ... | ... | |
| 652 | 651 |
blank_option = view.content_tag('option', ' '.html_safe, :value => '')
|
| 653 | 652 |
end |
| 654 | 653 |
end |
| 655 |
options_tags = |
|
| 656 |
blank_option + |
|
| 657 |
view.options_for_select(possible_custom_value_options(custom_value), custom_value.value) |
|
| 654 |
options_tags = blank_option + select_edit_tag_options(view, custom_value) |
|
| 658 | 655 |
s = |
| 659 | 656 |
view.select_tag( |
| 660 | 657 |
tag_name, options_tags, |
| ... | ... | |
| 666 | 663 |
s |
| 667 | 664 |
end |
| 665 |
# Returns the option tags of the select edit tag |
|
| 666 |
def select_edit_tag_options(view, custom_value) |
|
| 667 |
view.options_for_select(possible_custom_value_options(custom_value), custom_value.value) |
|
| 668 |
end |
|
| 669 | ||
| 670 |
# Returns the option tags of the bulk edit tag |
|
| 671 |
def bulk_edit_tag_options(view, custom_field, objects, value) |
|
| 672 |
view.options_for_select(possible_values_options(custom_field, objects), value) |
|
| 673 |
end |
|
| 674 | ||
| 668 | 675 |
# Renders the edit tag as check box or radio tags |
| 669 | 676 |
def check_box_edit_tag(view, tag_id, tag_name, custom_value, options={})
|
| 670 | 677 |
opts = [] |
| ... | ... | |
| 871 | 878 |
class UserFormat < RecordList |
| 872 | 879 |
add 'user' |
| 873 | 880 |
self.form_partial = 'custom_fields/formats/user' |
| 874 |
field_attributes :user_role |
|
| 881 |
field_attributes :user_role, :possible_principals |
|
| 882 | ||
| 883 |
# Maps the possible_principals option to the principal types that can be selected |
|
| 884 |
PRINCIPAL_TYPES = {
|
|
| 885 |
'user' => ['User'], |
|
| 886 |
'user_group' => ['User', 'Group'], |
|
| 887 |
'group' => ['Group'] |
|
| 888 |
}.freeze |
|
| 875 | 889 |
def possible_values_options(custom_field, object=nil) |
| 876 |
users = possible_values_records(custom_field, object) |
|
| 877 |
options = users.map {|u| [u.name, u.id.to_s]}
|
|
| 878 |
if !custom_field.multiple? && users.include?(User.current) |
|
| 879 |
options = [["<< #{l(:label_me)} >>", User.current.id.to_s]] + options
|
|
| 880 |
end |
|
| 881 |
options |
|
| 890 |
principals_options(custom_field, possible_values_records(custom_field, object)) |
|
| 882 | 891 |
end |
| 883 | 892 |
def possible_values_records(custom_field, object=nil) |
| ... | ... | |
| 887 | 896 |
projects = object.filter_map {|o| o.respond_to?(:project) ? o.project : nil}.uniq
|
| 888 | 897 |
projects.map {|project| possible_values_records(custom_field, project)}.reduce(:&) || []
|
| 889 | 898 |
elsif object.respond_to?(:project) && object.project |
| 890 |
scope = object.project.users
|
|
| 899 |
scope = object.project.principals.where(:type => selectable_principal_types(custom_field))
|
|
| 891 | 900 |
if custom_field.user_role.is_a?(Array) |
| 892 | 901 |
role_ids = custom_field.user_role.map(&:to_s).reject(&:blank?).map(&:to_i) |
| 893 | 902 |
if role_ids.any? |
| ... | ... | |
| 902 | 911 |
end |
| 903 | 912 |
end |
| 913 |
# Returns the principal types (User and/or Group) that can be |
|
| 914 |
# selected for the given custom field |
|
| 915 |
def selectable_principal_types(custom_field) |
|
| 916 |
PRINCIPAL_TYPES[custom_field.possible_principals.to_s] || PRINCIPAL_TYPES['user'] |
|
| 917 |
end |
|
| 918 | ||
| 919 |
def cast_single_value(custom_field, value, customized=nil) |
|
| 920 |
Principal.find_by_id(value.to_i) if value.present? |
|
| 921 |
end |
|
| 922 | ||
| 923 |
def possible_custom_value_options(custom_value) |
|
| 924 |
principals_options(custom_value.custom_field, possible_custom_value_records(custom_value)) |
|
| 925 |
end |
|
| 926 | ||
| 927 |
# Returns the principals that can be selected for the given custom value, |
|
| 928 |
# including the principals that are currently set but no longer selectable |
|
| 929 |
def possible_custom_value_records(custom_value) |
|
| 930 |
principals = possible_values_records(custom_value.custom_field, custom_value.customized).to_a |
|
| 931 |
missing = [custom_value.value_was].flatten.reject(&:blank?).map(&:to_i) - principals.map(&:id) |
|
| 932 |
if missing.any? |
|
| 933 |
principals += Principal.where(:id => missing).to_a |
|
| 934 |
end |
|
| 935 |
principals |
|
| 936 |
end |
|
| 937 | ||
| 904 | 938 |
def value_from_keyword(custom_field, keyword, object) |
| 905 |
users = possible_values_records(custom_field, object).to_a
|
|
| 939 |
principals = possible_values_records(custom_field, object).to_a
|
|
| 906 | 940 |
parse_keyword(custom_field, keyword) do |k| |
| 907 |
Principal.detect_by_keyword(users, k).try(:id)
|
|
| 941 |
Principal.detect_by_keyword(principals, k).try(:id)
|
|
| 908 | 942 |
end |
| 909 | 943 |
end |
| ... | ... | |
| 916 | 950 |
end |
| 917 | 951 |
end |
| 952 |
protected |
|
| 953 | ||
| 954 |
def select_edit_tag_options(view, custom_value) |
|
| 955 |
principals_option_tags(view, custom_value.custom_field, |
|
| 956 |
possible_custom_value_records(custom_value), custom_value.value) |
|
| 957 |
end |
|
| 958 | ||
| 959 |
def bulk_edit_tag_options(view, custom_field, objects, value) |
|
| 960 |
principals_option_tags(view, custom_field, possible_values_records(custom_field, objects), value) |
|
| 961 |
end |
|
| 962 | ||
| 963 |
# Returns the [name, id] options for the given principals, |
|
| 964 |
# with the "me" option first when the current user is selectable |
|
| 965 |
def principals_options(custom_field, principals) |
|
| 966 |
me_options(custom_field, principals) + principals_to_options(principals) |
|
| 967 |
end |
|
| 968 | ||
| 969 |
# Renders the option tags for the given principals. When both users |
|
| 970 |
# and groups are present, they are listed in separate optgroups |
|
| 971 |
def principals_option_tags(view, custom_field, principals, selected) |
|
| 972 |
users, groups = principals.partition {|principal| principal.is_a?(User)}
|
|
| 973 |
options = view.options_for_select(me_options(custom_field, principals), selected) |
|
| 974 |
if users.any? && groups.any? |
|
| 975 |
optgroups = [ |
|
| 976 |
[l(:label_user_plural), principals_to_options(users)], |
|
| 977 |
[l(:label_group_plural), principals_to_options(groups)] |
|
| 978 |
] |
|
| 979 |
options + view.grouped_options_for_select(optgroups, selected) |
|
| 980 |
else |
|
| 981 |
options + view.options_for_select(principals_to_options(principals), selected) |
|
| 982 |
end |
|
| 983 |
end |
|
| 984 | ||
| 985 |
def me_options(custom_field, principals) |
|
| 986 |
if !custom_field.multiple? && principals.include?(User.current) |
|
| 987 |
[["<< #{l(:label_me)} >>", User.current.id.to_s]]
|
|
| 988 |
else |
|
| 989 |
[] |
|
| 990 |
end |
|
| 991 |
end |
|
| 992 | ||
| 993 |
def principals_to_options(principals) |
|
| 994 |
principals.map {|principal| [principal.name, principal.id.to_s]}
|
|
| 995 |
end |
|
| 996 | ||
| 918 | 997 |
def query_filter_values(custom_field, query) |
| 919 |
query.author_values |
|
| 998 |
types = selectable_principal_types(custom_field) |
|
| 999 |
values = |
|
| 1000 |
query.principals.select {|p| types.include?(p.type)}.
|
|
| 1001 |
sort_by {|p| [p.status, p]}.
|
|
| 1002 |
collect {|p| [p.name, p.id.to_s, l("status_#{User::LABEL_BY_STATUS[p.status]}")]}
|
|
| 1003 |
values.unshift(["<< #{l(:label_me)} >>", "me"]) if User.current.logged?
|
|
| 1004 |
values |
|
| 920 | 1005 |
end |
| 921 | 1006 |
end |
| test/functional/custom_fields_controller_test.rb | ||
|---|---|---|
| 455 | 455 |
assert_equal [1, 3], field.projects.map(&:id).sort |
| 456 | 456 |
end |
| 457 |
def test_create_user_custom_field |
|
| 458 |
assert_difference 'CustomField.count' do |
|
| 459 |
post( |
|
| 460 |
:create, |
|
| 461 |
:params => {
|
|
| 462 |
:type => "IssueCustomField", |
|
| 463 |
:custom_field => {
|
|
| 464 |
:name => "foo", |
|
| 465 |
:field_format => "user", |
|
| 466 |
:possible_principals => "user_group" |
|
| 467 |
} |
|
| 468 |
} |
|
| 469 |
) |
|
| 470 |
assert_response :found |
|
| 471 |
end |
|
| 472 |
field = IssueCustomField.order(id: :desc).first |
|
| 473 |
assert_equal 'user_group', field.possible_principals |
|
| 474 |
end |
|
| 475 | ||
| 457 | 476 |
def test_create_with_continue_params |
| 458 | 477 |
assert_difference 'CustomField.count' do |
| 459 | 478 |
post( |
| test/unit/group_test.rb | ||
|---|---|---|
| 121 | 121 |
assert !User.find(8).member_of?(Project.find(5)) |
| 122 | 122 |
end |
| 123 |
def test_destroy_should_unassign_and_unwatch_issues
|
|
| 123 |
def test_destroy_should_remove_references_from_issues
|
|
| 124 | 124 |
group = Group.find(10) |
| 125 | 125 |
Issue.where(:id => 1).update_all(["assigned_to_id = ?", group.id]) |
| 126 | 126 |
issue = Issue.find(2) |
| ... | ... | |
| 129 | 129 |
issue.save |
| 130 | 130 |
issue.reload |
| 131 | 131 |
assert issue.watcher_user_ids.include?(10) |
| 132 |
cf = IssueCustomField.create!(:field_format => 'user', :possible_principals => 'user_group', :is_for_all => true, :name => 'User custom field', :tracker_ids => [1]) |
|
| 133 |
issue_with_cf = Issue.generate!(:project_id => 5, :tracker_id => 1, :custom_field_values => {cf.id.to_s => group.id.to_s})
|
|
| 134 |
assert_equal group.id.to_s, issue_with_cf.reload.custom_field_value(cf) |
|
| 132 | 135 |
assert group.destroy |
| 133 | 136 |
assert group.destroyed? |
| ... | ... | |
| 136 | 139 |
assert_nil Issue.find(1).assigned_to_id |
| 137 | 140 |
issue.reload |
| 138 | 141 |
assert !issue.watcher_user_ids.include?(10) |
| 142 |
assert_equal '', issue_with_cf.reload.custom_field_value(cf).to_s |
|
| 139 | 143 |
end |
| 140 | 144 |
def test_builtin_groups_should_be_created_if_missing |
| test/unit/lib/redmine/field_format/user_field_format_test.rb | ||
|---|---|---|
| 65 | 65 |
field = IssueCustomField.new(:field_format => 'user') |
| 66 | 66 |
project = Project.find(1) |
| 67 |
assert_nil field.possible_principals |
|
| 67 | 68 |
assert_equal ['Dave Lopper', 'John Smith'], field.possible_values_options(project).map(&:first) |
| 68 | 69 |
end |
| 69 | 70 |
def test_possible_values_options_should_return_project_members_with_selected_role |
| 70 |
field = IssueCustomField.new(:field_format => 'user', :user_role => ["2"]) |
|
| 71 |
project = Project.find(1)
|
|
| 71 |
field = IssueCustomField.new(:field_format => 'user', :possible_principals => 'user_group', :user_role => ["2"])
|
|
| 72 |
project = Project.find(5)
|
|
| 72 |
assert_equal ['Dave Lopper'], field.possible_values_options(project).map(&:first)
|
|
| 73 |
assert_equal ['User Misc', 'A Team'], field.possible_values_options(project).map(&:first)
|
|
| 73 | 74 |
end |
| 74 | 75 |
def test_possible_values_options_should_return_project_members_and_me_if_logged_in |
| ... | ... | |
| 109 | 110 |
assert_equal [2], field.value_from_keyword('jsmith', project)
|
| 110 | 111 |
assert_equal [], field.value_from_keyword('Unknown User', project)
|
| 111 | 112 |
end |
| 113 | ||
| 114 |
def test_possible_values_options_with_groups_only_should_include_groups_only |
|
| 115 |
# The current user is a member of the project but should not be included |
|
| 116 |
User.current = User.find(2) |
|
| 117 |
field = IssueCustomField.new(:field_format => 'user', :possible_principals => 'group') |
|
| 118 |
project = Project.find(5) |
|
| 119 | ||
| 120 |
assert_equal [['A Team', '10']], field.possible_values_options(project) |
|
| 121 |
end |
|
| 122 | ||
| 123 |
def test_group_value_should_be_invalid_when_groups_are_not_allowed |
|
| 124 |
field = IssueCustomField.create!(:name => 'Foo', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all) |
|
| 125 |
issue = Issue.new(:project_id => 5, :tracker_id => 1, :author_id => 2, :subject => 'Test', |
|
| 126 |
:custom_field_values => {field.id => '10'})
|
|
| 127 | ||
| 128 |
assert_equal false, issue.valid? |
|
| 129 |
assert_include "Foo #{::I18n.t('activerecord.errors.messages.inclusion')}", issue.errors.full_messages.first
|
|
| 130 |
end |
|
| 131 | ||
| 132 |
def test_existing_group_value_should_remain_valid_after_disallowing_groups |
|
| 133 |
field = IssueCustomField.create!(:name => 'Foo', :field_format => 'user', :possible_principals => 'user_group', |
|
| 134 |
:is_for_all => true, :trackers => Tracker.all) |
|
| 135 |
issue = Issue.generate!(:project_id => 5, :tracker_id => 1, :custom_field_values => {field.id => '10'})
|
|
| 136 | ||
| 137 |
field.update!(:possible_principals => 'user') |
|
| 138 |
issue.reload |
|
| 139 |
assert_equal '10', issue.custom_field_value(field) |
|
| 140 |
assert issue.valid? |
|
| 141 |
assert_equal 'A Team', field.format.formatted_value(self, field, '10', issue).to_s |
|
| 142 | ||
| 143 |
# Group can still be selected for the issue, but not for other issues |
|
| 144 |
assert_include '10', issue.custom_field_values.detect {|v| v.custom_field == field}.then {|v| field.format.possible_custom_value_options(v)}.map(&:last)
|
|
| 145 |
assert_not_include '10', field.possible_values_options(Issue.new(:project_id => 5)).map(&:last) |
|
| 146 |
end |
|
| 147 | ||
| 148 |
def test_edit_tag_should_not_use_optgroups_with_users_only_or_groups_only |
|
| 149 |
field = IssueCustomField.new(:field_format => 'user', :is_required => false) |
|
| 150 |
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new(:project_id => 5)) |
|
| 151 |
tag = field.format.edit_tag(self, 'abc', 'xyz', value) |
|
| 152 |
assert_select_in tag, 'select[id=abc][name=xyz]' do |
|
| 153 |
assert_select 'optgroup', 0 |
|
| 154 |
assert_select 'select > option[value="2"]', :text => 'John Smith' |
|
| 155 |
assert_select 'option[value="10"]', 0 |
|
| 156 |
end |
|
| 157 | ||
| 158 |
field = IssueCustomField.new(:field_format => 'user', :possible_principals => 'group', :is_required => false) |
|
| 159 |
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new(:project_id => 5)) |
|
| 160 |
tag = field.format.edit_tag(self, 'abc', 'xyz', value) |
|
| 161 |
assert_select_in tag, 'select[id=abc][name=xyz]' do |
|
| 162 |
assert_select 'optgroup', 0 |
|
| 163 |
assert_select 'select > option[value="10"]', :text => 'A Team' |
|
| 164 |
assert_select 'option[value="2"]', 0 |
|
| 165 |
end |
|
| 166 |
end |
|
| 167 | ||
| 168 |
def test_edit_tag_with_groups_should_group_users_and_groups_in_optgroups |
|
| 169 |
set_language_if_valid 'en' |
|
| 170 |
User.current = User.find(2) |
|
| 171 |
field = IssueCustomField.new(:field_format => 'user', :possible_principals => 'user_group', :is_required => false) |
|
| 172 |
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new(:project_id => 5)) |
|
| 173 | ||
| 174 |
tag = field.format.edit_tag(self, 'abc', 'xyz', value) |
|
| 175 |
assert_select_in tag, 'select[id=abc][name=xyz]' do |
|
| 176 |
assert_select 'option', :text => '<< me >>', :count => 1 |
|
| 177 |
assert_select 'optgroup', 2 |
|
| 178 |
assert_select 'optgroup:nth-of-type(1)[label="Users"]' do |
|
| 179 |
assert_select 'option[value="2"]', :text => 'John Smith' |
|
| 180 |
assert_select 'option[value="10"]', 0 |
|
| 181 |
end |
|
| 182 |
assert_select 'optgroup:nth-of-type(2)[label="Groups"]' do |
|
| 183 |
assert_select 'option', 1 |
|
| 184 |
assert_select 'option[value="10"]', :text => 'A Team' |
|
| 185 |
end |
|
| 186 |
end |
|
| 187 |
end |
|
| 188 | ||
| 189 |
def test_bulk_edit_tag_with_groups_should_group_users_and_groups_in_optgroups |
|
| 190 |
set_language_if_valid 'en' |
|
| 191 |
field = IssueCustomField.new(:field_format => 'user', :possible_principals => 'user_group', :is_required => false) |
|
| 192 |
issues = [Issue.new(:project_id => 5), Issue.new(:project_id => 5)] |
|
| 193 | ||
| 194 |
tag = field.format.bulk_edit_tag(self, 'abc', 'xyz', field, issues, '') |
|
| 195 |
assert_select_in tag, 'select[name=xyz]' do |
|
| 196 |
assert_select 'select > option[value=""]' |
|
| 197 |
assert_select 'select > option[value="__none__"]' |
|
| 198 |
assert_select 'optgroup[label="Users"] option[value="2"]', :text => 'John Smith' |
|
| 199 |
assert_select 'optgroup[label="Groups"] option[value="10"]', :text => 'A Team' |
|
| 200 |
end |
|
| 201 |
end |
|
| 202 | ||
| 203 |
def test_value_from_keyword_should_return_group_id_when_groups_are_allowed |
|
| 204 |
project = Project.find(5) |
|
| 205 | ||
| 206 |
field = IssueCustomField.new(:field_format => 'user', :possible_principals => 'user_group') |
|
| 207 |
assert_equal 10, field.value_from_keyword('A Team', project)
|
|
| 208 | ||
| 209 |
field = IssueCustomField.new(:field_format => 'user') |
|
| 210 |
assert_nil field.value_from_keyword('A Team', project)
|
|
| 211 |
end |
|
| 112 | 212 |
end |
| test/unit/query_test.rb | ||
|---|---|---|
| 1301 | 1301 |
assert_equal issue1, result.first |
| 1302 | 1302 |
end |
| 1303 |
def test_user_custom_field_with_groups_should_be_filterable_on_users_and_groups |
|
| 1304 |
User.current = User.find(8) |
|
| 1305 |
cf = IssueCustomField.create!(:field_format => 'user', :possible_principals => 'user_group', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1]) |
|
| 1306 |
issue1 = Issue.generate!(:project_id => 5, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '10'})
|
|
| 1307 |
issue2 = Issue.generate!(:project_id => 5, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '8'})
|
|
| 1308 |
issue3 = Issue.generate!(:project_id => 5, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'})
|
|
| 1309 | ||
| 1310 |
query = IssueQuery.new(:name => '_', :project => Project.find(5)) |
|
| 1311 |
filter = query.available_filters["cf_#{cf.id}"]
|
|
| 1312 |
assert_not_nil filter |
|
| 1313 |
values = filter[:values].pluck(1) |
|
| 1314 |
assert_include 'me', values |
|
| 1315 |
assert_include '2', values |
|
| 1316 |
assert_include '10', values |
|
| 1317 | ||
| 1318 |
# "me" includes the groups of the current user |
|
| 1319 |
query.filters = {"cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
|
|
| 1320 |
assert_equal [issue1, issue2].map(&:id).sort, query.issues.map(&:id).sort |
|
| 1321 |
end |
|
| 1322 | ||
| 1303 | 1323 |
def test_filter_on_chained_user_custom_field |
| 1304 | 1324 |
user = User.find(2) |
| 1305 | 1325 |
User.current = user |
- « Previous
- 1
- 2
- 3
- Next »