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