summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/issue_query.rb38
-rw-r--r--test/unit/query_test.rb60
2 files changed, 98 insertions, 0 deletions
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb
index 9c78fd734..c59e8d35c 100644
--- a/app/models/issue_query.rb
+++ b/app/models/issue_query.rb
@@ -172,6 +172,18 @@ class IssueQuery < Query
:type => :list, :values => lambda {author_values}
)
add_available_filter(
+ "author.group",
+ :type => :list,
+ :values => lambda {Group.givable.visible.pluck(:name, :id).map {|name, id| [name, id.to_s]}},
+ :name => l(:label_attribute_of_author, :name => l(:label_group))
+ )
+ add_available_filter(
+ "author.role",
+ :type => :list,
+ :values => lambda {Role.givable.pluck(:name, :id).map {|name, id| [name, id.to_s]}},
+ :name => l(:label_attribute_of_author, :name => l(:field_role))
+ )
+ add_available_filter(
"assigned_to_id",
:type => :list_optional_with_history, :values => lambda {assigned_to_values}
)
@@ -608,6 +620,32 @@ class IssueQuery < Query
end
end
+ def sql_for_author_group_field(field, operator, value)
+ groups = value.empty? ? Group.givable : Group.where(:id => value).to_a
+
+ author_groups = groups.inject([]) do |user_ids, group|
+ user_ids + group.user_ids + [group.id]
+ end.uniq.compact.sort.collect(&:to_s)
+
+ '(' + sql_for_field("author_id", operator, author_groups, Issue.table_name, "author_id", false) + ')'
+ end
+
+ def sql_for_author_role_field(field, operator, value)
+ role_cond =
+ if value.any?
+ "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")"
+ else
+ "1=0"
+ end
+ sw = operator == "!" ? 'NOT' : ''
+ nl = operator == "!" ? "#{Issue.table_name}.author_id IS NULL OR" : ''
+ subquery =
+ "SELECT 1" +
+ " FROM #{Member.table_name} inner join #{MemberRole.table_name} on members.id = member_roles.member_id" +
+ " 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}"
+ "(#{nl} #{sw} EXISTS (#{subquery}))"
+ end
+
def sql_for_fixed_version_status_field(field, operator, value)
where = sql_for_field(field, operator, value, Version.table_name, "status")
version_id_scope = project ? project.shared_versions : Version.visible
diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb
index d26743cad..dd3b67928 100644
--- a/test/unit/query_test.rb
+++ b/test/unit/query_test.rb
@@ -2851,6 +2851,28 @@ class QueryTest < ActiveSupport::TestCase
assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous', '5'])
end
+ def test_available_filters_should_include_author_group_filter
+ query = IssueQuery.new
+ assert query.available_filters.key?("author.group")
+ assert_equal :list, query.available_filters["author.group"][:type]
+ assert query.available_filters["author.group"][:values].present?
+ assert_equal Group.givable.sort.map {|g| [g.name, g.id.to_s]},
+ query.available_filters["author.group"][:values].sort
+ end
+
+ def test_available_filters_should_include_author_role_filter
+ query = IssueQuery.new
+ assert query.available_filters.key?("author.role")
+ assert_equal :list, query.available_filters["author.role"][:type]
+
+ assert query.available_filters["author.role"][:values].include?(['Manager', '1'])
+ assert query.available_filters["author.role"][:values].include?(['Developer', '2'])
+ assert query.available_filters["author.role"][:values].include?(['Reporter', '3'])
+
+ assert_not query.available_filters["author.role"][:values].include?(['Non member', '4'])
+ assert_not query.available_filters["author.role"][:values].include?(['Anonymous', '5'])
+ end
+
def test_available_filters_should_include_custom_field_according_to_user_visibility
visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true)
hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1])
@@ -3021,6 +3043,44 @@ class QueryTest < ActiveSupport::TestCase
assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
end
+ def test_author_group_filter_should_return_issues_with_or_without_author_in_group
+ project = Project.generate!
+ author = User.generate!
+ author_group = Group.generate!
+ not_author_group = Group.generate!
+ author.groups << author_group
+ issues = Array.new(3) { Issue.generate!(:project => project, :author => author) }
+
+ query = IssueQuery.new(:name => '_', :project => project)
+ query.add_filter('author_group', '=', [author_group.id.to_s])
+ assert_equal 3, query.issues.count
+ assert_query_result issues, query
+
+ query = IssueQuery.new(:name => '_', :project => project)
+ query.add_filter('author_group', '!', [not_author_group.id.to_s])
+ assert_equal 3, query.issues.count
+ assert_query_result issues, query
+ end
+
+ def test_author_role_filter_should_return_issues_with_or_without_author_in_role
+ project = Project.generate!
+ author = User.generate!
+ manager_role = Role.find_by_name('Manager')
+ developer_role = Role.find_by_name('Developer')
+ User.add_to_project(author, project, manager_role)
+ issues = Array.new(3) { Issue.generate!(:project => project, :author => author) }
+
+ query = IssueQuery.new(:name => 'issues generated by manager', :project => project)
+ query.add_filter('author_role', '=', [manager_role.id.to_s])
+ assert_equal 3, query.issues.count
+ assert_query_result issues, query
+
+ query = IssueQuery.new(:name => 'issues does not generated by developer', :project => project)
+ query.add_filter('author_role', '!', [developer_role.id.to_s])
+ assert_equal 3, query.issues.count
+ assert_query_result issues, query
+ end
+
def test_query_column_should_accept_a_symbol_as_caption
set_language_if_valid 'en'
c = QueryColumn.new('foo', :caption => :general_text_Yes)