Mercurial > hg > soundsoftware-site
comparison test/unit/query_test.rb @ 909:cbb26bc654de redmine-1.3
Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author | Chris Cannam |
---|---|
date | Fri, 24 Feb 2012 19:09:32 +0000 |
parents | cbce1fd3b1b7 |
children | 433d4f72a19b |
comparison
equal
deleted
inserted
replaced
908:c6c2cbd0afee | 909:cbb26bc654de |
---|---|
3 # | 3 # |
4 # This program is free software; you can redistribute it and/or | 4 # This program is free software; you can redistribute it and/or |
5 # modify it under the terms of the GNU General Public License | 5 # modify it under the terms of the GNU General Public License |
6 # as published by the Free Software Foundation; either version 2 | 6 # as published by the Free Software Foundation; either version 2 |
7 # of the License, or (at your option) any later version. | 7 # of the License, or (at your option) any later version. |
8 # | 8 # |
9 # This program is distributed in the hope that it will be useful, | 9 # This program is distributed in the hope that it will be useful, |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 # GNU General Public License for more details. | 12 # GNU General Public License for more details. |
13 # | 13 # |
14 # You should have received a copy of the GNU General Public License | 14 # You should have received a copy of the GNU General Public License |
15 # along with this program; if not, write to the Free Software | 15 # along with this program; if not, write to the Free Software |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 17 |
18 require File.expand_path('../../test_helper', __FILE__) | 18 require File.expand_path('../../test_helper', __FILE__) |
19 | 19 |
20 class QueryTest < ActiveSupport::TestCase | 20 class QueryTest < ActiveSupport::TestCase |
21 fixtures :projects, :enabled_modules, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :watchers, :custom_fields, :custom_values, :versions, :queries | 21 fixtures :projects, :enabled_modules, :users, :members, |
22 :member_roles, :roles, :trackers, :issue_statuses, | |
23 :issue_categories, :enumerations, :issues, | |
24 :watchers, :custom_fields, :custom_values, :versions, | |
25 :queries, | |
26 :projects_trackers | |
22 | 27 |
23 def test_custom_fields_for_all_projects_should_be_available_in_global_queries | 28 def test_custom_fields_for_all_projects_should_be_available_in_global_queries |
24 query = Query.new(:project => nil, :name => '_') | 29 query = Query.new(:project => nil, :name => '_') |
25 assert query.available_filters.has_key?('cf_1') | 30 assert query.available_filters.has_key?('cf_1') |
26 assert !query.available_filters.has_key?('cf_3') | 31 assert !query.available_filters.has_key?('cf_3') |
27 end | 32 end |
28 | 33 |
29 def test_system_shared_versions_should_be_available_in_global_queries | 34 def test_system_shared_versions_should_be_available_in_global_queries |
30 Version.find(2).update_attribute :sharing, 'system' | 35 Version.find(2).update_attribute :sharing, 'system' |
31 query = Query.new(:project => nil, :name => '_') | 36 query = Query.new(:project => nil, :name => '_') |
32 assert query.available_filters.has_key?('fixed_version_id') | 37 assert query.available_filters.has_key?('fixed_version_id') |
33 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'} | 38 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'} |
34 end | 39 end |
35 | 40 |
36 def test_project_filter_in_global_queries | 41 def test_project_filter_in_global_queries |
37 query = Query.new(:project => nil, :name => '_') | 42 query = Query.new(:project => nil, :name => '_') |
38 project_filter = query.available_filters["project_id"] | 43 project_filter = query.available_filters["project_id"] |
39 assert_not_nil project_filter | 44 assert_not_nil project_filter |
40 project_ids = project_filter[:values].map{|p| p[1]} | 45 project_ids = project_filter[:values].map{|p| p[1]} |
41 assert project_ids.include?("1") #public project | 46 assert project_ids.include?("1") #public project |
42 assert !project_ids.include?("2") #private project user cannot see | 47 assert !project_ids.include?("2") #private project user cannot see |
43 end | 48 end |
44 | 49 |
45 def find_issues_with_query(query) | 50 def find_issues_with_query(query) |
46 Issue.find :all, | 51 Issue.find :all, |
47 :include => [ :assigned_to, :status, :tracker, :project, :priority ], | 52 :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
48 :conditions => query.statement | 53 :conditions => query.statement |
49 end | 54 end |
50 | 55 |
51 def assert_find_issues_with_query_is_successful(query) | 56 def assert_find_issues_with_query_is_successful(query) |
52 assert_nothing_raised do | 57 assert_nothing_raised do |
55 end | 60 end |
56 | 61 |
57 def assert_query_statement_includes(query, condition) | 62 def assert_query_statement_includes(query, condition) |
58 assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}" | 63 assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}" |
59 end | 64 end |
65 | |
66 def assert_query_result(expected, query) | |
67 assert_nothing_raised do | |
68 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort | |
69 assert_equal expected.size, query.issue_count | |
70 end | |
71 end | |
60 | 72 |
61 def test_query_should_allow_shared_versions_for_a_project_query | 73 def test_query_should_allow_shared_versions_for_a_project_query |
62 subproject_version = Version.find(4) | 74 subproject_version = Version.find(4) |
63 query = Query.new(:project => Project.find(1), :name => '_') | 75 query = Query.new(:project => Project.find(1), :name => '_') |
64 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s]) | 76 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s]) |
65 | 77 |
66 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')") | 78 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')") |
67 end | 79 end |
68 | 80 |
69 def test_query_with_multiple_custom_fields | 81 def test_query_with_multiple_custom_fields |
70 query = Query.find(1) | 82 query = Query.find(1) |
71 assert query.valid? | 83 assert query.valid? |
72 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')") | 84 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')") |
73 issues = find_issues_with_query(query) | 85 issues = find_issues_with_query(query) |
74 assert_equal 1, issues.length | 86 assert_equal 1, issues.length |
75 assert_equal Issue.find(3), issues.first | 87 assert_equal Issue.find(3), issues.first |
76 end | 88 end |
77 | 89 |
78 def test_operator_none | 90 def test_operator_none |
79 query = Query.new(:project => Project.find(1), :name => '_') | 91 query = Query.new(:project => Project.find(1), :name => '_') |
80 query.add_filter('fixed_version_id', '!*', ['']) | 92 query.add_filter('fixed_version_id', '!*', ['']) |
81 query.add_filter('cf_1', '!*', ['']) | 93 query.add_filter('cf_1', '!*', ['']) |
82 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL") | 94 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL") |
83 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''") | 95 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''") |
84 find_issues_with_query(query) | 96 find_issues_with_query(query) |
85 end | 97 end |
86 | 98 |
87 def test_operator_none_for_integer | 99 def test_operator_none_for_integer |
88 query = Query.new(:project => Project.find(1), :name => '_') | 100 query = Query.new(:project => Project.find(1), :name => '_') |
89 query.add_filter('estimated_hours', '!*', ['']) | 101 query.add_filter('estimated_hours', '!*', ['']) |
90 issues = find_issues_with_query(query) | 102 issues = find_issues_with_query(query) |
91 assert !issues.empty? | 103 assert !issues.empty? |
92 assert issues.all? {|i| !i.estimated_hours} | 104 assert issues.all? {|i| !i.estimated_hours} |
105 end | |
106 | |
107 def test_operator_none_for_date | |
108 query = Query.new(:project => Project.find(1), :name => '_') | |
109 query.add_filter('start_date', '!*', ['']) | |
110 issues = find_issues_with_query(query) | |
111 assert !issues.empty? | |
112 assert issues.all? {|i| i.start_date.nil?} | |
93 end | 113 end |
94 | 114 |
95 def test_operator_all | 115 def test_operator_all |
96 query = Query.new(:project => Project.find(1), :name => '_') | 116 query = Query.new(:project => Project.find(1), :name => '_') |
97 query.add_filter('fixed_version_id', '*', ['']) | 117 query.add_filter('fixed_version_id', '*', ['']) |
98 query.add_filter('cf_1', '*', ['']) | 118 query.add_filter('cf_1', '*', ['']) |
99 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL") | 119 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL") |
100 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''") | 120 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''") |
101 find_issues_with_query(query) | 121 find_issues_with_query(query) |
102 end | 122 end |
103 | 123 |
124 def test_operator_all_for_date | |
125 query = Query.new(:project => Project.find(1), :name => '_') | |
126 query.add_filter('start_date', '*', ['']) | |
127 issues = find_issues_with_query(query) | |
128 assert !issues.empty? | |
129 assert issues.all? {|i| i.start_date.present?} | |
130 end | |
131 | |
132 def test_numeric_filter_should_not_accept_non_numeric_values | |
133 query = Query.new(:name => '_') | |
134 query.add_filter('estimated_hours', '=', ['a']) | |
135 | |
136 assert query.has_filter?('estimated_hours') | |
137 assert !query.valid? | |
138 end | |
139 | |
140 def test_operator_is_on_float | |
141 Issue.update_all("estimated_hours = 171.2", "id=2") | |
142 | |
143 query = Query.new(:name => '_') | |
144 query.add_filter('estimated_hours', '=', ['171.20']) | |
145 issues = find_issues_with_query(query) | |
146 assert_equal 1, issues.size | |
147 assert_equal 2, issues.first.id | |
148 end | |
149 | |
104 def test_operator_greater_than | 150 def test_operator_greater_than |
105 query = Query.new(:project => Project.find(1), :name => '_') | 151 query = Query.new(:project => Project.find(1), :name => '_') |
106 query.add_filter('done_ratio', '>=', ['40']) | 152 query.add_filter('done_ratio', '>=', ['40']) |
107 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40") | 153 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0") |
154 find_issues_with_query(query) | |
155 end | |
156 | |
157 def test_operator_greater_than_a_float | |
158 query = Query.new(:project => Project.find(1), :name => '_') | |
159 query.add_filter('estimated_hours', '>=', ['40.5']) | |
160 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5") | |
161 find_issues_with_query(query) | |
162 end | |
163 | |
164 def test_operator_greater_than_on_custom_field | |
165 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true) | |
166 query = Query.new(:project => Project.find(1), :name => '_') | |
167 query.add_filter("cf_#{f.id}", '>=', ['40']) | |
168 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) >= 40.0") | |
169 find_issues_with_query(query) | |
170 end | |
171 | |
172 def test_operator_lesser_than | |
173 query = Query.new(:project => Project.find(1), :name => '_') | |
174 query.add_filter('done_ratio', '<=', ['30']) | |
175 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0") | |
176 find_issues_with_query(query) | |
177 end | |
178 | |
179 def test_operator_lesser_than_on_custom_field | |
180 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true) | |
181 query = Query.new(:project => Project.find(1), :name => '_') | |
182 query.add_filter("cf_#{f.id}", '<=', ['30']) | |
183 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0") | |
184 find_issues_with_query(query) | |
185 end | |
186 | |
187 def test_operator_between | |
188 query = Query.new(:project => Project.find(1), :name => '_') | |
189 query.add_filter('done_ratio', '><', ['30', '40']) | |
190 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement | |
191 find_issues_with_query(query) | |
192 end | |
193 | |
194 def test_operator_between_on_custom_field | |
195 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true) | |
196 query = Query.new(:project => Project.find(1), :name => '_') | |
197 query.add_filter("cf_#{f.id}", '><', ['30', '40']) | |
198 assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement | |
199 find_issues_with_query(query) | |
200 end | |
201 | |
202 def test_date_filter_should_not_accept_non_date_values | |
203 query = Query.new(:name => '_') | |
204 query.add_filter('created_on', '=', ['a']) | |
205 | |
206 assert query.has_filter?('created_on') | |
207 assert !query.valid? | |
208 end | |
209 | |
210 def test_date_filter_should_not_accept_invalid_date_values | |
211 query = Query.new(:name => '_') | |
212 query.add_filter('created_on', '=', ['2011-01-34']) | |
213 | |
214 assert query.has_filter?('created_on') | |
215 assert !query.valid? | |
216 end | |
217 | |
218 def test_relative_date_filter_should_not_accept_non_integer_values | |
219 query = Query.new(:name => '_') | |
220 query.add_filter('created_on', '>t-', ['a']) | |
221 | |
222 assert query.has_filter?('created_on') | |
223 assert !query.valid? | |
224 end | |
225 | |
226 def test_operator_date_equals | |
227 query = Query.new(:name => '_') | |
228 query.add_filter('due_date', '=', ['2011-07-10']) | |
229 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement | |
230 find_issues_with_query(query) | |
231 end | |
232 | |
233 def test_operator_date_lesser_than | |
234 query = Query.new(:name => '_') | |
235 query.add_filter('due_date', '<=', ['2011-07-10']) | |
236 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement | |
237 find_issues_with_query(query) | |
238 end | |
239 | |
240 def test_operator_date_greater_than | |
241 query = Query.new(:name => '_') | |
242 query.add_filter('due_date', '>=', ['2011-07-10']) | |
243 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement | |
244 find_issues_with_query(query) | |
245 end | |
246 | |
247 def test_operator_date_between | |
248 query = Query.new(:name => '_') | |
249 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10']) | |
250 assert_match /issues\.due_date > '2011-06-22 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement | |
108 find_issues_with_query(query) | 251 find_issues_with_query(query) |
109 end | 252 end |
110 | 253 |
111 def test_operator_in_more_than | 254 def test_operator_in_more_than |
112 Issue.find(7).update_attribute(:due_date, (Date.today + 15)) | 255 Issue.find(7).update_attribute(:due_date, (Date.today + 15)) |
122 query.add_filter('due_date', '<t+', ['15']) | 265 query.add_filter('due_date', '<t+', ['15']) |
123 issues = find_issues_with_query(query) | 266 issues = find_issues_with_query(query) |
124 assert !issues.empty? | 267 assert !issues.empty? |
125 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))} | 268 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))} |
126 end | 269 end |
127 | 270 |
128 def test_operator_less_than_ago | 271 def test_operator_less_than_ago |
129 Issue.find(7).update_attribute(:due_date, (Date.today - 3)) | 272 Issue.find(7).update_attribute(:due_date, (Date.today - 3)) |
130 query = Query.new(:project => Project.find(1), :name => '_') | 273 query = Query.new(:project => Project.find(1), :name => '_') |
131 query.add_filter('due_date', '>t-', ['3']) | 274 query.add_filter('due_date', '>t-', ['3']) |
132 issues = find_issues_with_query(query) | 275 issues = find_issues_with_query(query) |
133 assert !issues.empty? | 276 assert !issues.empty? |
134 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)} | 277 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)} |
135 end | 278 end |
136 | 279 |
137 def test_operator_more_than_ago | 280 def test_operator_more_than_ago |
138 Issue.find(7).update_attribute(:due_date, (Date.today - 10)) | 281 Issue.find(7).update_attribute(:due_date, (Date.today - 10)) |
139 query = Query.new(:project => Project.find(1), :name => '_') | 282 query = Query.new(:project => Project.find(1), :name => '_') |
140 query.add_filter('due_date', '<t-', ['10']) | 283 query.add_filter('due_date', '<t-', ['10']) |
141 assert query.statement.include?("#{Issue.table_name}.due_date <=") | 284 assert query.statement.include?("#{Issue.table_name}.due_date <=") |
188 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'") | 331 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'") |
189 result = find_issues_with_query(query) | 332 result = find_issues_with_query(query) |
190 assert result.empty? | 333 assert result.empty? |
191 result.each {|issue| assert issue.subject.downcase.include?('unable') } | 334 result.each {|issue| assert issue.subject.downcase.include?('unable') } |
192 end | 335 end |
193 | 336 |
194 def test_range_for_this_week_with_week_starting_on_monday | 337 def test_range_for_this_week_with_week_starting_on_monday |
195 I18n.locale = :fr | 338 I18n.locale = :fr |
196 assert_equal '1', I18n.t(:general_first_day_of_week) | 339 assert_equal '1', I18n.t(:general_first_day_of_week) |
197 | 340 |
198 Date.stubs(:today).returns(Date.parse('2011-04-29')) | 341 Date.stubs(:today).returns(Date.parse('2011-04-29')) |
199 | 342 |
200 query = Query.new(:project => Project.find(1), :name => '_') | 343 query = Query.new(:project => Project.find(1), :name => '_') |
201 query.add_filter('due_date', 'w', ['']) | 344 query.add_filter('due_date', 'w', ['']) |
202 assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}" | 345 assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}" |
203 I18n.locale = :en | 346 I18n.locale = :en |
204 end | 347 end |
205 | 348 |
206 def test_range_for_this_week_with_week_starting_on_sunday | 349 def test_range_for_this_week_with_week_starting_on_sunday |
207 I18n.locale = :en | 350 I18n.locale = :en |
208 assert_equal '7', I18n.t(:general_first_day_of_week) | 351 assert_equal '7', I18n.t(:general_first_day_of_week) |
209 | 352 |
210 Date.stubs(:today).returns(Date.parse('2011-04-29')) | 353 Date.stubs(:today).returns(Date.parse('2011-04-29')) |
211 | 354 |
212 query = Query.new(:project => Project.find(1), :name => '_') | 355 query = Query.new(:project => Project.find(1), :name => '_') |
213 query.add_filter('due_date', 'w', ['']) | 356 query.add_filter('due_date', 'w', ['']) |
214 assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}" | 357 assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}" |
215 end | 358 end |
216 | 359 |
217 def test_operator_does_not_contains | 360 def test_operator_does_not_contains |
218 query = Query.new(:project => Project.find(1), :name => '_') | 361 query = Query.new(:project => Project.find(1), :name => '_') |
219 query.add_filter('subject', '!~', ['uNable']) | 362 query.add_filter('subject', '!~', ['uNable']) |
220 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'") | 363 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'") |
221 find_issues_with_query(query) | 364 find_issues_with_query(query) |
222 end | 365 end |
223 | 366 |
367 def test_filter_assigned_to_me | |
368 user = User.find(2) | |
369 group = Group.find(10) | |
370 User.current = user | |
371 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user) | |
372 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group) | |
373 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11)) | |
374 group.users << user | |
375 | |
376 query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}}) | |
377 result = query.issues | |
378 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id) | |
379 | |
380 assert result.include?(i1) | |
381 assert result.include?(i2) | |
382 assert !result.include?(i3) | |
383 end | |
384 | |
224 def test_filter_watched_issues | 385 def test_filter_watched_issues |
225 User.current = User.find(1) | 386 User.current = User.find(1) |
226 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}}) | 387 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}}) |
227 result = find_issues_with_query(query) | 388 result = find_issues_with_query(query) |
228 assert_not_nil result | 389 assert_not_nil result |
229 assert !result.empty? | 390 assert !result.empty? |
230 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id) | 391 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id) |
231 User.current = nil | 392 User.current = nil |
232 end | 393 end |
233 | 394 |
234 def test_filter_unwatched_issues | 395 def test_filter_unwatched_issues |
235 User.current = User.find(1) | 396 User.current = User.find(1) |
236 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}}) | 397 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}}) |
237 result = find_issues_with_query(query) | 398 result = find_issues_with_query(query) |
238 assert_not_nil result | 399 assert_not_nil result |
239 assert !result.empty? | 400 assert !result.empty? |
240 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size) | 401 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size) |
241 User.current = nil | 402 User.current = nil |
242 end | 403 end |
243 | 404 |
244 def test_statement_should_be_nil_with_no_filters | 405 def test_statement_should_be_nil_with_no_filters |
245 q = Query.new(:name => '_') | 406 q = Query.new(:name => '_') |
246 q.filters = {} | 407 q.filters = {} |
247 | 408 |
248 assert q.valid? | 409 assert q.valid? |
249 assert_nil q.statement | 410 assert_nil q.statement |
250 end | 411 end |
251 | 412 |
252 def test_default_columns | 413 def test_default_columns |
253 q = Query.new | 414 q = Query.new |
254 assert !q.columns.empty? | 415 assert !q.columns.empty? |
255 end | 416 end |
256 | 417 |
257 def test_set_column_names | 418 def test_set_column_names |
258 q = Query.new | 419 q = Query.new |
259 q.column_names = ['tracker', :subject, '', 'unknonw_column'] | 420 q.column_names = ['tracker', :subject, '', 'unknonw_column'] |
260 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name} | 421 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name} |
261 c = q.columns.first | 422 c = q.columns.first |
262 assert q.has_column?(c) | 423 assert q.has_column?(c) |
263 end | 424 end |
264 | 425 |
265 def test_groupable_columns_should_include_custom_fields | 426 def test_groupable_columns_should_include_custom_fields |
266 q = Query.new | 427 q = Query.new |
267 assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn} | 428 assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn} |
268 end | 429 end |
269 | 430 |
273 assert_not_nil q.group_by_column | 434 assert_not_nil q.group_by_column |
274 assert_equal :status, q.group_by_column.name | 435 assert_equal :status, q.group_by_column.name |
275 assert_not_nil q.group_by_statement | 436 assert_not_nil q.group_by_statement |
276 assert_equal 'status', q.group_by_statement | 437 assert_equal 'status', q.group_by_statement |
277 end | 438 end |
278 | 439 |
279 def test_grouped_with_invalid_column | 440 def test_grouped_with_invalid_column |
280 q = Query.new(:group_by => 'foo') | 441 q = Query.new(:group_by => 'foo') |
281 assert !q.grouped? | 442 assert !q.grouped? |
282 assert_nil q.group_by_column | 443 assert_nil q.group_by_column |
283 assert_nil q.group_by_statement | 444 assert_nil q.group_by_statement |
284 end | 445 end |
285 | 446 |
447 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting | |
448 with_settings :user_format => 'lastname_coma_firstname' do | |
449 q = Query.new | |
450 assert q.sortable_columns.has_key?('assigned_to') | |
451 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to'] | |
452 end | |
453 end | |
454 | |
455 def test_sortable_columns_should_sort_authors_according_to_user_format_setting | |
456 with_settings :user_format => 'lastname_coma_firstname' do | |
457 q = Query.new | |
458 assert q.sortable_columns.has_key?('author') | |
459 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author'] | |
460 end | |
461 end | |
462 | |
286 def test_default_sort | 463 def test_default_sort |
287 q = Query.new | 464 q = Query.new |
288 assert_equal [], q.sort_criteria | 465 assert_equal [], q.sort_criteria |
289 end | 466 end |
290 | 467 |
291 def test_set_sort_criteria_with_hash | 468 def test_set_sort_criteria_with_hash |
292 q = Query.new | 469 q = Query.new |
293 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']} | 470 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']} |
294 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria | 471 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria |
295 end | 472 end |
296 | 473 |
297 def test_set_sort_criteria_with_array | 474 def test_set_sort_criteria_with_array |
298 q = Query.new | 475 q = Query.new |
299 q.sort_criteria = [['priority', 'desc'], 'tracker'] | 476 q.sort_criteria = [['priority', 'desc'], 'tracker'] |
300 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria | 477 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria |
301 end | 478 end |
302 | 479 |
303 def test_create_query_with_sort | 480 def test_create_query_with_sort |
304 q = Query.new(:name => 'Sorted') | 481 q = Query.new(:name => 'Sorted') |
305 q.sort_criteria = [['priority', 'desc'], 'tracker'] | 482 q.sort_criteria = [['priority', 'desc'], 'tracker'] |
306 assert q.save | 483 assert q.save |
307 q.reload | 484 q.reload |
308 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria | 485 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria |
309 end | 486 end |
310 | 487 |
311 def test_sort_by_string_custom_field_asc | 488 def test_sort_by_string_custom_field_asc |
312 q = Query.new | 489 q = Query.new |
313 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } | 490 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } |
314 assert c | 491 assert c |
315 assert c.sortable | 492 assert c.sortable |
316 issues = Issue.find :all, | 493 issues = Issue.find :all, |
317 :include => [ :assigned_to, :status, :tracker, :project, :priority ], | 494 :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
318 :conditions => q.statement, | 495 :conditions => q.statement, |
319 :order => "#{c.sortable} ASC" | 496 :order => "#{c.sortable} ASC" |
320 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} | 497 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} |
321 assert !values.empty? | 498 assert !values.empty? |
322 assert_equal values.sort, values | 499 assert_equal values.sort, values |
323 end | 500 end |
324 | 501 |
325 def test_sort_by_string_custom_field_desc | 502 def test_sort_by_string_custom_field_desc |
326 q = Query.new | 503 q = Query.new |
327 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } | 504 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } |
328 assert c | 505 assert c |
329 assert c.sortable | 506 assert c.sortable |
330 issues = Issue.find :all, | 507 issues = Issue.find :all, |
331 :include => [ :assigned_to, :status, :tracker, :project, :priority ], | 508 :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
332 :conditions => q.statement, | 509 :conditions => q.statement, |
333 :order => "#{c.sortable} DESC" | 510 :order => "#{c.sortable} DESC" |
334 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} | 511 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} |
335 assert !values.empty? | 512 assert !values.empty? |
336 assert_equal values.sort.reverse, values | 513 assert_equal values.sort.reverse, values |
337 end | 514 end |
338 | 515 |
339 def test_sort_by_float_custom_field_asc | 516 def test_sort_by_float_custom_field_asc |
340 q = Query.new | 517 q = Query.new |
341 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' } | 518 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' } |
342 assert c | 519 assert c |
343 assert c.sortable | 520 assert c.sortable |
344 issues = Issue.find :all, | 521 issues = Issue.find :all, |
345 :include => [ :assigned_to, :status, :tracker, :project, :priority ], | 522 :include => [ :assigned_to, :status, :tracker, :project, :priority ], |
346 :conditions => q.statement, | 523 :conditions => q.statement, |
347 :order => "#{c.sortable} ASC" | 524 :order => "#{c.sortable} ASC" |
348 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact | 525 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact |
349 assert !values.empty? | 526 assert !values.empty? |
350 assert_equal values.sort, values | 527 assert_equal values.sort, values |
351 end | 528 end |
352 | 529 |
353 def test_invalid_query_should_raise_query_statement_invalid_error | 530 def test_invalid_query_should_raise_query_statement_invalid_error |
354 q = Query.new | 531 q = Query.new |
355 assert_raise Query::StatementInvalid do | 532 assert_raise Query::StatementInvalid do |
356 q.issues(:conditions => "foo = 1") | 533 q.issues(:conditions => "foo = 1") |
357 end | 534 end |
358 end | 535 end |
359 | 536 |
537 def test_issue_count | |
538 q = Query.new(:name => '_') | |
539 issue_count = q.issue_count | |
540 assert_equal q.issues.size, issue_count | |
541 end | |
542 | |
543 def test_issue_count_with_archived_issues | |
544 p = Project.generate!( :status => Project::STATUS_ARCHIVED ) | |
545 i = Issue.generate!( :project => p, :tracker => p.trackers.first ) | |
546 assert !i.visible? | |
547 | |
548 test_issue_count | |
549 end | |
550 | |
360 def test_issue_count_by_association_group | 551 def test_issue_count_by_association_group |
361 q = Query.new(:name => '_', :group_by => 'assigned_to') | 552 q = Query.new(:name => '_', :group_by => 'assigned_to') |
362 count_by_group = q.issue_count_by_group | 553 count_by_group = q.issue_count_by_group |
363 assert_kind_of Hash, count_by_group | 554 assert_kind_of Hash, count_by_group |
364 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort | 555 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort |
372 assert_kind_of Hash, count_by_group | 563 assert_kind_of Hash, count_by_group |
373 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort | 564 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort |
374 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq | 565 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq |
375 assert count_by_group.has_key?('MySQL') | 566 assert count_by_group.has_key?('MySQL') |
376 end | 567 end |
377 | 568 |
378 def test_issue_count_by_date_custom_field_group | 569 def test_issue_count_by_date_custom_field_group |
379 q = Query.new(:name => '_', :group_by => 'cf_8') | 570 q = Query.new(:name => '_', :group_by => 'cf_8') |
380 count_by_group = q.issue_count_by_group | 571 count_by_group = q.issue_count_by_group |
381 assert_kind_of Hash, count_by_group | 572 assert_kind_of Hash, count_by_group |
382 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort | 573 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort |
383 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq | 574 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq |
384 end | 575 end |
385 | 576 |
386 def test_label_for | 577 def test_label_for |
387 q = Query.new | 578 q = Query.new |
388 assert_equal 'assigned_to', q.label_for('assigned_to_id') | 579 assert_equal 'assigned_to', q.label_for('assigned_to_id') |
389 end | 580 end |
390 | 581 |
391 def test_editable_by | 582 def test_editable_by |
392 admin = User.find(1) | 583 admin = User.find(1) |
393 manager = User.find(2) | 584 manager = User.find(2) |
394 developer = User.find(3) | 585 developer = User.find(3) |
395 | 586 |
396 # Public query on project 1 | 587 # Public query on project 1 |
397 q = Query.find(1) | 588 q = Query.find(1) |
398 assert q.editable_by?(admin) | 589 assert q.editable_by?(admin) |
399 assert q.editable_by?(manager) | 590 assert q.editable_by?(manager) |
400 assert !q.editable_by?(developer) | 591 assert !q.editable_by?(developer) |
416 assert q.editable_by?(admin) | 607 assert q.editable_by?(admin) |
417 assert !q.editable_by?(manager) | 608 assert !q.editable_by?(manager) |
418 assert !q.editable_by?(developer) | 609 assert !q.editable_by?(developer) |
419 end | 610 end |
420 | 611 |
612 def test_visible_scope | |
613 query_ids = Query.visible(User.anonymous).map(&:id) | |
614 | |
615 assert query_ids.include?(1), 'public query on public project was not visible' | |
616 assert query_ids.include?(4), 'public query for all projects was not visible' | |
617 assert !query_ids.include?(2), 'private query on public project was visible' | |
618 assert !query_ids.include?(3), 'private query for all projects was visible' | |
619 assert !query_ids.include?(7), 'public query on private project was visible' | |
620 end | |
621 | |
421 context "#available_filters" do | 622 context "#available_filters" do |
422 setup do | 623 setup do |
423 @query = Query.new(:name => "_") | 624 @query = Query.new(:name => "_") |
424 end | 625 end |
425 | 626 |
426 should "include users of visible projects in cross-project view" do | 627 should "include users of visible projects in cross-project view" do |
427 users = @query.available_filters["assigned_to_id"] | 628 users = @query.available_filters["assigned_to_id"] |
428 assert_not_nil users | 629 assert_not_nil users |
429 assert users[:values].map{|u|u[1]}.include?("3") | 630 assert users[:values].map{|u|u[1]}.include?("3") |
430 end | 631 end |
437 | 638 |
438 context "'member_of_group' filter" do | 639 context "'member_of_group' filter" do |
439 should "be present" do | 640 should "be present" do |
440 assert @query.available_filters.keys.include?("member_of_group") | 641 assert @query.available_filters.keys.include?("member_of_group") |
441 end | 642 end |
442 | 643 |
443 should "be an optional list" do | 644 should "be an optional list" do |
444 assert_equal :list_optional, @query.available_filters["member_of_group"][:type] | 645 assert_equal :list_optional, @query.available_filters["member_of_group"][:type] |
445 end | 646 end |
446 | 647 |
447 should "have a list of the groups as values" do | 648 should "have a list of the groups as values" do |
448 Group.destroy_all # No fixtures | 649 Group.destroy_all # No fixtures |
449 group1 = Group.generate!.reload | 650 group1 = Group.generate!.reload |
450 group2 = Group.generate!.reload | 651 group2 = Group.generate!.reload |
451 | 652 |
460 | 661 |
461 context "'assigned_to_role' filter" do | 662 context "'assigned_to_role' filter" do |
462 should "be present" do | 663 should "be present" do |
463 assert @query.available_filters.keys.include?("assigned_to_role") | 664 assert @query.available_filters.keys.include?("assigned_to_role") |
464 end | 665 end |
465 | 666 |
466 should "be an optional list" do | 667 should "be an optional list" do |
467 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type] | 668 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type] |
468 end | 669 end |
469 | 670 |
470 should "have a list of the Roles as values" do | 671 should "have a list of the Roles as values" do |
471 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1']) | 672 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1']) |
472 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2']) | 673 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2']) |
473 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3']) | 674 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3']) |
474 end | 675 end |
488 Group.destroy_all # No fixtures | 689 Group.destroy_all # No fixtures |
489 @user_in_group = User.generate! | 690 @user_in_group = User.generate! |
490 @second_user_in_group = User.generate! | 691 @second_user_in_group = User.generate! |
491 @user_in_group2 = User.generate! | 692 @user_in_group2 = User.generate! |
492 @user_not_in_group = User.generate! | 693 @user_not_in_group = User.generate! |
493 | 694 |
494 @group = Group.generate!.reload | 695 @group = Group.generate!.reload |
495 @group.users << @user_in_group | 696 @group.users << @user_in_group |
496 @group.users << @second_user_in_group | 697 @group.users << @second_user_in_group |
497 | 698 |
498 @group2 = Group.generate!.reload | 699 @group2 = Group.generate!.reload |
499 @group2.users << @user_in_group2 | 700 @group2.users << @user_in_group2 |
500 | 701 |
501 end | 702 end |
502 | 703 |
503 should "search assigned to for users in the group" do | 704 should "search assigned to for users in the group" do |
504 @query = Query.new(:name => '_') | 705 @query = Query.new(:name => '_') |
505 @query.add_filter('member_of_group', '=', [@group.id.to_s]) | 706 @query.add_filter('member_of_group', '=', [@group.id.to_s]) |
506 | 707 |
507 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')" | 708 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')" |
523 | 724 |
524 # Only users in a group | 725 # Only users in a group |
525 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}')" | 726 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}')" |
526 assert_find_issues_with_query_is_successful @query | 727 assert_find_issues_with_query_is_successful @query |
527 end | 728 end |
528 | 729 |
529 should "return an empty set with = empty group" do | 730 should "return an empty set with = empty group" do |
530 @empty_group = Group.generate! | 731 @empty_group = Group.generate! |
531 @query = Query.new(:name => '_') | 732 @query = Query.new(:name => '_') |
532 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s]) | 733 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s]) |
533 | 734 |
534 assert_equal [], find_issues_with_query(@query) | 735 assert_equal [], find_issues_with_query(@query) |
535 end | 736 end |
536 | 737 |
537 should "return issues with ! empty group" do | 738 should "return issues with ! empty group" do |
538 @empty_group = Group.generate! | 739 @empty_group = Group.generate! |
539 @query = Query.new(:name => '_') | 740 @query = Query.new(:name => '_') |
540 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s]) | 741 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s]) |
541 | 742 |
542 assert_find_issues_with_query_is_successful @query | 743 assert_find_issues_with_query_is_successful @query |
543 end | 744 end |
544 end | 745 end |
545 | 746 |
546 context "with 'assigned_to_role' filter" do | 747 context "with 'assigned_to_role' filter" do |
547 setup do | 748 setup do |
548 # No fixtures | 749 @manager_role = Role.find_by_name('Manager') |
549 MemberRole.delete_all | 750 @developer_role = Role.find_by_name('Developer') |
550 Member.delete_all | |
551 Role.delete_all | |
552 | |
553 @manager_role = Role.generate!(:name => 'Manager') | |
554 @developer_role = Role.generate!(:name => 'Developer') | |
555 | 751 |
556 @project = Project.generate! | 752 @project = Project.generate! |
557 @manager = User.generate! | 753 @manager = User.generate! |
558 @developer = User.generate! | 754 @developer = User.generate! |
559 @boss = User.generate! | 755 @boss = User.generate! |
756 @guest = User.generate! | |
560 User.add_to_project(@manager, @project, @manager_role) | 757 User.add_to_project(@manager, @project, @manager_role) |
561 User.add_to_project(@developer, @project, @developer_role) | 758 User.add_to_project(@developer, @project, @developer_role) |
562 User.add_to_project(@boss, @project, [@manager_role, @developer_role]) | 759 User.add_to_project(@boss, @project, [@manager_role, @developer_role]) |
563 end | 760 |
564 | 761 @issue1 = Issue.generate_for_project!(@project, :assigned_to_id => @manager.id) |
762 @issue2 = Issue.generate_for_project!(@project, :assigned_to_id => @developer.id) | |
763 @issue3 = Issue.generate_for_project!(@project, :assigned_to_id => @boss.id) | |
764 @issue4 = Issue.generate_for_project!(@project, :assigned_to_id => @guest.id) | |
765 @issue5 = Issue.generate_for_project!(@project) | |
766 end | |
767 | |
565 should "search assigned to for users with the Role" do | 768 should "search assigned to for users with the Role" do |
566 @query = Query.new(:name => '_') | 769 @query = Query.new(:name => '_', :project => @project) |
567 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s]) | 770 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s]) |
568 | 771 |
569 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@boss.id}')" | 772 assert_query_result [@issue1, @issue3], @query |
570 assert_find_issues_with_query_is_successful @query | 773 end |
571 end | 774 |
572 | 775 should "search assigned to for users with the Role on the issue project" do |
573 should "search assigned to for users not assigned to any Role (none)" do | 776 other_project = Project.generate! |
574 @query = Query.new(:name => '_') | 777 User.add_to_project(@developer, other_project, @manager_role) |
575 @query.add_filter('assigned_to_role', '!*', ['']) | 778 |
576 | 779 @query = Query.new(:name => '_', :project => @project) |
577 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')" | 780 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s]) |
578 assert_find_issues_with_query_is_successful @query | 781 |
579 end | 782 assert_query_result [@issue1, @issue3], @query |
580 | 783 end |
581 should "search assigned to for users assigned to any Role (all)" do | 784 |
582 @query = Query.new(:name => '_') | |
583 @query.add_filter('assigned_to_role', '*', ['']) | |
584 | |
585 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')" | |
586 assert_find_issues_with_query_is_successful @query | |
587 end | |
588 | |
589 should "return an empty set with empty role" do | 785 should "return an empty set with empty role" do |
590 @empty_role = Role.generate! | 786 @empty_role = Role.generate! |
591 @query = Query.new(:name => '_') | 787 @query = Query.new(:name => '_', :project => @project) |
592 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s]) | 788 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s]) |
593 | 789 |
594 assert_equal [], find_issues_with_query(@query) | 790 assert_query_result [], @query |
595 end | 791 end |
596 | 792 |
793 should "search assigned to for users without the Role" do | |
794 @query = Query.new(:name => '_', :project => @project) | |
795 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s]) | |
796 | |
797 assert_query_result [@issue2, @issue4, @issue5], @query | |
798 end | |
799 | |
800 should "search assigned to for users not assigned to any Role (none)" do | |
801 @query = Query.new(:name => '_', :project => @project) | |
802 @query.add_filter('assigned_to_role', '!*', ['']) | |
803 | |
804 assert_query_result [@issue4, @issue5], @query | |
805 end | |
806 | |
807 should "search assigned to for users assigned to any Role (all)" do | |
808 @query = Query.new(:name => '_', :project => @project) | |
809 @query.add_filter('assigned_to_role', '*', ['']) | |
810 | |
811 assert_query_result [@issue1, @issue2, @issue3], @query | |
812 end | |
813 | |
597 should "return issues with ! empty role" do | 814 should "return issues with ! empty role" do |
598 @empty_role = Role.generate! | 815 @empty_role = Role.generate! |
599 @query = Query.new(:name => '_') | 816 @query = Query.new(:name => '_', :project => @project) |
600 @query.add_filter('member_of_group', '!', [@empty_role.id.to_s]) | 817 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s]) |
601 | 818 |
602 assert_find_issues_with_query_is_successful @query | 819 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query |
603 end | 820 end |
604 end | 821 end |
605 end | 822 end |
606 | 823 |
607 end | 824 end |