comparison test/unit/query_test.rb @ 1298:4f746d8966dd redmine_2.3_integration

Merge from redmine-2.3 branch to create new branch redmine-2.3-integration
author Chris Cannam
date Fri, 14 Jun 2013 09:28:30 +0100
parents 622f24f53b42
children
comparison
equal deleted inserted replaced
1297:0a574315af3e 1298:4f746d8966dd
1 # Redmine - project management software 1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
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.
26 :watchers, :custom_fields, :custom_values, :versions, 26 :watchers, :custom_fields, :custom_values, :versions,
27 :queries, 27 :queries,
28 :projects_trackers, 28 :projects_trackers,
29 :custom_fields_trackers 29 :custom_fields_trackers
30 30
31 def test_available_filters_should_be_ordered
32 query = IssueQuery.new
33 assert_equal 0, query.available_filters.keys.index('status_id')
34 end
35
31 def test_custom_fields_for_all_projects_should_be_available_in_global_queries 36 def test_custom_fields_for_all_projects_should_be_available_in_global_queries
32 query = Query.new(:project => nil, :name => '_') 37 query = IssueQuery.new(:project => nil, :name => '_')
33 assert query.available_filters.has_key?('cf_1') 38 assert query.available_filters.has_key?('cf_1')
34 assert !query.available_filters.has_key?('cf_3') 39 assert !query.available_filters.has_key?('cf_3')
35 end 40 end
36 41
37 def test_system_shared_versions_should_be_available_in_global_queries 42 def test_system_shared_versions_should_be_available_in_global_queries
38 Version.find(2).update_attribute :sharing, 'system' 43 Version.find(2).update_attribute :sharing, 'system'
39 query = Query.new(:project => nil, :name => '_') 44 query = IssueQuery.new(:project => nil, :name => '_')
40 assert query.available_filters.has_key?('fixed_version_id') 45 assert query.available_filters.has_key?('fixed_version_id')
41 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'} 46 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
42 end 47 end
43 48
44 def test_project_filter_in_global_queries 49 def test_project_filter_in_global_queries
45 query = Query.new(:project => nil, :name => '_') 50 query = IssueQuery.new(:project => nil, :name => '_')
46 project_filter = query.available_filters["project_id"] 51 project_filter = query.available_filters["project_id"]
47 assert_not_nil project_filter 52 assert_not_nil project_filter
48 project_ids = project_filter[:values].map{|p| p[1]} 53 project_ids = project_filter[:values].map{|p| p[1]}
49 assert project_ids.include?("1") #public project 54 assert project_ids.include?("1") #public project
50 assert !project_ids.include?("2") #private project user cannot see 55 assert !project_ids.include?("2") #private project user cannot see
61 find_issues_with_query(query) 66 find_issues_with_query(query)
62 end 67 end
63 end 68 end
64 69
65 def assert_query_statement_includes(query, condition) 70 def assert_query_statement_includes(query, condition)
66 assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}" 71 assert_include condition, query.statement
67 end 72 end
68 73
69 def assert_query_result(expected, query) 74 def assert_query_result(expected, query)
70 assert_nothing_raised do 75 assert_nothing_raised do
71 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort 76 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
73 end 78 end
74 end 79 end
75 80
76 def test_query_should_allow_shared_versions_for_a_project_query 81 def test_query_should_allow_shared_versions_for_a_project_query
77 subproject_version = Version.find(4) 82 subproject_version = Version.find(4)
78 query = Query.new(:project => Project.find(1), :name => '_') 83 query = IssueQuery.new(:project => Project.find(1), :name => '_')
79 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s]) 84 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
80 85
81 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')") 86 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
82 end 87 end
83 88
84 def test_query_with_multiple_custom_fields 89 def test_query_with_multiple_custom_fields
85 query = Query.find(1) 90 query = IssueQuery.find(1)
86 assert query.valid? 91 assert query.valid?
87 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')") 92 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
88 issues = find_issues_with_query(query) 93 issues = find_issues_with_query(query)
89 assert_equal 1, issues.length 94 assert_equal 1, issues.length
90 assert_equal Issue.find(3), issues.first 95 assert_equal Issue.find(3), issues.first
91 end 96 end
92 97
93 def test_operator_none 98 def test_operator_none
94 query = Query.new(:project => Project.find(1), :name => '_') 99 query = IssueQuery.new(:project => Project.find(1), :name => '_')
95 query.add_filter('fixed_version_id', '!*', ['']) 100 query.add_filter('fixed_version_id', '!*', [''])
96 query.add_filter('cf_1', '!*', ['']) 101 query.add_filter('cf_1', '!*', [''])
97 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL") 102 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
98 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''") 103 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
99 find_issues_with_query(query) 104 find_issues_with_query(query)
100 end 105 end
101 106
102 def test_operator_none_for_integer 107 def test_operator_none_for_integer
103 query = Query.new(:project => Project.find(1), :name => '_') 108 query = IssueQuery.new(:project => Project.find(1), :name => '_')
104 query.add_filter('estimated_hours', '!*', ['']) 109 query.add_filter('estimated_hours', '!*', [''])
105 issues = find_issues_with_query(query) 110 issues = find_issues_with_query(query)
106 assert !issues.empty? 111 assert !issues.empty?
107 assert issues.all? {|i| !i.estimated_hours} 112 assert issues.all? {|i| !i.estimated_hours}
108 end 113 end
109 114
110 def test_operator_none_for_date 115 def test_operator_none_for_date
111 query = Query.new(:project => Project.find(1), :name => '_') 116 query = IssueQuery.new(:project => Project.find(1), :name => '_')
112 query.add_filter('start_date', '!*', ['']) 117 query.add_filter('start_date', '!*', [''])
113 issues = find_issues_with_query(query) 118 issues = find_issues_with_query(query)
114 assert !issues.empty? 119 assert !issues.empty?
115 assert issues.all? {|i| i.start_date.nil?} 120 assert issues.all? {|i| i.start_date.nil?}
116 end 121 end
117 122
118 def test_operator_none_for_string_custom_field 123 def test_operator_none_for_string_custom_field
119 query = Query.new(:project => Project.find(1), :name => '_') 124 query = IssueQuery.new(:project => Project.find(1), :name => '_')
120 query.add_filter('cf_2', '!*', ['']) 125 query.add_filter('cf_2', '!*', [''])
121 assert query.has_filter?('cf_2') 126 assert query.has_filter?('cf_2')
122 issues = find_issues_with_query(query) 127 issues = find_issues_with_query(query)
123 assert !issues.empty? 128 assert !issues.empty?
124 assert issues.all? {|i| i.custom_field_value(2).blank?} 129 assert issues.all? {|i| i.custom_field_value(2).blank?}
125 end 130 end
126 131
127 def test_operator_all 132 def test_operator_all
128 query = Query.new(:project => Project.find(1), :name => '_') 133 query = IssueQuery.new(:project => Project.find(1), :name => '_')
129 query.add_filter('fixed_version_id', '*', ['']) 134 query.add_filter('fixed_version_id', '*', [''])
130 query.add_filter('cf_1', '*', ['']) 135 query.add_filter('cf_1', '*', [''])
131 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL") 136 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
132 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''") 137 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
133 find_issues_with_query(query) 138 find_issues_with_query(query)
134 end 139 end
135 140
136 def test_operator_all_for_date 141 def test_operator_all_for_date
137 query = Query.new(:project => Project.find(1), :name => '_') 142 query = IssueQuery.new(:project => Project.find(1), :name => '_')
138 query.add_filter('start_date', '*', ['']) 143 query.add_filter('start_date', '*', [''])
139 issues = find_issues_with_query(query) 144 issues = find_issues_with_query(query)
140 assert !issues.empty? 145 assert !issues.empty?
141 assert issues.all? {|i| i.start_date.present?} 146 assert issues.all? {|i| i.start_date.present?}
142 end 147 end
143 148
144 def test_operator_all_for_string_custom_field 149 def test_operator_all_for_string_custom_field
145 query = Query.new(:project => Project.find(1), :name => '_') 150 query = IssueQuery.new(:project => Project.find(1), :name => '_')
146 query.add_filter('cf_2', '*', ['']) 151 query.add_filter('cf_2', '*', [''])
147 assert query.has_filter?('cf_2') 152 assert query.has_filter?('cf_2')
148 issues = find_issues_with_query(query) 153 issues = find_issues_with_query(query)
149 assert !issues.empty? 154 assert !issues.empty?
150 assert issues.all? {|i| i.custom_field_value(2).present?} 155 assert issues.all? {|i| i.custom_field_value(2).present?}
151 end 156 end
152 157
153 def test_numeric_filter_should_not_accept_non_numeric_values 158 def test_numeric_filter_should_not_accept_non_numeric_values
154 query = Query.new(:name => '_') 159 query = IssueQuery.new(:name => '_')
155 query.add_filter('estimated_hours', '=', ['a']) 160 query.add_filter('estimated_hours', '=', ['a'])
156 161
157 assert query.has_filter?('estimated_hours') 162 assert query.has_filter?('estimated_hours')
158 assert !query.valid? 163 assert !query.valid?
159 end 164 end
160 165
161 def test_operator_is_on_float 166 def test_operator_is_on_float
162 Issue.update_all("estimated_hours = 171.2", "id=2") 167 Issue.update_all("estimated_hours = 171.2", "id=2")
163 168
164 query = Query.new(:name => '_') 169 query = IssueQuery.new(:name => '_')
165 query.add_filter('estimated_hours', '=', ['171.20']) 170 query.add_filter('estimated_hours', '=', ['171.20'])
166 issues = find_issues_with_query(query) 171 issues = find_issues_with_query(query)
167 assert_equal 1, issues.size 172 assert_equal 1, issues.size
168 assert_equal 2, issues.first.id 173 assert_equal 2, issues.first.id
169 end 174 end
172 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true) 177 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true)
173 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7') 178 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
174 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12') 179 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
175 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '') 180 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
176 181
177 query = Query.new(:name => '_') 182 query = IssueQuery.new(:name => '_')
178 query.add_filter("cf_#{f.id}", '=', ['12']) 183 query.add_filter("cf_#{f.id}", '=', ['12'])
179 issues = find_issues_with_query(query) 184 issues = find_issues_with_query(query)
180 assert_equal 1, issues.size 185 assert_equal 1, issues.size
181 assert_equal 2, issues.first.id 186 assert_equal 2, issues.first.id
182 end 187 end
185 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true) 190 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true)
186 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7') 191 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
187 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12') 192 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12')
188 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '') 193 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
189 194
190 query = Query.new(:name => '_') 195 query = IssueQuery.new(:name => '_')
191 query.add_filter("cf_#{f.id}", '=', ['-12']) 196 query.add_filter("cf_#{f.id}", '=', ['-12'])
192 assert query.valid? 197 assert query.valid?
193 issues = find_issues_with_query(query) 198 issues = find_issues_with_query(query)
194 assert_equal 1, issues.size 199 assert_equal 1, issues.size
195 assert_equal 2, issues.first.id 200 assert_equal 2, issues.first.id
199 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true) 204 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true)
200 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3') 205 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
201 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7') 206 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
202 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '') 207 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
203 208
204 query = Query.new(:name => '_') 209 query = IssueQuery.new(:name => '_')
205 query.add_filter("cf_#{f.id}", '=', ['12.7']) 210 query.add_filter("cf_#{f.id}", '=', ['12.7'])
206 issues = find_issues_with_query(query) 211 issues = find_issues_with_query(query)
207 assert_equal 1, issues.size 212 assert_equal 1, issues.size
208 assert_equal 2, issues.first.id 213 assert_equal 2, issues.first.id
209 end 214 end
212 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true) 217 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true)
213 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3') 218 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
214 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12.7') 219 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12.7')
215 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '') 220 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
216 221
217 query = Query.new(:name => '_') 222 query = IssueQuery.new(:name => '_')
218 query.add_filter("cf_#{f.id}", '=', ['-12.7']) 223 query.add_filter("cf_#{f.id}", '=', ['-12.7'])
219 assert query.valid? 224 assert query.valid?
220 issues = find_issues_with_query(query) 225 issues = find_issues_with_query(query)
221 assert_equal 1, issues.size 226 assert_equal 1, issues.size
222 assert_equal 2, issues.first.id 227 assert_equal 2, issues.first.id
227 :possible_values => ['value1', 'value2', 'value3'], :multiple => true) 232 :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
228 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1') 233 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
229 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2') 234 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
230 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1') 235 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
231 236
232 query = Query.new(:name => '_') 237 query = IssueQuery.new(:name => '_')
233 query.add_filter("cf_#{f.id}", '=', ['value1']) 238 query.add_filter("cf_#{f.id}", '=', ['value1'])
234 issues = find_issues_with_query(query) 239 issues = find_issues_with_query(query)
235 assert_equal [1, 3], issues.map(&:id).sort 240 assert_equal [1, 3], issues.map(&:id).sort
236 241
237 query = Query.new(:name => '_') 242 query = IssueQuery.new(:name => '_')
238 query.add_filter("cf_#{f.id}", '=', ['value2']) 243 query.add_filter("cf_#{f.id}", '=', ['value2'])
239 issues = find_issues_with_query(query) 244 issues = find_issues_with_query(query)
240 assert_equal [1], issues.map(&:id).sort 245 assert_equal [1], issues.map(&:id).sort
241 end 246 end
242 247
245 :possible_values => ['value1', 'value2', 'value3'], :multiple => true) 250 :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
246 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1') 251 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
247 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2') 252 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
248 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1') 253 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
249 254
250 query = Query.new(:name => '_') 255 query = IssueQuery.new(:name => '_')
251 query.add_filter("cf_#{f.id}", '!', ['value1']) 256 query.add_filter("cf_#{f.id}", '!', ['value1'])
252 issues = find_issues_with_query(query) 257 issues = find_issues_with_query(query)
253 assert !issues.map(&:id).include?(1) 258 assert !issues.map(&:id).include?(1)
254 assert !issues.map(&:id).include?(3) 259 assert !issues.map(&:id).include?(3)
255 260
256 query = Query.new(:name => '_') 261 query = IssueQuery.new(:name => '_')
257 query.add_filter("cf_#{f.id}", '!', ['value2']) 262 query.add_filter("cf_#{f.id}", '!', ['value2'])
258 issues = find_issues_with_query(query) 263 issues = find_issues_with_query(query)
259 assert !issues.map(&:id).include?(1) 264 assert !issues.map(&:id).include?(1)
260 assert issues.map(&:id).include?(3) 265 assert issues.map(&:id).include?(3)
261 end 266 end
262 267
263 def test_operator_is_on_is_private_field 268 def test_operator_is_on_is_private_field
264 # is_private filter only available for those who can set issues private 269 # is_private filter only available for those who can set issues private
265 User.current = User.find(2) 270 User.current = User.find(2)
266 271
267 query = Query.new(:name => '_') 272 query = IssueQuery.new(:name => '_')
268 assert query.available_filters.key?('is_private') 273 assert query.available_filters.key?('is_private')
269 274
270 query.add_filter("is_private", '=', ['1']) 275 query.add_filter("is_private", '=', ['1'])
271 issues = find_issues_with_query(query) 276 issues = find_issues_with_query(query)
272 assert issues.any? 277 assert issues.any?
277 282
278 def test_operator_is_not_on_is_private_field 283 def test_operator_is_not_on_is_private_field
279 # is_private filter only available for those who can set issues private 284 # is_private filter only available for those who can set issues private
280 User.current = User.find(2) 285 User.current = User.find(2)
281 286
282 query = Query.new(:name => '_') 287 query = IssueQuery.new(:name => '_')
283 assert query.available_filters.key?('is_private') 288 assert query.available_filters.key?('is_private')
284 289
285 query.add_filter("is_private", '!', ['1']) 290 query.add_filter("is_private", '!', ['1'])
286 issues = find_issues_with_query(query) 291 issues = find_issues_with_query(query)
287 assert issues.any? 292 assert issues.any?
289 ensure 294 ensure
290 User.current = nil 295 User.current = nil
291 end 296 end
292 297
293 def test_operator_greater_than 298 def test_operator_greater_than
294 query = Query.new(:project => Project.find(1), :name => '_') 299 query = IssueQuery.new(:project => Project.find(1), :name => '_')
295 query.add_filter('done_ratio', '>=', ['40']) 300 query.add_filter('done_ratio', '>=', ['40'])
296 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0") 301 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
297 find_issues_with_query(query) 302 find_issues_with_query(query)
298 end 303 end
299 304
300 def test_operator_greater_than_a_float 305 def test_operator_greater_than_a_float
301 query = Query.new(:project => Project.find(1), :name => '_') 306 query = IssueQuery.new(:project => Project.find(1), :name => '_')
302 query.add_filter('estimated_hours', '>=', ['40.5']) 307 query.add_filter('estimated_hours', '>=', ['40.5'])
303 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5") 308 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
304 find_issues_with_query(query) 309 find_issues_with_query(query)
305 end 310 end
306 311
308 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true) 313 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
309 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7') 314 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
310 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12') 315 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
311 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '') 316 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
312 317
313 query = Query.new(:project => Project.find(1), :name => '_') 318 query = IssueQuery.new(:project => Project.find(1), :name => '_')
314 query.add_filter("cf_#{f.id}", '>=', ['8']) 319 query.add_filter("cf_#{f.id}", '>=', ['8'])
315 issues = find_issues_with_query(query) 320 issues = find_issues_with_query(query)
316 assert_equal 1, issues.size 321 assert_equal 1, issues.size
317 assert_equal 2, issues.first.id 322 assert_equal 2, issues.first.id
318 end 323 end
319 324
320 def test_operator_lesser_than 325 def test_operator_lesser_than
321 query = Query.new(:project => Project.find(1), :name => '_') 326 query = IssueQuery.new(:project => Project.find(1), :name => '_')
322 query.add_filter('done_ratio', '<=', ['30']) 327 query.add_filter('done_ratio', '<=', ['30'])
323 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0") 328 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
324 find_issues_with_query(query) 329 find_issues_with_query(query)
325 end 330 end
326 331
327 def test_operator_lesser_than_on_custom_field 332 def test_operator_lesser_than_on_custom_field
328 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true) 333 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
329 query = Query.new(:project => Project.find(1), :name => '_') 334 query = IssueQuery.new(:project => Project.find(1), :name => '_')
330 query.add_filter("cf_#{f.id}", '<=', ['30']) 335 query.add_filter("cf_#{f.id}", '<=', ['30'])
331 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0") 336 assert_match /CAST.+ <= 30\.0/, query.statement
332 find_issues_with_query(query) 337 find_issues_with_query(query)
338 end
339
340 def test_operator_lesser_than_on_date_custom_field
341 f = IssueCustomField.create!(:name => 'filter', :field_format => 'date', :is_filter => true, :is_for_all => true)
342 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '2013-04-11')
343 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '2013-05-14')
344 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
345
346 query = IssueQuery.new(:project => Project.find(1), :name => '_')
347 query.add_filter("cf_#{f.id}", '<=', ['2013-05-01'])
348 issue_ids = find_issues_with_query(query).map(&:id)
349 assert_include 1, issue_ids
350 assert_not_include 2, issue_ids
351 assert_not_include 3, issue_ids
333 end 352 end
334 353
335 def test_operator_between 354 def test_operator_between
336 query = Query.new(:project => Project.find(1), :name => '_') 355 query = IssueQuery.new(:project => Project.find(1), :name => '_')
337 query.add_filter('done_ratio', '><', ['30', '40']) 356 query.add_filter('done_ratio', '><', ['30', '40'])
338 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement 357 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
339 find_issues_with_query(query) 358 find_issues_with_query(query)
340 end 359 end
341 360
342 def test_operator_between_on_custom_field 361 def test_operator_between_on_custom_field
343 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true) 362 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
344 query = Query.new(:project => Project.find(1), :name => '_') 363 query = IssueQuery.new(:project => Project.find(1), :name => '_')
345 query.add_filter("cf_#{f.id}", '><', ['30', '40']) 364 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
346 assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement 365 assert_match /CAST.+ BETWEEN 30.0 AND 40.0/, query.statement
347 find_issues_with_query(query) 366 find_issues_with_query(query)
348 end 367 end
349 368
350 def test_date_filter_should_not_accept_non_date_values 369 def test_date_filter_should_not_accept_non_date_values
351 query = Query.new(:name => '_') 370 query = IssueQuery.new(:name => '_')
352 query.add_filter('created_on', '=', ['a']) 371 query.add_filter('created_on', '=', ['a'])
353 372
354 assert query.has_filter?('created_on') 373 assert query.has_filter?('created_on')
355 assert !query.valid? 374 assert !query.valid?
356 end 375 end
357 376
358 def test_date_filter_should_not_accept_invalid_date_values 377 def test_date_filter_should_not_accept_invalid_date_values
359 query = Query.new(:name => '_') 378 query = IssueQuery.new(:name => '_')
360 query.add_filter('created_on', '=', ['2011-01-34']) 379 query.add_filter('created_on', '=', ['2011-01-34'])
361 380
362 assert query.has_filter?('created_on') 381 assert query.has_filter?('created_on')
363 assert !query.valid? 382 assert !query.valid?
364 end 383 end
365 384
366 def test_relative_date_filter_should_not_accept_non_integer_values 385 def test_relative_date_filter_should_not_accept_non_integer_values
367 query = Query.new(:name => '_') 386 query = IssueQuery.new(:name => '_')
368 query.add_filter('created_on', '>t-', ['a']) 387 query.add_filter('created_on', '>t-', ['a'])
369 388
370 assert query.has_filter?('created_on') 389 assert query.has_filter?('created_on')
371 assert !query.valid? 390 assert !query.valid?
372 end 391 end
373 392
374 def test_operator_date_equals 393 def test_operator_date_equals
375 query = Query.new(:name => '_') 394 query = IssueQuery.new(:name => '_')
376 query.add_filter('due_date', '=', ['2011-07-10']) 395 query.add_filter('due_date', '=', ['2011-07-10'])
377 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 396 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
378 find_issues_with_query(query) 397 find_issues_with_query(query)
379 end 398 end
380 399
381 def test_operator_date_lesser_than 400 def test_operator_date_lesser_than
382 query = Query.new(:name => '_') 401 query = IssueQuery.new(:name => '_')
383 query.add_filter('due_date', '<=', ['2011-07-10']) 402 query.add_filter('due_date', '<=', ['2011-07-10'])
384 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement 403 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
385 find_issues_with_query(query) 404 find_issues_with_query(query)
386 end 405 end
387 406
388 def test_operator_date_greater_than 407 def test_operator_date_greater_than
389 query = Query.new(:name => '_') 408 query = IssueQuery.new(:name => '_')
390 query.add_filter('due_date', '>=', ['2011-07-10']) 409 query.add_filter('due_date', '>=', ['2011-07-10'])
391 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement 410 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
392 find_issues_with_query(query) 411 find_issues_with_query(query)
393 end 412 end
394 413
395 def test_operator_date_between 414 def test_operator_date_between
396 query = Query.new(:name => '_') 415 query = IssueQuery.new(:name => '_')
397 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10']) 416 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
398 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 417 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
399 find_issues_with_query(query) 418 find_issues_with_query(query)
400 end 419 end
401 420
402 def test_operator_in_more_than 421 def test_operator_in_more_than
403 Issue.find(7).update_attribute(:due_date, (Date.today + 15)) 422 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
404 query = Query.new(:project => Project.find(1), :name => '_') 423 query = IssueQuery.new(:project => Project.find(1), :name => '_')
405 query.add_filter('due_date', '>t+', ['15']) 424 query.add_filter('due_date', '>t+', ['15'])
406 issues = find_issues_with_query(query) 425 issues = find_issues_with_query(query)
407 assert !issues.empty? 426 assert !issues.empty?
408 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))} 427 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
409 end 428 end
410 429
411 def test_operator_in_less_than 430 def test_operator_in_less_than
412 query = Query.new(:project => Project.find(1), :name => '_') 431 query = IssueQuery.new(:project => Project.find(1), :name => '_')
413 query.add_filter('due_date', '<t+', ['15']) 432 query.add_filter('due_date', '<t+', ['15'])
414 issues = find_issues_with_query(query) 433 issues = find_issues_with_query(query)
415 assert !issues.empty? 434 assert !issues.empty?
416 issues.each {|issue| assert(issue.due_date <= (Date.today + 15))} 435 issues.each {|issue| assert(issue.due_date <= (Date.today + 15))}
417 end 436 end
418 437
419 def test_operator_in_the_next_days 438 def test_operator_in_the_next_days
420 query = Query.new(:project => Project.find(1), :name => '_') 439 query = IssueQuery.new(:project => Project.find(1), :name => '_')
421 query.add_filter('due_date', '><t+', ['15']) 440 query.add_filter('due_date', '><t+', ['15'])
422 issues = find_issues_with_query(query) 441 issues = find_issues_with_query(query)
423 assert !issues.empty? 442 assert !issues.empty?
424 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))} 443 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
425 end 444 end
426 445
427 def test_operator_less_than_ago 446 def test_operator_less_than_ago
428 Issue.find(7).update_attribute(:due_date, (Date.today - 3)) 447 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
429 query = Query.new(:project => Project.find(1), :name => '_') 448 query = IssueQuery.new(:project => Project.find(1), :name => '_')
430 query.add_filter('due_date', '>t-', ['3']) 449 query.add_filter('due_date', '>t-', ['3'])
431 issues = find_issues_with_query(query) 450 issues = find_issues_with_query(query)
432 assert !issues.empty? 451 assert !issues.empty?
433 issues.each {|issue| assert(issue.due_date >= (Date.today - 3))} 452 issues.each {|issue| assert(issue.due_date >= (Date.today - 3))}
434 end 453 end
435 454
436 def test_operator_in_the_past_days 455 def test_operator_in_the_past_days
437 Issue.find(7).update_attribute(:due_date, (Date.today - 3)) 456 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
438 query = Query.new(:project => Project.find(1), :name => '_') 457 query = IssueQuery.new(:project => Project.find(1), :name => '_')
439 query.add_filter('due_date', '><t-', ['3']) 458 query.add_filter('due_date', '><t-', ['3'])
440 issues = find_issues_with_query(query) 459 issues = find_issues_with_query(query)
441 assert !issues.empty? 460 assert !issues.empty?
442 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)} 461 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
443 end 462 end
444 463
445 def test_operator_more_than_ago 464 def test_operator_more_than_ago
446 Issue.find(7).update_attribute(:due_date, (Date.today - 10)) 465 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
447 query = Query.new(:project => Project.find(1), :name => '_') 466 query = IssueQuery.new(:project => Project.find(1), :name => '_')
448 query.add_filter('due_date', '<t-', ['10']) 467 query.add_filter('due_date', '<t-', ['10'])
449 assert query.statement.include?("#{Issue.table_name}.due_date <=") 468 assert query.statement.include?("#{Issue.table_name}.due_date <=")
450 issues = find_issues_with_query(query) 469 issues = find_issues_with_query(query)
451 assert !issues.empty? 470 assert !issues.empty?
452 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))} 471 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
453 end 472 end
454 473
455 def test_operator_in 474 def test_operator_in
456 Issue.find(7).update_attribute(:due_date, (Date.today + 2)) 475 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
457 query = Query.new(:project => Project.find(1), :name => '_') 476 query = IssueQuery.new(:project => Project.find(1), :name => '_')
458 query.add_filter('due_date', 't+', ['2']) 477 query.add_filter('due_date', 't+', ['2'])
459 issues = find_issues_with_query(query) 478 issues = find_issues_with_query(query)
460 assert !issues.empty? 479 assert !issues.empty?
461 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)} 480 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
462 end 481 end
463 482
464 def test_operator_ago 483 def test_operator_ago
465 Issue.find(7).update_attribute(:due_date, (Date.today - 3)) 484 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
466 query = Query.new(:project => Project.find(1), :name => '_') 485 query = IssueQuery.new(:project => Project.find(1), :name => '_')
467 query.add_filter('due_date', 't-', ['3']) 486 query.add_filter('due_date', 't-', ['3'])
468 issues = find_issues_with_query(query) 487 issues = find_issues_with_query(query)
469 assert !issues.empty? 488 assert !issues.empty?
470 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)} 489 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
471 end 490 end
472 491
473 def test_operator_today 492 def test_operator_today
474 query = Query.new(:project => Project.find(1), :name => '_') 493 query = IssueQuery.new(:project => Project.find(1), :name => '_')
475 query.add_filter('due_date', 't', ['']) 494 query.add_filter('due_date', 't', [''])
476 issues = find_issues_with_query(query) 495 issues = find_issues_with_query(query)
477 assert !issues.empty? 496 assert !issues.empty?
478 issues.each {|issue| assert_equal Date.today, issue.due_date} 497 issues.each {|issue| assert_equal Date.today, issue.due_date}
479 end 498 end
480 499
481 def test_operator_this_week_on_date 500 def test_operator_this_week_on_date
482 query = Query.new(:project => Project.find(1), :name => '_') 501 query = IssueQuery.new(:project => Project.find(1), :name => '_')
483 query.add_filter('due_date', 'w', ['']) 502 query.add_filter('due_date', 'w', [''])
484 find_issues_with_query(query) 503 find_issues_with_query(query)
485 end 504 end
486 505
487 def test_operator_this_week_on_datetime 506 def test_operator_this_week_on_datetime
488 query = Query.new(:project => Project.find(1), :name => '_') 507 query = IssueQuery.new(:project => Project.find(1), :name => '_')
489 query.add_filter('created_on', 'w', ['']) 508 query.add_filter('created_on', 'w', [''])
490 find_issues_with_query(query) 509 find_issues_with_query(query)
491 end 510 end
492 511
493 def test_operator_contains 512 def test_operator_contains
494 query = Query.new(:project => Project.find(1), :name => '_') 513 query = IssueQuery.new(:project => Project.find(1), :name => '_')
495 query.add_filter('subject', '~', ['uNable']) 514 query.add_filter('subject', '~', ['uNable'])
496 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'") 515 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
497 result = find_issues_with_query(query) 516 result = find_issues_with_query(query)
498 assert result.empty? 517 assert result.empty?
499 result.each {|issue| assert issue.subject.downcase.include?('unable') } 518 result.each {|issue| assert issue.subject.downcase.include?('unable') }
503 I18n.locale = :fr 522 I18n.locale = :fr
504 assert_equal '1', I18n.t(:general_first_day_of_week) 523 assert_equal '1', I18n.t(:general_first_day_of_week)
505 524
506 Date.stubs(:today).returns(Date.parse('2011-04-29')) 525 Date.stubs(:today).returns(Date.parse('2011-04-29'))
507 526
508 query = Query.new(:project => Project.find(1), :name => '_') 527 query = IssueQuery.new(:project => Project.find(1), :name => '_')
509 query.add_filter('due_date', 'w', ['']) 528 query.add_filter('due_date', 'w', [''])
510 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}" 529 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}"
511 I18n.locale = :en 530 I18n.locale = :en
512 end 531 end
513 532
515 I18n.locale = :en 534 I18n.locale = :en
516 assert_equal '7', I18n.t(:general_first_day_of_week) 535 assert_equal '7', I18n.t(:general_first_day_of_week)
517 536
518 Date.stubs(:today).returns(Date.parse('2011-04-29')) 537 Date.stubs(:today).returns(Date.parse('2011-04-29'))
519 538
520 query = Query.new(:project => Project.find(1), :name => '_') 539 query = IssueQuery.new(:project => Project.find(1), :name => '_')
521 query.add_filter('due_date', 'w', ['']) 540 query.add_filter('due_date', 'w', [''])
522 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}" 541 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}"
523 end 542 end
524 543
525 def test_operator_does_not_contains 544 def test_operator_does_not_contains
526 query = Query.new(:project => Project.find(1), :name => '_') 545 query = IssueQuery.new(:project => Project.find(1), :name => '_')
527 query.add_filter('subject', '!~', ['uNable']) 546 query.add_filter('subject', '!~', ['uNable'])
528 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'") 547 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
529 find_issues_with_query(query) 548 find_issues_with_query(query)
530 end 549 end
531 550
536 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user) 555 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
537 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group) 556 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
538 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11)) 557 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
539 group.users << user 558 group.users << user
540 559
541 query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}}) 560 query = IssueQuery.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
542 result = query.issues 561 result = query.issues
543 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id) 562 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
544 563
545 assert result.include?(i1) 564 assert result.include?(i1)
546 assert result.include?(i2) 565 assert result.include?(i2)
551 User.current = User.find(2) 570 User.current = User.find(2)
552 cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1]) 571 cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])
553 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1) 572 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
554 issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'}) 573 issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
555 574
556 query = Query.new(:name => '_', :project => Project.find(1)) 575 query = IssueQuery.new(:name => '_', :project => Project.find(1))
557 filter = query.available_filters["cf_#{cf.id}"] 576 filter = query.available_filters["cf_#{cf.id}"]
558 assert_not_nil filter 577 assert_not_nil filter
559 assert_include 'me', filter[:values].map{|v| v[1]} 578 assert_include 'me', filter[:values].map{|v| v[1]}
560 579
561 query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}} 580 query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
564 assert_equal issue1, result.first 583 assert_equal issue1, result.first
565 end 584 end
566 585
567 def test_filter_my_projects 586 def test_filter_my_projects
568 User.current = User.find(2) 587 User.current = User.find(2)
569 query = Query.new(:name => '_') 588 query = IssueQuery.new(:name => '_')
570 filter = query.available_filters['project_id'] 589 filter = query.available_filters['project_id']
571 assert_not_nil filter 590 assert_not_nil filter
572 assert_include 'mine', filter[:values].map{|v| v[1]} 591 assert_include 'mine', filter[:values].map{|v| v[1]}
573 592
574 query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}} 593 query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}}
576 assert_nil result.detect {|issue| !User.current.member_of?(issue.project)} 595 assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
577 end 596 end
578 597
579 def test_filter_watched_issues 598 def test_filter_watched_issues
580 User.current = User.find(1) 599 User.current = User.find(1)
581 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}}) 600 query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
582 result = find_issues_with_query(query) 601 result = find_issues_with_query(query)
583 assert_not_nil result 602 assert_not_nil result
584 assert !result.empty? 603 assert !result.empty?
585 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id) 604 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
586 User.current = nil 605 User.current = nil
587 end 606 end
588 607
589 def test_filter_unwatched_issues 608 def test_filter_unwatched_issues
590 User.current = User.find(1) 609 User.current = User.find(1)
591 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}}) 610 query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
592 result = find_issues_with_query(query) 611 result = find_issues_with_query(query)
593 assert_not_nil result 612 assert_not_nil result
594 assert !result.empty? 613 assert !result.empty?
595 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size) 614 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
596 User.current = nil 615 User.current = nil
599 def test_filter_on_project_custom_field 618 def test_filter_on_project_custom_field
600 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string') 619 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
601 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo') 620 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
602 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo') 621 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
603 622
604 query = Query.new(:name => '_') 623 query = IssueQuery.new(:name => '_')
605 filter_name = "project.cf_#{field.id}" 624 filter_name = "project.cf_#{field.id}"
606 assert_include filter_name, query.available_filters.keys 625 assert_include filter_name, query.available_filters.keys
607 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}} 626 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
608 assert_equal [3, 5], find_issues_with_query(query).map(&:project_id).uniq.sort 627 assert_equal [3, 5], find_issues_with_query(query).map(&:project_id).uniq.sort
609 end 628 end
610 629
611 def test_filter_on_author_custom_field 630 def test_filter_on_author_custom_field
612 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string') 631 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
613 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo') 632 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
614 633
615 query = Query.new(:name => '_') 634 query = IssueQuery.new(:name => '_')
616 filter_name = "author.cf_#{field.id}" 635 filter_name = "author.cf_#{field.id}"
617 assert_include filter_name, query.available_filters.keys 636 assert_include filter_name, query.available_filters.keys
618 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}} 637 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
619 assert_equal [3], find_issues_with_query(query).map(&:author_id).uniq.sort 638 assert_equal [3], find_issues_with_query(query).map(&:author_id).uniq.sort
620 end 639 end
621 640
622 def test_filter_on_assigned_to_custom_field 641 def test_filter_on_assigned_to_custom_field
623 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string') 642 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
624 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo') 643 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
625 644
626 query = Query.new(:name => '_') 645 query = IssueQuery.new(:name => '_')
627 filter_name = "assigned_to.cf_#{field.id}" 646 filter_name = "assigned_to.cf_#{field.id}"
628 assert_include filter_name, query.available_filters.keys 647 assert_include filter_name, query.available_filters.keys
629 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}} 648 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
630 assert_equal [3], find_issues_with_query(query).map(&:assigned_to_id).uniq.sort 649 assert_equal [3], find_issues_with_query(query).map(&:assigned_to_id).uniq.sort
631 end 650 end
632 651
633 def test_filter_on_fixed_version_custom_field 652 def test_filter_on_fixed_version_custom_field
634 field = VersionCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string') 653 field = VersionCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
635 CustomValue.create!(:custom_field => field, :customized => Version.find(2), :value => 'Foo') 654 CustomValue.create!(:custom_field => field, :customized => Version.find(2), :value => 'Foo')
636 655
637 query = Query.new(:name => '_') 656 query = IssueQuery.new(:name => '_')
638 filter_name = "fixed_version.cf_#{field.id}" 657 filter_name = "fixed_version.cf_#{field.id}"
639 assert_include filter_name, query.available_filters.keys 658 assert_include filter_name, query.available_filters.keys
640 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}} 659 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
641 assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort 660 assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort
642 end 661 end
644 def test_filter_on_relations_with_a_specific_issue 663 def test_filter_on_relations_with_a_specific_issue
645 IssueRelation.delete_all 664 IssueRelation.delete_all
646 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) 665 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
647 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1)) 666 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
648 667
649 query = Query.new(:name => '_') 668 query = IssueQuery.new(:name => '_')
650 query.filters = {"relates" => {:operator => '=', :values => ['1']}} 669 query.filters = {"relates" => {:operator => '=', :values => ['1']}}
651 assert_equal [2, 3], find_issues_with_query(query).map(&:id).sort 670 assert_equal [2, 3], find_issues_with_query(query).map(&:id).sort
652 671
653 query = Query.new(:name => '_') 672 query = IssueQuery.new(:name => '_')
654 query.filters = {"relates" => {:operator => '=', :values => ['2']}} 673 query.filters = {"relates" => {:operator => '=', :values => ['2']}}
655 assert_equal [1], find_issues_with_query(query).map(&:id).sort 674 assert_equal [1], find_issues_with_query(query).map(&:id).sort
656 end 675 end
657 676
658 def test_filter_on_relations_with_any_issues_in_a_project 677 def test_filter_on_relations_with_any_issues_in_a_project
661 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first) 680 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
662 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(2).issues.first) 681 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(2).issues.first)
663 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first) 682 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
664 end 683 end
665 684
666 query = Query.new(:name => '_') 685 query = IssueQuery.new(:name => '_')
667 query.filters = {"relates" => {:operator => '=p', :values => ['2']}} 686 query.filters = {"relates" => {:operator => '=p', :values => ['2']}}
668 assert_equal [1, 2], find_issues_with_query(query).map(&:id).sort 687 assert_equal [1, 2], find_issues_with_query(query).map(&:id).sort
669 688
670 query = Query.new(:name => '_') 689 query = IssueQuery.new(:name => '_')
671 query.filters = {"relates" => {:operator => '=p', :values => ['3']}} 690 query.filters = {"relates" => {:operator => '=p', :values => ['3']}}
672 assert_equal [1], find_issues_with_query(query).map(&:id).sort 691 assert_equal [1], find_issues_with_query(query).map(&:id).sort
673 692
674 query = Query.new(:name => '_') 693 query = IssueQuery.new(:name => '_')
675 query.filters = {"relates" => {:operator => '=p', :values => ['4']}} 694 query.filters = {"relates" => {:operator => '=p', :values => ['4']}}
676 assert_equal [], find_issues_with_query(query).map(&:id).sort 695 assert_equal [], find_issues_with_query(query).map(&:id).sort
677 end 696 end
678 697
679 def test_filter_on_relations_with_any_issues_not_in_a_project 698 def test_filter_on_relations_with_any_issues_not_in_a_project
682 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first) 701 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
683 #IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first) 702 #IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first)
684 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first) 703 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
685 end 704 end
686 705
687 query = Query.new(:name => '_') 706 query = IssueQuery.new(:name => '_')
688 query.filters = {"relates" => {:operator => '=!p', :values => ['1']}} 707 query.filters = {"relates" => {:operator => '=!p', :values => ['1']}}
689 assert_equal [1], find_issues_with_query(query).map(&:id).sort 708 assert_equal [1], find_issues_with_query(query).map(&:id).sort
690 end 709 end
691 710
692 def test_filter_on_relations_with_no_issues_in_a_project 711 def test_filter_on_relations_with_no_issues_in_a_project
695 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first) 714 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
696 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first) 715 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first)
697 IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3)) 716 IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3))
698 end 717 end
699 718
700 query = Query.new(:name => '_') 719 query = IssueQuery.new(:name => '_')
701 query.filters = {"relates" => {:operator => '!p', :values => ['2']}} 720 query.filters = {"relates" => {:operator => '!p', :values => ['2']}}
702 ids = find_issues_with_query(query).map(&:id).sort 721 ids = find_issues_with_query(query).map(&:id).sort
703 assert_include 2, ids 722 assert_include 2, ids
704 assert_not_include 1, ids 723 assert_not_include 1, ids
705 assert_not_include 3, ids 724 assert_not_include 3, ids
708 def test_filter_on_relations_with_no_issues 727 def test_filter_on_relations_with_no_issues
709 IssueRelation.delete_all 728 IssueRelation.delete_all
710 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) 729 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
711 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1)) 730 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
712 731
713 query = Query.new(:name => '_') 732 query = IssueQuery.new(:name => '_')
714 query.filters = {"relates" => {:operator => '!*', :values => ['']}} 733 query.filters = {"relates" => {:operator => '!*', :values => ['']}}
715 ids = find_issues_with_query(query).map(&:id) 734 ids = find_issues_with_query(query).map(&:id)
716 assert_equal [], ids & [1, 2, 3] 735 assert_equal [], ids & [1, 2, 3]
717 assert_include 4, ids 736 assert_include 4, ids
718 end 737 end
720 def test_filter_on_relations_with_any_issues 739 def test_filter_on_relations_with_any_issues
721 IssueRelation.delete_all 740 IssueRelation.delete_all
722 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) 741 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
723 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1)) 742 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
724 743
725 query = Query.new(:name => '_') 744 query = IssueQuery.new(:name => '_')
726 query.filters = {"relates" => {:operator => '*', :values => ['']}} 745 query.filters = {"relates" => {:operator => '*', :values => ['']}}
727 assert_equal [1, 2, 3], find_issues_with_query(query).map(&:id).sort 746 assert_equal [1, 2, 3], find_issues_with_query(query).map(&:id).sort
728 end 747 end
729 748
730 def test_statement_should_be_nil_with_no_filters 749 def test_statement_should_be_nil_with_no_filters
731 q = Query.new(:name => '_') 750 q = IssueQuery.new(:name => '_')
732 q.filters = {} 751 q.filters = {}
733 752
734 assert q.valid? 753 assert q.valid?
735 assert_nil q.statement 754 assert_nil q.statement
736 end 755 end
737 756
738 def test_default_columns 757 def test_default_columns
739 q = Query.new 758 q = IssueQuery.new
740 assert q.columns.any? 759 assert q.columns.any?
741 assert q.inline_columns.any? 760 assert q.inline_columns.any?
742 assert q.block_columns.empty? 761 assert q.block_columns.empty?
743 end 762 end
744 763
745 def test_set_column_names 764 def test_set_column_names
746 q = Query.new 765 q = IssueQuery.new
747 q.column_names = ['tracker', :subject, '', 'unknonw_column'] 766 q.column_names = ['tracker', :subject, '', 'unknonw_column']
748 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name} 767 assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
749 c = q.columns.first 768 end
750 assert q.has_column?(c) 769
770 def test_has_column_should_accept_a_column_name
771 q = IssueQuery.new
772 q.column_names = ['tracker', :subject]
773 assert q.has_column?(:tracker)
774 assert !q.has_column?(:category)
775 end
776
777 def test_has_column_should_accept_a_column
778 q = IssueQuery.new
779 q.column_names = ['tracker', :subject]
780
781 tracker_column = q.available_columns.detect {|c| c.name==:tracker}
782 assert_kind_of QueryColumn, tracker_column
783 category_column = q.available_columns.detect {|c| c.name==:category}
784 assert_kind_of QueryColumn, category_column
785
786 assert q.has_column?(tracker_column)
787 assert !q.has_column?(category_column)
751 end 788 end
752 789
753 def test_inline_and_block_columns 790 def test_inline_and_block_columns
754 q = Query.new 791 q = IssueQuery.new
755 q.column_names = ['subject', 'description', 'tracker'] 792 q.column_names = ['subject', 'description', 'tracker']
756 793
757 assert_equal [:subject, :tracker], q.inline_columns.map(&:name) 794 assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
758 assert_equal [:description], q.block_columns.map(&:name) 795 assert_equal [:description], q.block_columns.map(&:name)
759 end 796 end
760 797
761 def test_custom_field_columns_should_be_inline 798 def test_custom_field_columns_should_be_inline
762 q = Query.new 799 q = IssueQuery.new
763 columns = q.available_columns.select {|column| column.is_a? QueryCustomFieldColumn} 800 columns = q.available_columns.select {|column| column.is_a? QueryCustomFieldColumn}
764 assert columns.any? 801 assert columns.any?
765 assert_nil columns.detect {|column| !column.inline?} 802 assert_nil columns.detect {|column| !column.inline?}
766 end 803 end
767 804
768 def test_query_should_preload_spent_hours 805 def test_query_should_preload_spent_hours
769 q = Query.new(:name => '_', :column_names => [:subject, :spent_hours]) 806 q = IssueQuery.new(:name => '_', :column_names => [:subject, :spent_hours])
770 assert q.has_column?(:spent_hours) 807 assert q.has_column?(:spent_hours)
771 issues = q.issues 808 issues = q.issues
772 assert_not_nil issues.first.instance_variable_get("@spent_hours") 809 assert_not_nil issues.first.instance_variable_get("@spent_hours")
773 end 810 end
774 811
775 def test_groupable_columns_should_include_custom_fields 812 def test_groupable_columns_should_include_custom_fields
776 q = Query.new 813 q = IssueQuery.new
777 column = q.groupable_columns.detect {|c| c.name == :cf_1} 814 column = q.groupable_columns.detect {|c| c.name == :cf_1}
778 assert_not_nil column 815 assert_not_nil column
779 assert_kind_of QueryCustomFieldColumn, column 816 assert_kind_of QueryCustomFieldColumn, column
780 end 817 end
781 818
782 def test_groupable_columns_should_not_include_multi_custom_fields 819 def test_groupable_columns_should_not_include_multi_custom_fields
783 field = CustomField.find(1) 820 field = CustomField.find(1)
784 field.update_attribute :multiple, true 821 field.update_attribute :multiple, true
785 822
786 q = Query.new 823 q = IssueQuery.new
787 column = q.groupable_columns.detect {|c| c.name == :cf_1} 824 column = q.groupable_columns.detect {|c| c.name == :cf_1}
788 assert_nil column 825 assert_nil column
789 end 826 end
790 827
791 def test_groupable_columns_should_include_user_custom_fields 828 def test_groupable_columns_should_include_user_custom_fields
792 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'user') 829 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'user')
793 830
794 q = Query.new 831 q = IssueQuery.new
795 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym} 832 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
796 end 833 end
797 834
798 def test_groupable_columns_should_include_version_custom_fields 835 def test_groupable_columns_should_include_version_custom_fields
799 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'version') 836 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'version')
800 837
801 q = Query.new 838 q = IssueQuery.new
802 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym} 839 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
803 end 840 end
804 841
805 def test_grouped_with_valid_column 842 def test_grouped_with_valid_column
806 q = Query.new(:group_by => 'status') 843 q = IssueQuery.new(:group_by => 'status')
807 assert q.grouped? 844 assert q.grouped?
808 assert_not_nil q.group_by_column 845 assert_not_nil q.group_by_column
809 assert_equal :status, q.group_by_column.name 846 assert_equal :status, q.group_by_column.name
810 assert_not_nil q.group_by_statement 847 assert_not_nil q.group_by_statement
811 assert_equal 'status', q.group_by_statement 848 assert_equal 'status', q.group_by_statement
812 end 849 end
813 850
814 def test_grouped_with_invalid_column 851 def test_grouped_with_invalid_column
815 q = Query.new(:group_by => 'foo') 852 q = IssueQuery.new(:group_by => 'foo')
816 assert !q.grouped? 853 assert !q.grouped?
817 assert_nil q.group_by_column 854 assert_nil q.group_by_column
818 assert_nil q.group_by_statement 855 assert_nil q.group_by_statement
819 end 856 end
820 857
821 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting 858 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
822 with_settings :user_format => 'lastname_coma_firstname' do 859 with_settings :user_format => 'lastname_coma_firstname' do
823 q = Query.new 860 q = IssueQuery.new
824 assert q.sortable_columns.has_key?('assigned_to') 861 assert q.sortable_columns.has_key?('assigned_to')
825 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to'] 862 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
826 end 863 end
827 end 864 end
828 865
829 def test_sortable_columns_should_sort_authors_according_to_user_format_setting 866 def test_sortable_columns_should_sort_authors_according_to_user_format_setting
830 with_settings :user_format => 'lastname_coma_firstname' do 867 with_settings :user_format => 'lastname_coma_firstname' do
831 q = Query.new 868 q = IssueQuery.new
832 assert q.sortable_columns.has_key?('author') 869 assert q.sortable_columns.has_key?('author')
833 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author'] 870 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
834 end 871 end
835 end 872 end
836 873
837 def test_sortable_columns_should_include_custom_field 874 def test_sortable_columns_should_include_custom_field
838 q = Query.new 875 q = IssueQuery.new
839 assert q.sortable_columns['cf_1'] 876 assert q.sortable_columns['cf_1']
840 end 877 end
841 878
842 def test_sortable_columns_should_not_include_multi_custom_field 879 def test_sortable_columns_should_not_include_multi_custom_field
843 field = CustomField.find(1) 880 field = CustomField.find(1)
844 field.update_attribute :multiple, true 881 field.update_attribute :multiple, true
845 882
846 q = Query.new 883 q = IssueQuery.new
847 assert !q.sortable_columns['cf_1'] 884 assert !q.sortable_columns['cf_1']
848 end 885 end
849 886
850 def test_default_sort 887 def test_default_sort
851 q = Query.new 888 q = IssueQuery.new
852 assert_equal [], q.sort_criteria 889 assert_equal [], q.sort_criteria
853 end 890 end
854 891
855 def test_set_sort_criteria_with_hash 892 def test_set_sort_criteria_with_hash
856 q = Query.new 893 q = IssueQuery.new
857 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']} 894 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
858 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria 895 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
859 end 896 end
860 897
861 def test_set_sort_criteria_with_array 898 def test_set_sort_criteria_with_array
862 q = Query.new 899 q = IssueQuery.new
863 q.sort_criteria = [['priority', 'desc'], 'tracker'] 900 q.sort_criteria = [['priority', 'desc'], 'tracker']
864 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria 901 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
865 end 902 end
866 903
867 def test_create_query_with_sort 904 def test_create_query_with_sort
868 q = Query.new(:name => 'Sorted') 905 q = IssueQuery.new(:name => 'Sorted')
869 q.sort_criteria = [['priority', 'desc'], 'tracker'] 906 q.sort_criteria = [['priority', 'desc'], 'tracker']
870 assert q.save 907 assert q.save
871 q.reload 908 q.reload
872 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria 909 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
873 end 910 end
874 911
875 def test_sort_by_string_custom_field_asc 912 def test_sort_by_string_custom_field_asc
876 q = Query.new 913 q = IssueQuery.new
877 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } 914 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
878 assert c 915 assert c
879 assert c.sortable 916 assert c.sortable
880 issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where( 917 issues = q.issues(:order => "#{c.sortable} ASC")
881 q.statement
882 ).order("#{c.sortable} ASC").all
883 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} 918 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
884 assert !values.empty? 919 assert !values.empty?
885 assert_equal values.sort, values 920 assert_equal values.sort, values
886 end 921 end
887 922
888 def test_sort_by_string_custom_field_desc 923 def test_sort_by_string_custom_field_desc
889 q = Query.new 924 q = IssueQuery.new
890 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' } 925 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
891 assert c 926 assert c
892 assert c.sortable 927 assert c.sortable
893 issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where( 928 issues = q.issues(:order => "#{c.sortable} DESC")
894 q.statement
895 ).order("#{c.sortable} DESC").all
896 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} 929 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
897 assert !values.empty? 930 assert !values.empty?
898 assert_equal values.sort.reverse, values 931 assert_equal values.sort.reverse, values
899 end 932 end
900 933
901 def test_sort_by_float_custom_field_asc 934 def test_sort_by_float_custom_field_asc
902 q = Query.new 935 q = IssueQuery.new
903 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' } 936 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
904 assert c 937 assert c
905 assert c.sortable 938 assert c.sortable
906 issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where( 939 issues = q.issues(:order => "#{c.sortable} ASC")
907 q.statement
908 ).order("#{c.sortable} ASC").all
909 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact 940 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
910 assert !values.empty? 941 assert !values.empty?
911 assert_equal values.sort, values 942 assert_equal values.sort, values
912 end 943 end
913 944
914 def test_invalid_query_should_raise_query_statement_invalid_error 945 def test_invalid_query_should_raise_query_statement_invalid_error
915 q = Query.new 946 q = IssueQuery.new
916 assert_raise Query::StatementInvalid do 947 assert_raise Query::StatementInvalid do
917 q.issues(:conditions => "foo = 1") 948 q.issues(:conditions => "foo = 1")
918 end 949 end
919 end 950 end
920 951
921 def test_issue_count 952 def test_issue_count
922 q = Query.new(:name => '_') 953 q = IssueQuery.new(:name => '_')
923 issue_count = q.issue_count 954 issue_count = q.issue_count
924 assert_equal q.issues.size, issue_count 955 assert_equal q.issues.size, issue_count
925 end 956 end
926 957
927 def test_issue_count_with_archived_issues 958 def test_issue_count_with_archived_issues
933 964
934 test_issue_count 965 test_issue_count
935 end 966 end
936 967
937 def test_issue_count_by_association_group 968 def test_issue_count_by_association_group
938 q = Query.new(:name => '_', :group_by => 'assigned_to') 969 q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
939 count_by_group = q.issue_count_by_group 970 count_by_group = q.issue_count_by_group
940 assert_kind_of Hash, count_by_group 971 assert_kind_of Hash, count_by_group
941 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort 972 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
942 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq 973 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
943 assert count_by_group.has_key?(User.find(3)) 974 assert count_by_group.has_key?(User.find(3))
944 end 975 end
945 976
946 def test_issue_count_by_list_custom_field_group 977 def test_issue_count_by_list_custom_field_group
947 q = Query.new(:name => '_', :group_by => 'cf_1') 978 q = IssueQuery.new(:name => '_', :group_by => 'cf_1')
948 count_by_group = q.issue_count_by_group 979 count_by_group = q.issue_count_by_group
949 assert_kind_of Hash, count_by_group 980 assert_kind_of Hash, count_by_group
950 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort 981 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
951 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq 982 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
952 assert count_by_group.has_key?('MySQL') 983 assert count_by_group.has_key?('MySQL')
953 end 984 end
954 985
955 def test_issue_count_by_date_custom_field_group 986 def test_issue_count_by_date_custom_field_group
956 q = Query.new(:name => '_', :group_by => 'cf_8') 987 q = IssueQuery.new(:name => '_', :group_by => 'cf_8')
957 count_by_group = q.issue_count_by_group 988 count_by_group = q.issue_count_by_group
958 assert_kind_of Hash, count_by_group 989 assert_kind_of Hash, count_by_group
959 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort 990 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
960 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq 991 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
961 end 992 end
962 993
963 def test_issue_count_with_nil_group_only 994 def test_issue_count_with_nil_group_only
964 Issue.update_all("assigned_to_id = NULL") 995 Issue.update_all("assigned_to_id = NULL")
965 996
966 q = Query.new(:name => '_', :group_by => 'assigned_to') 997 q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
967 count_by_group = q.issue_count_by_group 998 count_by_group = q.issue_count_by_group
968 assert_kind_of Hash, count_by_group 999 assert_kind_of Hash, count_by_group
969 assert_equal 1, count_by_group.keys.size 1000 assert_equal 1, count_by_group.keys.size
970 assert_nil count_by_group.keys.first 1001 assert_nil count_by_group.keys.first
971 end 1002 end
972 1003
973 def test_issue_ids 1004 def test_issue_ids
974 q = Query.new(:name => '_') 1005 q = IssueQuery.new(:name => '_')
975 order = "issues.subject, issues.id" 1006 order = "issues.subject, issues.id"
976 issues = q.issues(:order => order) 1007 issues = q.issues(:order => order)
977 assert_equal issues.map(&:id), q.issue_ids(:order => order) 1008 assert_equal issues.map(&:id), q.issue_ids(:order => order)
978 end 1009 end
979 1010
980 def test_label_for 1011 def test_label_for
981 set_language_if_valid 'en' 1012 set_language_if_valid 'en'
982 q = Query.new 1013 q = IssueQuery.new
983 assert_equal 'Assignee', q.label_for('assigned_to_id') 1014 assert_equal 'Assignee', q.label_for('assigned_to_id')
984 end 1015 end
985 1016
986 def test_label_for_fr 1017 def test_label_for_fr
987 set_language_if_valid 'fr' 1018 set_language_if_valid 'fr'
988 q = Query.new 1019 q = IssueQuery.new
989 s = "Assign\xc3\xa9 \xc3\xa0" 1020 s = "Assign\xc3\xa9 \xc3\xa0"
990 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding) 1021 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
991 assert_equal s, q.label_for('assigned_to_id') 1022 assert_equal s, q.label_for('assigned_to_id')
992 end 1023 end
993 1024
995 admin = User.find(1) 1026 admin = User.find(1)
996 manager = User.find(2) 1027 manager = User.find(2)
997 developer = User.find(3) 1028 developer = User.find(3)
998 1029
999 # Public query on project 1 1030 # Public query on project 1
1000 q = Query.find(1) 1031 q = IssueQuery.find(1)
1001 assert q.editable_by?(admin) 1032 assert q.editable_by?(admin)
1002 assert q.editable_by?(manager) 1033 assert q.editable_by?(manager)
1003 assert !q.editable_by?(developer) 1034 assert !q.editable_by?(developer)
1004 1035
1005 # Private query on project 1 1036 # Private query on project 1
1006 q = Query.find(2) 1037 q = IssueQuery.find(2)
1007 assert q.editable_by?(admin) 1038 assert q.editable_by?(admin)
1008 assert !q.editable_by?(manager) 1039 assert !q.editable_by?(manager)
1009 assert q.editable_by?(developer) 1040 assert q.editable_by?(developer)
1010 1041
1011 # Private query for all projects 1042 # Private query for all projects
1012 q = Query.find(3) 1043 q = IssueQuery.find(3)
1013 assert q.editable_by?(admin) 1044 assert q.editable_by?(admin)
1014 assert !q.editable_by?(manager) 1045 assert !q.editable_by?(manager)
1015 assert q.editable_by?(developer) 1046 assert q.editable_by?(developer)
1016 1047
1017 # Public query for all projects 1048 # Public query for all projects
1018 q = Query.find(4) 1049 q = IssueQuery.find(4)
1019 assert q.editable_by?(admin) 1050 assert q.editable_by?(admin)
1020 assert !q.editable_by?(manager) 1051 assert !q.editable_by?(manager)
1021 assert !q.editable_by?(developer) 1052 assert !q.editable_by?(developer)
1022 end 1053 end
1023 1054
1024 def test_visible_scope 1055 def test_visible_scope
1025 query_ids = Query.visible(User.anonymous).map(&:id) 1056 query_ids = IssueQuery.visible(User.anonymous).map(&:id)
1026 1057
1027 assert query_ids.include?(1), 'public query on public project was not visible' 1058 assert query_ids.include?(1), 'public query on public project was not visible'
1028 assert query_ids.include?(4), 'public query for all projects was not visible' 1059 assert query_ids.include?(4), 'public query for all projects was not visible'
1029 assert !query_ids.include?(2), 'private query on public project was visible' 1060 assert !query_ids.include?(2), 'private query on public project was visible'
1030 assert !query_ids.include?(3), 'private query for all projects was visible' 1061 assert !query_ids.include?(3), 'private query for all projects was visible'
1031 assert !query_ids.include?(7), 'public query on private project was visible' 1062 assert !query_ids.include?(7), 'public query on private project was visible'
1032 end 1063 end
1033 1064
1034 context "#available_filters" do 1065 test "#available_filters should include users of visible projects in cross-project view" do
1035 setup do 1066 users = IssueQuery.new.available_filters["assigned_to_id"]
1036 @query = Query.new(:name => "_") 1067 assert_not_nil users
1037 end 1068 assert users[:values].map{|u|u[1]}.include?("3")
1038 1069 end
1039 should "include users of visible projects in cross-project view" do 1070
1040 users = @query.available_filters["assigned_to_id"] 1071 test "#available_filters should include users of subprojects" do
1041 assert_not_nil users 1072 user1 = User.generate!
1042 assert users[:values].map{|u|u[1]}.include?("3") 1073 user2 = User.generate!
1043 end 1074 project = Project.find(1)
1044 1075 Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
1045 should "include users of subprojects" do 1076
1046 user1 = User.generate! 1077 users = IssueQuery.new(:project => project).available_filters["assigned_to_id"]
1047 user2 = User.generate! 1078 assert_not_nil users
1048 project = Project.find(1) 1079 assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
1049 Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1]) 1080 assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
1050 @query.project = project 1081 end
1051 1082
1052 users = @query.available_filters["assigned_to_id"] 1083 test "#available_filters should include visible projects in cross-project view" do
1053 assert_not_nil users 1084 projects = IssueQuery.new.available_filters["project_id"]
1054 assert users[:values].map{|u|u[1]}.include?(user1.id.to_s) 1085 assert_not_nil projects
1055 assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s) 1086 assert projects[:values].map{|u|u[1]}.include?("1")
1056 end 1087 end
1057 1088
1058 should "include visible projects in cross-project view" do 1089 test "#available_filters should include 'member_of_group' filter" do
1059 projects = @query.available_filters["project_id"] 1090 query = IssueQuery.new
1060 assert_not_nil projects 1091 assert query.available_filters.keys.include?("member_of_group")
1061 assert projects[:values].map{|u|u[1]}.include?("1") 1092 assert_equal :list_optional, query.available_filters["member_of_group"][:type]
1062 end 1093 assert query.available_filters["member_of_group"][:values].present?
1063 1094 assert_equal Group.all.sort.map {|g| [g.name, g.id.to_s]},
1064 context "'member_of_group' filter" do 1095 query.available_filters["member_of_group"][:values].sort
1065 should "be present" do 1096 end
1066 assert @query.available_filters.keys.include?("member_of_group") 1097
1067 end 1098 test "#available_filters should include 'assigned_to_role' filter" do
1068 1099 query = IssueQuery.new
1069 should "be an optional list" do 1100 assert query.available_filters.keys.include?("assigned_to_role")
1070 assert_equal :list_optional, @query.available_filters["member_of_group"][:type] 1101 assert_equal :list_optional, query.available_filters["assigned_to_role"][:type]
1071 end 1102
1072 1103 assert query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
1073 should "have a list of the groups as values" do 1104 assert query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
1074 Group.destroy_all # No fixtures 1105 assert query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
1075 group1 = Group.generate!.reload 1106
1076 group2 = Group.generate!.reload 1107 assert ! query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
1077 1108 assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
1078 expected_group_list = [
1079 [group1.name, group1.id.to_s],
1080 [group2.name, group2.id.to_s]
1081 ]
1082 assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
1083 end
1084
1085 end
1086
1087 context "'assigned_to_role' filter" do
1088 should "be present" do
1089 assert @query.available_filters.keys.include?("assigned_to_role")
1090 end
1091
1092 should "be an optional list" do
1093 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
1094 end
1095
1096 should "have a list of the Roles as values" do
1097 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
1098 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
1099 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
1100 end
1101
1102 should "not include the built in Roles as values" do
1103 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
1104 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
1105 end
1106
1107 end
1108
1109 end 1109 end
1110 1110
1111 context "#statement" do 1111 context "#statement" do
1112 context "with 'member_of_group' filter" do 1112 context "with 'member_of_group' filter" do
1113 setup do 1113 setup do
1125 @group2.users << @user_in_group2 1125 @group2.users << @user_in_group2
1126 1126
1127 end 1127 end
1128 1128
1129 should "search assigned to for users in the group" do 1129 should "search assigned to for users in the group" do
1130 @query = Query.new(:name => '_') 1130 @query = IssueQuery.new(:name => '_')
1131 @query.add_filter('member_of_group', '=', [@group.id.to_s]) 1131 @query.add_filter('member_of_group', '=', [@group.id.to_s])
1132 1132
1133 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')" 1133 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@group.id}')"
1134 assert_find_issues_with_query_is_successful @query 1134 assert_find_issues_with_query_is_successful @query
1135 end 1135 end
1136 1136
1137 should "search not assigned to any group member (none)" do 1137 should "search not assigned to any group member (none)" do
1138 @query = Query.new(:name => '_') 1138 @query = IssueQuery.new(:name => '_')
1139 @query.add_filter('member_of_group', '!*', ['']) 1139 @query.add_filter('member_of_group', '!*', [''])
1140 1140
1141 # Users not in a group 1141 # Users not in a group
1142 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}')" 1142 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}','#{@group.id}','#{@group2.id}')"
1143 assert_find_issues_with_query_is_successful @query 1143 assert_find_issues_with_query_is_successful @query
1144 end 1144 end
1145 1145
1146 should "search assigned to any group member (all)" do 1146 should "search assigned to any group member (all)" do
1147 @query = Query.new(:name => '_') 1147 @query = IssueQuery.new(:name => '_')
1148 @query.add_filter('member_of_group', '*', ['']) 1148 @query.add_filter('member_of_group', '*', [''])
1149 1149
1150 # Only users in a group 1150 # Only users in a group
1151 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}')" 1151 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}','#{@group.id}','#{@group2.id}')"
1152 assert_find_issues_with_query_is_successful @query 1152 assert_find_issues_with_query_is_successful @query
1153 end 1153 end
1154 1154
1155 should "return an empty set with = empty group" do 1155 should "return an empty set with = empty group" do
1156 @empty_group = Group.generate! 1156 @empty_group = Group.generate!
1157 @query = Query.new(:name => '_') 1157 @query = IssueQuery.new(:name => '_')
1158 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s]) 1158 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
1159 1159
1160 assert_equal [], find_issues_with_query(@query) 1160 assert_equal [], find_issues_with_query(@query)
1161 end 1161 end
1162 1162
1163 should "return issues with ! empty group" do 1163 should "return issues with ! empty group" do
1164 @empty_group = Group.generate! 1164 @empty_group = Group.generate!
1165 @query = Query.new(:name => '_') 1165 @query = IssueQuery.new(:name => '_')
1166 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s]) 1166 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
1167 1167
1168 assert_find_issues_with_query_is_successful @query 1168 assert_find_issues_with_query_is_successful @query
1169 end 1169 end
1170 end 1170 end
1189 @issue4 = Issue.generate!(:project => @project, :assigned_to_id => @guest.id) 1189 @issue4 = Issue.generate!(:project => @project, :assigned_to_id => @guest.id)
1190 @issue5 = Issue.generate!(:project => @project) 1190 @issue5 = Issue.generate!(:project => @project)
1191 end 1191 end
1192 1192
1193 should "search assigned to for users with the Role" do 1193 should "search assigned to for users with the Role" do
1194 @query = Query.new(:name => '_', :project => @project) 1194 @query = IssueQuery.new(:name => '_', :project => @project)
1195 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s]) 1195 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
1196 1196
1197 assert_query_result [@issue1, @issue3], @query 1197 assert_query_result [@issue1, @issue3], @query
1198 end 1198 end
1199 1199
1200 should "search assigned to for users with the Role on the issue project" do 1200 should "search assigned to for users with the Role on the issue project" do
1201 other_project = Project.generate! 1201 other_project = Project.generate!
1202 User.add_to_project(@developer, other_project, @manager_role) 1202 User.add_to_project(@developer, other_project, @manager_role)
1203 1203
1204 @query = Query.new(:name => '_', :project => @project) 1204 @query = IssueQuery.new(:name => '_', :project => @project)
1205 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s]) 1205 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
1206 1206
1207 assert_query_result [@issue1, @issue3], @query 1207 assert_query_result [@issue1, @issue3], @query
1208 end 1208 end
1209 1209
1210 should "return an empty set with empty role" do 1210 should "return an empty set with empty role" do
1211 @empty_role = Role.generate! 1211 @empty_role = Role.generate!
1212 @query = Query.new(:name => '_', :project => @project) 1212 @query = IssueQuery.new(:name => '_', :project => @project)
1213 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s]) 1213 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
1214 1214
1215 assert_query_result [], @query 1215 assert_query_result [], @query
1216 end 1216 end
1217 1217
1218 should "search assigned to for users without the Role" do 1218 should "search assigned to for users without the Role" do
1219 @query = Query.new(:name => '_', :project => @project) 1219 @query = IssueQuery.new(:name => '_', :project => @project)
1220 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s]) 1220 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
1221 1221
1222 assert_query_result [@issue2, @issue4, @issue5], @query 1222 assert_query_result [@issue2, @issue4, @issue5], @query
1223 end 1223 end
1224 1224
1225 should "search assigned to for users not assigned to any Role (none)" do 1225 should "search assigned to for users not assigned to any Role (none)" do
1226 @query = Query.new(:name => '_', :project => @project) 1226 @query = IssueQuery.new(:name => '_', :project => @project)
1227 @query.add_filter('assigned_to_role', '!*', ['']) 1227 @query.add_filter('assigned_to_role', '!*', [''])
1228 1228
1229 assert_query_result [@issue4, @issue5], @query 1229 assert_query_result [@issue4, @issue5], @query
1230 end 1230 end
1231 1231
1232 should "search assigned to for users assigned to any Role (all)" do 1232 should "search assigned to for users assigned to any Role (all)" do
1233 @query = Query.new(:name => '_', :project => @project) 1233 @query = IssueQuery.new(:name => '_', :project => @project)
1234 @query.add_filter('assigned_to_role', '*', ['']) 1234 @query.add_filter('assigned_to_role', '*', [''])
1235 1235
1236 assert_query_result [@issue1, @issue2, @issue3], @query 1236 assert_query_result [@issue1, @issue2, @issue3], @query
1237 end 1237 end
1238 1238
1239 should "return issues with ! empty role" do 1239 should "return issues with ! empty role" do
1240 @empty_role = Role.generate! 1240 @empty_role = Role.generate!
1241 @query = Query.new(:name => '_', :project => @project) 1241 @query = IssueQuery.new(:name => '_', :project => @project)
1242 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s]) 1242 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
1243 1243
1244 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query 1244 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
1245 end 1245 end
1246 end 1246 end
1247 end 1247 end
1248
1249 end 1248 end