@@ -153,6 +153,15 class IssueQuery < Query | |||
|
153 | 153 | :type => :list_optional, |
|
154 | 154 | :values => Version.sort_by_status(versions).collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s, l("version_status_#{s.status}")] } |
|
155 | 155 | |
|
156 | add_available_filter "fixed_version.due_date", | |
|
157 | :type => :date, | |
|
158 | :name => l(:label_attribute_of_fixed_version, :name => l(:field_effective_date)) | |
|
159 | ||
|
160 | add_available_filter "fixed_version.status", | |
|
161 | :type => :list, | |
|
162 | :name => l(:label_attribute_of_fixed_version, :name => l(:field_status)), | |
|
163 | :values => Version::VERSION_STATUSES.map{|t| [t, t] } | |
|
164 | ||
|
156 | 165 | add_available_filter "category_id", |
|
157 | 166 | :type => :list_optional, |
|
158 | 167 | :values => categories.collect{|s| [s.name, s.id.to_s] } |
@@ -417,6 +426,22 class IssueQuery < Query | |||
|
417 | 426 | end |
|
418 | 427 | end |
|
419 | 428 | |
|
429 | def sql_for_fixed_version_status_field(field, operator, value) | |
|
430 | where = sql_for_field(field, operator, value, Version.table_name, "status") | |
|
431 | version_ids = versions(:conditions => [where]).map(&:id) | |
|
432 | ||
|
433 | nl = operator == "!" ? "#{Issue.table_name}.fixed_version_id IS NULL OR" : '' | |
|
434 | "(#{nl} #{sql_for_field("fixed_version_id", "=", version_ids, Issue.table_name, "fixed_version_id")})" | |
|
435 | end | |
|
436 | ||
|
437 | def sql_for_fixed_version_due_date_field(field, operator, value) | |
|
438 | where = sql_for_field(field, operator, value, Version.table_name, "effective_date") | |
|
439 | version_ids = versions(:conditions => [where]).map(&:id) | |
|
440 | ||
|
441 | nl = operator == "!*" ? "#{Issue.table_name}.fixed_version_id IS NULL OR" : '' | |
|
442 | "(#{nl} #{sql_for_field("fixed_version_id", "=", version_ids, Issue.table_name, "fixed_version_id")})" | |
|
443 | end | |
|
444 | ||
|
420 | 445 | def sql_for_is_private_field(field, operator, value) |
|
421 | 446 | op = (operator == "=" ? 'IN' : 'NOT IN') |
|
422 | 447 | va = value.map {|v| v == '0' ? self.class.connection.quoted_false : self.class.connection.quoted_true}.uniq.join(',') |
@@ -819,6 +819,36 class QueryTest < ActiveSupport::TestCase | |||
|
819 | 819 | assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort |
|
820 | 820 | end |
|
821 | 821 | |
|
822 | def test_filter_on_fixed_version_due_date | |
|
823 | query = IssueQuery.new(:name => '_') | |
|
824 | filter_name = "fixed_version.due_date" | |
|
825 | assert_include filter_name, query.available_filters.keys | |
|
826 | query.filters = {filter_name => {:operator => '=', :values => [20.day.from_now.to_date.to_s(:db)]}} | |
|
827 | issues = find_issues_with_query(query) | |
|
828 | assert_equal [2], issues.map(&:fixed_version_id).uniq.sort | |
|
829 | assert_equal [2, 12], issues.map(&:id).sort | |
|
830 | ||
|
831 | query = IssueQuery.new(:name => '_') | |
|
832 | query.filters = {filter_name => {:operator => '>=', :values => [21.day.from_now.to_date.to_s(:db)]}} | |
|
833 | assert_equal 0, find_issues_with_query(query).size | |
|
834 | end | |
|
835 | ||
|
836 | def test_filter_on_fixed_version_status | |
|
837 | query = IssueQuery.new(:name => '_') | |
|
838 | filter_name = "fixed_version.status" | |
|
839 | assert_include filter_name, query.available_filters.keys | |
|
840 | query.filters = {filter_name => {:operator => '=', :values => ['closed']}} | |
|
841 | issues = find_issues_with_query(query) | |
|
842 | ||
|
843 | assert_equal [1], issues.map(&:fixed_version_id).sort | |
|
844 | assert_equal [11], issues.map(&:id).sort | |
|
845 | ||
|
846 | # "is not" operator should include issues without target version | |
|
847 | query = IssueQuery.new(:name => '_') | |
|
848 | query.filters = {filter_name => {:operator => '!', :values => ['open', 'closed', 'locked']}, "project_id" => {:operator => '=', :values => [1]}} | |
|
849 | assert_equal [1, 3, 7, 8], find_issues_with_query(query).map(&:id).uniq.sort | |
|
850 | end | |
|
851 | ||
|
822 | 852 | def test_filter_on_relations_with_a_specific_issue |
|
823 | 853 | IssueRelation.delete_all |
|
824 | 854 | IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) |
@@ -951,7 +981,7 class QueryTest < ActiveSupport::TestCase | |||
|
951 | 981 | def test_filter_on_parent |
|
952 | 982 | Issue.delete_all |
|
953 | 983 | parent = Issue.generate_with_descendants! |
|
954 | ||
|
984 | ||
|
955 | 985 | |
|
956 | 986 | query = IssueQuery.new(:name => '_') |
|
957 | 987 | query.filters = {"parent_id" => {:operator => '=', :values => [parent.id.to_s]}} |
@@ -981,7 +1011,7 class QueryTest < ActiveSupport::TestCase | |||
|
981 | 1011 | parent = Issue.generate_with_descendants! |
|
982 | 1012 | child, leaf = parent.children.sort_by(&:id) |
|
983 | 1013 | grandchild = child.children.first |
|
984 | ||
|
1014 | ||
|
985 | 1015 | |
|
986 | 1016 | query = IssueQuery.new(:name => '_') |
|
987 | 1017 | query.filters = {"child_id" => {:operator => '=', :values => [grandchild.id.to_s]}} |
General Comments 0
You need to be logged in to leave comments.
Login now