Added a "Member of Group" to the issues filter. #5869
This filter will check an issue's assigned to field for users in (or not in) specific groups. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4077 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
4c656fcffc
commit
109b42f482
|
@ -196,6 +196,9 @@ class Query < ActiveRecord::Base
|
||||||
@available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty?
|
@available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty?
|
||||||
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
|
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
|
||||||
|
|
||||||
|
group_values = Group.all.collect {|g| [g.name, g.id] }
|
||||||
|
@available_filters["member_of_group"] = { :type => :list_optional, :order => 6, :values => group_values } unless group_values.empty?
|
||||||
|
|
||||||
if User.current.logged?
|
if User.current.logged?
|
||||||
@available_filters["watcher_id"] = { :type => :list, :order => 15, :values => [["<< #{l(:label_me)} >>", "me"]] }
|
@available_filters["watcher_id"] = { :type => :list, :order => 15, :values => [["<< #{l(:label_me)} >>", "me"]] }
|
||||||
end
|
end
|
||||||
|
@ -432,6 +435,22 @@ class Query < ActiveRecord::Base
|
||||||
db_field = 'user_id'
|
db_field = 'user_id'
|
||||||
sql << "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND "
|
sql << "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND "
|
||||||
sql << sql_for_field(field, '=', v, db_table, db_field) + ')'
|
sql << sql_for_field(field, '=', v, db_table, db_field) + ')'
|
||||||
|
elsif field == "member_of_group" # named field
|
||||||
|
if operator == '*' # Any group
|
||||||
|
groups = Group.all
|
||||||
|
members_of_groups = groups.collect(&:user_ids).flatten.compact.collect(&:to_s)
|
||||||
|
operator = '=' # Override the operator since we want to find by assigned_to
|
||||||
|
elsif operator == "!*"
|
||||||
|
groups = Group.all
|
||||||
|
members_of_groups = groups.collect(&:user_ids).flatten.compact.collect(&:to_s)
|
||||||
|
operator = '!' # Override the operator since we want to find by assigned_to
|
||||||
|
else
|
||||||
|
groups = Group.find_all_by_id(v)
|
||||||
|
members_of_groups = groups.collect(&:user_ids).flatten.compact.collect(&:to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
sql << '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')'
|
||||||
|
|
||||||
else
|
else
|
||||||
# regular field
|
# regular field
|
||||||
db_table = Issue.table_name
|
db_table = Issue.table_name
|
||||||
|
|
|
@ -293,6 +293,7 @@ en:
|
||||||
field_group_by: Group results by
|
field_group_by: Group results by
|
||||||
field_sharing: Sharing
|
field_sharing: Sharing
|
||||||
field_parent_issue: Parent task
|
field_parent_issue: Parent task
|
||||||
|
field_member_of_group: Member of Group
|
||||||
|
|
||||||
setting_app_title: Application title
|
setting_app_title: Application title
|
||||||
setting_app_subtitle: Application subtitle
|
setting_app_subtitle: Application subtitle
|
||||||
|
|
|
@ -48,6 +48,16 @@ class QueryTest < ActiveSupport::TestCase
|
||||||
:conditions => query.statement
|
:conditions => query.statement
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assert_find_issues_with_query_is_successful(query)
|
||||||
|
assert_nothing_raised do
|
||||||
|
find_issues_with_query(query)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_query_statement_includes(query, condition)
|
||||||
|
assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}"
|
||||||
|
end
|
||||||
|
|
||||||
def test_query_should_allow_shared_versions_for_a_project_query
|
def test_query_should_allow_shared_versions_for_a_project_query
|
||||||
subproject_version = Version.find(4)
|
subproject_version = Version.find(4)
|
||||||
query = Query.new(:project => Project.find(1), :name => '_')
|
query = Query.new(:project => Project.find(1), :name => '_')
|
||||||
|
@ -362,11 +372,87 @@ class QueryTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
context "#available_filters" do
|
context "#available_filters" do
|
||||||
|
setup do
|
||||||
|
@query = Query.new(:name => "_")
|
||||||
|
end
|
||||||
|
|
||||||
should "include users of visible projects in cross-project view" do
|
should "include users of visible projects in cross-project view" do
|
||||||
query = Query.new(:name => "_")
|
users = @query.available_filters["assigned_to_id"]
|
||||||
users = query.available_filters["assigned_to_id"]
|
|
||||||
assert_not_nil users
|
assert_not_nil users
|
||||||
assert users[:values].map{|u|u[1]}.include?("3")
|
assert users[:values].map{|u|u[1]}.include?("3")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "'member_of_group' filter" do
|
||||||
|
should "be present" do
|
||||||
|
assert @query.available_filters.keys.include?("member_of_group")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "be an optional list" do
|
||||||
|
assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
|
||||||
|
end
|
||||||
|
|
||||||
|
should "have a list of the groups as values" do
|
||||||
|
Group.destroy_all # No fixtures
|
||||||
|
group1 = Group.generate!.reload
|
||||||
|
group2 = Group.generate!.reload
|
||||||
|
|
||||||
|
expected_group_list = [
|
||||||
|
[group1.name, group1.id],
|
||||||
|
[group2.name, group2.id]
|
||||||
|
]
|
||||||
|
assert_equal expected_group_list, @query.available_filters["member_of_group"][:values]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "#statement" do
|
||||||
|
context "with 'member_of_group' filter" do
|
||||||
|
setup do
|
||||||
|
Group.destroy_all # No fixtures
|
||||||
|
@user_in_group = User.generate!
|
||||||
|
@second_user_in_group = User.generate!
|
||||||
|
@user_in_group2 = User.generate!
|
||||||
|
@user_not_in_group = User.generate!
|
||||||
|
|
||||||
|
@group = Group.generate!.reload
|
||||||
|
@group.users << @user_in_group
|
||||||
|
@group.users << @second_user_in_group
|
||||||
|
|
||||||
|
@group2 = Group.generate!.reload
|
||||||
|
@group2.users << @user_in_group2
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
should "search assigned to for users in the group" do
|
||||||
|
@query = Query.new(:name => '_')
|
||||||
|
@query.add_filter('member_of_group', '=', [@group.id.to_s])
|
||||||
|
|
||||||
|
assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
|
||||||
|
assert_find_issues_with_query_is_successful @query
|
||||||
|
end
|
||||||
|
|
||||||
|
should "search not assigned to any group member (none)" do
|
||||||
|
@query = Query.new(:name => '_')
|
||||||
|
@query.add_filter('member_of_group', '!*', [''])
|
||||||
|
|
||||||
|
# Users not in a group
|
||||||
|
assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
|
||||||
|
assert_find_issues_with_query_is_successful @query
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
should "search assigned to any group member (all)" do
|
||||||
|
@query = Query.new(:name => '_')
|
||||||
|
@query.add_filter('member_of_group', '*', [''])
|
||||||
|
|
||||||
|
# Only users in a group
|
||||||
|
assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
|
||||||
|
assert_find_issues_with_query_is_successful @query
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue