Feature #7867 » add-author-group-filtering.patch
app/helpers/queries_helper.rb | ||
---|---|---|
37 | 37 |
group = query.is_a?(IssueQuery) ? :label_relations : nil |
38 | 38 |
elsif %w(member_of_group assigned_to_role).include?(field) |
39 | 39 |
group = :field_assigned_to |
40 |
elsif %w(author_group author_role).include?(field) |
|
41 |
group = :field_author |
|
40 | 42 |
elsif field_options[:type] == :date_past || field_options[:type] == :date |
41 | 43 |
group = :label_date |
42 | 44 |
elsif %w(estimated_hours spent_time).include?(field) |
app/models/issue_query.rb | ||
---|---|---|
180 | 180 |
:type => :list_optional, |
181 | 181 |
:values => lambda {Role.givable.pluck(:name, :id).map {|name, id| [name, id.to_s]}} |
182 | 182 |
) |
183 |
add_available_filter( |
|
184 |
"author_group", |
|
185 |
:type => :list, |
|
186 |
:values => lambda {Group.givable.visible.pluck(:name, :id).map {|name, id| [name, id.to_s]}} |
|
187 |
) |
|
188 |
add_available_filter( |
|
189 |
"author_role", |
|
190 |
:type => :list, |
|
191 |
:values => lambda {Role.givable.pluck(:name, :id).map {|name, id| [name, id.to_s]}} |
|
192 |
) |
|
183 | 193 |
add_available_filter( |
184 | 194 |
"fixed_version_id", |
185 | 195 |
:type => :list_optional_with_history, :values => lambda {fixed_version_values} |
... | ... | |
592 | 602 |
end |
593 | 603 |
end |
594 | 604 | |
605 |
def sql_for_author_group_field(field, operator, value) |
|
606 |
groups = if value.empty? |
|
607 |
Group.givable |
|
608 |
else |
|
609 |
Group.where(:id => value).to_a |
|
610 |
end |
|
611 | ||
612 |
author_groups = groups.inject([]) do |user_ids, group| |
|
613 |
user_ids + group.user_ids + [group.id] |
|
614 |
end.uniq.compact.sort.collect(&:to_s) |
|
615 | ||
616 |
'(' + sql_for_field("author_id", operator, author_groups, Issue.table_name, "author_id", false) + ')' |
|
617 |
end |
|
618 | ||
619 |
def sql_for_author_role_field(field, operator, value) |
|
620 |
role_cond = |
|
621 |
if value.any? |
|
622 |
"#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")" |
|
623 |
else |
|
624 |
"1=0" |
|
625 |
end |
|
626 |
sw = operator == "!" ? 'NOT' : '' |
|
627 |
nl = operator == "!" ? "#{Issue.table_name}.author_id IS NULL OR" : '' |
|
628 |
subquery = |
|
629 |
"SELECT 1" + |
|
630 |
" FROM #{Member.table_name} inner join #{MemberRole.table_name} on members.id = member_roles.member_id" + |
|
631 |
" WHERE #{Issue.table_name}.project_id = #{Member.table_name}.project_id AND #{Member.table_name}.user_id = #{Issue.table_name}.author_id AND #{role_cond}" |
|
632 |
"(#{nl} #{sw} EXISTS (#{subquery}))" |
|
633 |
end |
|
634 | ||
595 | 635 |
def sql_for_fixed_version_status_field(field, operator, value) |
596 | 636 |
where = sql_for_field(field, operator, value, Version.table_name, "status") |
597 | 637 |
version_id_scope = project ? project.shared_versions : Version.visible |
config/locales/en.yml | ||
---|---|---|
376 | 376 |
field_parent_issue_subject: Parent task subject |
377 | 377 |
field_member_of_group: "Assignee's group" |
378 | 378 |
field_assigned_to_role: "Assignee's role" |
379 |
field_author_group: "Author's group" |
|
380 |
field_author_role: "Author's role" |
|
379 | 381 |
field_text: Text field |
380 | 382 |
field_visible: Visible |
381 | 383 |
field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text" |
config/locales/ja.yml | ||
---|---|---|
334 | 334 |
field_parent_issue: 親チケット |
335 | 335 |
field_member_of_group: 担当者のグループ |
336 | 336 |
field_assigned_to_role: 担当者のロール |
337 |
field_author_group: 作成者のグループ |
|
338 |
field_author_role: 作成者のロール |
|
337 | 339 |
field_text: テキスト |
338 | 340 |
field_visible: 表示 |
339 | 341 |
field_warn_on_leaving_unsaved: データを保存せずにページから移動するときに警告 |
test/helpers/queries_helper_test.rb | ||
---|---|---|
117 | 117 |
assert_select_in options, 'option[value=?]', "cf_#{i_cf.id}.cf_#{u_cf.id}", text: "User's Phone number" |
118 | 118 |
assert_select_in options, 'optgroup[label=?]', 'User', 1 |
119 | 119 |
end |
120 | ||
121 |
def test_filters_options_for_select_should_group_author_filters |
|
122 |
with_locale 'en' do |
|
123 |
options = filters_options_for_select(IssueQuery.new) |
|
124 |
assert_select_in options, 'optgroup[label=?]', "Author", 1 |
|
125 |
assert_select_in options, 'optgroup > option[value=author_group]', :text => "Author's group" |
|
126 |
assert_select_in options, 'optgroup > option[value=author_role]', :text => "Author's role" |
|
127 |
end |
|
128 |
end |
|
120 | 129 |
end |
test/unit/query_test.rb | ||
---|---|---|
2788 | 2788 |
assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous', '5']) |
2789 | 2789 |
end |
2790 | 2790 | |
2791 |
def test_available_filters_should_include_author_group_filter |
|
2792 |
query = IssueQuery.new |
|
2793 |
assert query.available_filters.key?("author_group") |
|
2794 |
assert_equal :list, query.available_filters["author_group"][:type] |
|
2795 |
assert query.available_filters["author_group"][:values].present? |
|
2796 |
assert_equal Group.givable.sort.map {|g| [g.name, g.id.to_s]}, |
|
2797 |
query.available_filters["author_group"][:values].sort |
|
2798 |
end |
|
2799 | ||
2800 |
def test_available_filters_should_include_author_role_filter |
|
2801 |
query = IssueQuery.new |
|
2802 |
assert query.available_filters.key?("author_role") |
|
2803 |
assert_equal :list, query.available_filters["author_role"][:type] |
|
2804 | ||
2805 |
assert query.available_filters["author_role"][:values].include?(['Manager', '1']) |
|
2806 |
assert query.available_filters["author_role"][:values].include?(['Developer', '2']) |
|
2807 |
assert query.available_filters["author_role"][:values].include?(['Reporter', '3']) |
|
2808 | ||
2809 |
assert ! query.available_filters["author_role"][:values].include?(['Non member', '4']) |
|
2810 |
assert ! query.available_filters["author_role"][:values].include?(['Anonymous', '5']) |
|
2811 |
end |
|
2812 | ||
2791 | 2813 |
def test_available_filters_should_include_custom_field_according_to_user_visibility |
2792 | 2814 |
visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true) |
2793 | 2815 |
hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1]) |
... | ... | |
2958 | 2980 |
assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query |
2959 | 2981 |
end |
2960 | 2982 | |
2983 |
def test_author_group_filter_should_return_issues_with_or_without_author_in_group |
|
2984 |
project = Project.generate! |
|
2985 |
author = User.generate! |
|
2986 |
author_group = Group.generate! |
|
2987 |
not_author_group = Group.generate! |
|
2988 |
author.groups << author_group |
|
2989 |
issues = 3.times.collect { Issue.generate!(:project => project, :author => author) } |
|
2990 | ||
2991 |
query = IssueQuery.new(:name => '_', :project => project) |
|
2992 |
query.add_filter('author_group', '=', [author_group.id.to_s]) |
|
2993 |
assert_equal 3, query.issues.count |
|
2994 |
assert_query_result issues, query |
|
2995 | ||
2996 |
query = IssueQuery.new(:name => '_', :project => project) |
|
2997 |
query.add_filter('author_group', '!', [not_author_group.id.to_s]) |
|
2998 |
assert_equal 3, query.issues.count |
|
2999 |
assert_query_result issues, query |
|
3000 |
end |
|
3001 | ||
3002 |
def test_author_role_filter_should_return_issues_with_or_without_author_in_role |
|
3003 |
project = Project.generate! |
|
3004 |
author = User.generate! |
|
3005 |
manager_role = Role.find_by_name('Manager') |
|
3006 |
developer_role = Role.find_by_name('Developer') |
|
3007 |
User.add_to_project(author, project, manager_role) |
|
3008 |
issues = 3.times.collect { Issue.generate!(:project => project, :author => author) } |
|
3009 | ||
3010 |
query = IssueQuery.new(:name => 'issues generated by manager', :project => project) |
|
3011 |
query.add_filter('author_role', '=', [manager_role.id.to_s]) |
|
3012 |
assert_equal 3, query.issues.count |
|
3013 |
assert_query_result issues, query |
|
3014 | ||
3015 |
query = IssueQuery.new(:name => 'issues does not generated by developer', :project => project) |
|
3016 |
query.add_filter('author_role', '!', [developer_role.id.to_s]) |
|
3017 |
assert_equal 3, query.issues.count |
|
3018 |
assert_query_result issues, query |
|
3019 |
end |
|
3020 | ||
2961 | 3021 |
def test_query_column_should_accept_a_symbol_as_caption |
2962 | 3022 |
set_language_if_valid 'en' |
2963 | 3023 |
c = QueryColumn.new('foo', :caption => :general_text_Yes) |