##// END OF EJS Templates
add missing groups_users fixture to unit issue test...
Toshi MARUYAMA -
r8516:1054237d821b
parent child
Show More
@@ -1,1191 +1,1192
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 IssueTest < ActiveSupport::TestCase
21 21 fixtures :projects, :users, :members, :member_roles, :roles,
22 :groups_users,
22 23 :trackers, :projects_trackers,
23 24 :enabled_modules,
24 25 :versions,
25 26 :issue_statuses, :issue_categories, :issue_relations, :workflows,
26 27 :enumerations,
27 28 :issues,
28 29 :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
29 30 :time_entries
30 31
31 32 def test_create
32 33 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
33 34 :status_id => 1, :priority => IssuePriority.all.first,
34 35 :subject => 'test_create',
35 36 :description => 'IssueTest#test_create', :estimated_hours => '1:30')
36 37 assert issue.save
37 38 issue.reload
38 39 assert_equal 1.5, issue.estimated_hours
39 40 end
40 41
41 42 def test_create_minimal
42 43 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
43 44 :status_id => 1, :priority => IssuePriority.all.first,
44 45 :subject => 'test_create')
45 46 assert issue.save
46 47 assert issue.description.nil?
47 48 end
48 49
49 50 def test_create_with_required_custom_field
50 51 field = IssueCustomField.find_by_name('Database')
51 52 field.update_attribute(:is_required, true)
52 53
53 54 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
54 55 :status_id => 1, :subject => 'test_create',
55 56 :description => 'IssueTest#test_create_with_required_custom_field')
56 57 assert issue.available_custom_fields.include?(field)
57 58 # No value for the custom field
58 59 assert !issue.save
59 60 assert_equal I18n.translate('activerecord.errors.messages.invalid'),
60 61 issue.errors[:custom_values].to_s
61 62 # Blank value
62 63 issue.custom_field_values = { field.id => '' }
63 64 assert !issue.save
64 65 assert_equal I18n.translate('activerecord.errors.messages.invalid'),
65 66 issue.errors[:custom_values].to_s
66 67 # Invalid value
67 68 issue.custom_field_values = { field.id => 'SQLServer' }
68 69 assert !issue.save
69 70 assert_equal I18n.translate('activerecord.errors.messages.invalid'),
70 71 issue.errors[:custom_values].to_s
71 72 # Valid value
72 73 issue.custom_field_values = { field.id => 'PostgreSQL' }
73 74 assert issue.save
74 75 issue.reload
75 76 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
76 77 end
77 78
78 79 def test_create_with_group_assignment
79 80 with_settings :issue_group_assignment => '1' do
80 81 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
81 82 :subject => 'Group assignment',
82 83 :assigned_to_id => 11).save
83 84 issue = Issue.first(:order => 'id DESC')
84 85 assert_kind_of Group, issue.assigned_to
85 86 assert_equal Group.find(11), issue.assigned_to
86 87 end
87 88 end
88 89
89 90 def assert_visibility_match(user, issues)
90 91 assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
91 92 end
92 93
93 94 def test_visible_scope_for_anonymous
94 95 # Anonymous user should see issues of public projects only
95 96 issues = Issue.visible(User.anonymous).all
96 97 assert issues.any?
97 98 assert_nil issues.detect {|issue| !issue.project.is_public?}
98 99 assert_nil issues.detect {|issue| issue.is_private?}
99 100 assert_visibility_match User.anonymous, issues
100 101 end
101 102
102 103 def test_visible_scope_for_anonymous_with_own_issues_visibility
103 104 Role.anonymous.update_attribute :issues_visibility, 'own'
104 105 Issue.create!(:project_id => 1, :tracker_id => 1,
105 106 :author_id => User.anonymous.id,
106 107 :subject => 'Issue by anonymous')
107 108
108 109 issues = Issue.visible(User.anonymous).all
109 110 assert issues.any?
110 111 assert_nil issues.detect {|issue| issue.author != User.anonymous}
111 112 assert_visibility_match User.anonymous, issues
112 113 end
113 114
114 115 def test_visible_scope_for_anonymous_without_view_issues_permissions
115 116 # Anonymous user should not see issues without permission
116 117 Role.anonymous.remove_permission!(:view_issues)
117 118 issues = Issue.visible(User.anonymous).all
118 119 assert issues.empty?
119 120 assert_visibility_match User.anonymous, issues
120 121 end
121 122
122 123 def test_visible_scope_for_non_member
123 124 user = User.find(9)
124 125 assert user.projects.empty?
125 126 # Non member user should see issues of public projects only
126 127 issues = Issue.visible(user).all
127 128 assert issues.any?
128 129 assert_nil issues.detect {|issue| !issue.project.is_public?}
129 130 assert_nil issues.detect {|issue| issue.is_private?}
130 131 assert_visibility_match user, issues
131 132 end
132 133
133 134 def test_visible_scope_for_non_member_with_own_issues_visibility
134 135 Role.non_member.update_attribute :issues_visibility, 'own'
135 136 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
136 137 user = User.find(9)
137 138
138 139 issues = Issue.visible(user).all
139 140 assert issues.any?
140 141 assert_nil issues.detect {|issue| issue.author != user}
141 142 assert_visibility_match user, issues
142 143 end
143 144
144 145 def test_visible_scope_for_non_member_without_view_issues_permissions
145 146 # Non member user should not see issues without permission
146 147 Role.non_member.remove_permission!(:view_issues)
147 148 user = User.find(9)
148 149 assert user.projects.empty?
149 150 issues = Issue.visible(user).all
150 151 assert issues.empty?
151 152 assert_visibility_match user, issues
152 153 end
153 154
154 155 def test_visible_scope_for_member
155 156 user = User.find(9)
156 157 # User should see issues of projects for which he has view_issues permissions only
157 158 Role.non_member.remove_permission!(:view_issues)
158 159 Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
159 160 issues = Issue.visible(user).all
160 161 assert issues.any?
161 162 assert_nil issues.detect {|issue| issue.project_id != 3}
162 163 assert_nil issues.detect {|issue| issue.is_private?}
163 164 assert_visibility_match user, issues
164 165 end
165 166
166 167 def test_visible_scope_for_member_with_groups_should_return_assigned_issues
167 168 user = User.find(8)
168 169 assert user.groups.any?
169 170 Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2])
170 171 Role.non_member.remove_permission!(:view_issues)
171 172
172 173 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
173 174 :status_id => 1, :priority => IssuePriority.all.first,
174 175 :subject => 'Assignment test',
175 176 :assigned_to => user.groups.first,
176 177 :is_private => true)
177 178
178 179 Role.find(2).update_attribute :issues_visibility, 'default'
179 180 issues = Issue.visible(User.find(8)).all
180 181 assert issues.any?
181 182 assert issues.include?(issue)
182 183
183 184 Role.find(2).update_attribute :issues_visibility, 'own'
184 185 issues = Issue.visible(User.find(8)).all
185 186 assert issues.any?
186 187 assert issues.include?(issue)
187 188 end
188 189
189 190 def test_visible_scope_for_admin
190 191 user = User.find(1)
191 192 user.members.each(&:destroy)
192 193 assert user.projects.empty?
193 194 issues = Issue.visible(user).all
194 195 assert issues.any?
195 196 # Admin should see issues on private projects that he does not belong to
196 197 assert issues.detect {|issue| !issue.project.is_public?}
197 198 # Admin should see private issues of other users
198 199 assert issues.detect {|issue| issue.is_private? && issue.author != user}
199 200 assert_visibility_match user, issues
200 201 end
201 202
202 203 def test_visible_scope_with_project
203 204 project = Project.find(1)
204 205 issues = Issue.visible(User.find(2), :project => project).all
205 206 projects = issues.collect(&:project).uniq
206 207 assert_equal 1, projects.size
207 208 assert_equal project, projects.first
208 209 end
209 210
210 211 def test_visible_scope_with_project_and_subprojects
211 212 project = Project.find(1)
212 213 issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
213 214 projects = issues.collect(&:project).uniq
214 215 assert projects.size > 1
215 216 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
216 217 end
217 218
218 219 def test_visible_and_nested_set_scopes
219 220 assert_equal 0, Issue.find(1).descendants.visible.all.size
220 221 end
221 222
222 223 def test_open_scope
223 224 issues = Issue.open.all
224 225 assert_nil issues.detect(&:closed?)
225 226 end
226 227
227 228 def test_open_scope_with_arg
228 229 issues = Issue.open(false).all
229 230 assert_equal issues, issues.select(&:closed?)
230 231 end
231 232
232 233 def test_errors_full_messages_should_include_custom_fields_errors
233 234 field = IssueCustomField.find_by_name('Database')
234 235
235 236 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
236 237 :status_id => 1, :subject => 'test_create',
237 238 :description => 'IssueTest#test_create_with_required_custom_field')
238 239 assert issue.available_custom_fields.include?(field)
239 240 # Invalid value
240 241 issue.custom_field_values = { field.id => 'SQLServer' }
241 242
242 243 assert !issue.valid?
243 244 assert_equal 1, issue.errors.full_messages.size
244 245 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}",
245 246 issue.errors.full_messages.first
246 247 end
247 248
248 249 def test_update_issue_with_required_custom_field
249 250 field = IssueCustomField.find_by_name('Database')
250 251 field.update_attribute(:is_required, true)
251 252
252 253 issue = Issue.find(1)
253 254 assert_nil issue.custom_value_for(field)
254 255 assert issue.available_custom_fields.include?(field)
255 256 # No change to custom values, issue can be saved
256 257 assert issue.save
257 258 # Blank value
258 259 issue.custom_field_values = { field.id => '' }
259 260 assert !issue.save
260 261 # Valid value
261 262 issue.custom_field_values = { field.id => 'PostgreSQL' }
262 263 assert issue.save
263 264 issue.reload
264 265 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
265 266 end
266 267
267 268 def test_should_not_update_attributes_if_custom_fields_validation_fails
268 269 issue = Issue.find(1)
269 270 field = IssueCustomField.find_by_name('Database')
270 271 assert issue.available_custom_fields.include?(field)
271 272
272 273 issue.custom_field_values = { field.id => 'Invalid' }
273 274 issue.subject = 'Should be not be saved'
274 275 assert !issue.save
275 276
276 277 issue.reload
277 278 assert_equal "Can't print recipes", issue.subject
278 279 end
279 280
280 281 def test_should_not_recreate_custom_values_objects_on_update
281 282 field = IssueCustomField.find_by_name('Database')
282 283
283 284 issue = Issue.find(1)
284 285 issue.custom_field_values = { field.id => 'PostgreSQL' }
285 286 assert issue.save
286 287 custom_value = issue.custom_value_for(field)
287 288 issue.reload
288 289 issue.custom_field_values = { field.id => 'MySQL' }
289 290 assert issue.save
290 291 issue.reload
291 292 assert_equal custom_value.id, issue.custom_value_for(field).id
292 293 end
293 294
294 295 def test_should_not_update_custom_fields_on_changing_tracker_with_different_custom_fields
295 296 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => 'Test', :custom_field_values => {'2' => 'Test'})
296 297 assert !Tracker.find(2).custom_field_ids.include?(2)
297 298
298 299 issue = Issue.find(issue.id)
299 300 issue.attributes = {:tracker_id => 2, :custom_field_values => {'1' => ''}}
300 301
301 302 issue = Issue.find(issue.id)
302 303 custom_value = issue.custom_value_for(2)
303 304 assert_not_nil custom_value
304 305 assert_equal 'Test', custom_value.value
305 306 end
306 307
307 308 def test_assigning_tracker_id_should_reload_custom_fields_values
308 309 issue = Issue.new(:project => Project.find(1))
309 310 assert issue.custom_field_values.empty?
310 311 issue.tracker_id = 1
311 312 assert issue.custom_field_values.any?
312 313 end
313 314
314 315 def test_assigning_attributes_should_assign_project_and_tracker_first
315 316 seq = sequence('seq')
316 317 issue = Issue.new
317 318 issue.expects(:project_id=).in_sequence(seq)
318 319 issue.expects(:tracker_id=).in_sequence(seq)
319 320 issue.expects(:subject=).in_sequence(seq)
320 321 issue.attributes = {:tracker_id => 2, :project_id => 1, :subject => 'Test'}
321 322 end
322 323
323 324 def test_assigning_tracker_and_custom_fields_should_assign_custom_fields
324 325 attributes = ActiveSupport::OrderedHash.new
325 326 attributes['custom_field_values'] = { '1' => 'MySQL' }
326 327 attributes['tracker_id'] = '1'
327 328 issue = Issue.new(:project => Project.find(1))
328 329 issue.attributes = attributes
329 330 assert_not_nil issue.custom_value_for(1)
330 331 assert_equal 'MySQL', issue.custom_value_for(1).value
331 332 end
332 333
333 334 def test_should_update_issue_with_disabled_tracker
334 335 p = Project.find(1)
335 336 issue = Issue.find(1)
336 337
337 338 p.trackers.delete(issue.tracker)
338 339 assert !p.trackers.include?(issue.tracker)
339 340
340 341 issue.reload
341 342 issue.subject = 'New subject'
342 343 assert issue.save
343 344 end
344 345
345 346 def test_should_not_set_a_disabled_tracker
346 347 p = Project.find(1)
347 348 p.trackers.delete(Tracker.find(2))
348 349
349 350 issue = Issue.find(1)
350 351 issue.tracker_id = 2
351 352 issue.subject = 'New subject'
352 353 assert !issue.save
353 354 assert_not_nil issue.errors[:tracker_id]
354 355 end
355 356
356 357 def test_category_based_assignment
357 358 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
358 359 :status_id => 1, :priority => IssuePriority.all.first,
359 360 :subject => 'Assignment test',
360 361 :description => 'Assignment test', :category_id => 1)
361 362 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
362 363 end
363 364
364 365 def test_new_statuses_allowed_to
365 366 Workflow.delete_all
366 367
367 368 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
368 369 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
369 370 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
370 371 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
371 372 status = IssueStatus.find(1)
372 373 role = Role.find(1)
373 374 tracker = Tracker.find(1)
374 375 user = User.find(2)
375 376
376 377 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1)
377 378 assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
378 379
379 380 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user)
380 381 assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
381 382
382 383 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :assigned_to => user)
383 384 assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
384 385
385 386 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user)
386 387 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
387 388 end
388 389
389 390 def test_copy
390 391 issue = Issue.new.copy_from(1)
391 392 assert issue.copy?
392 393 assert issue.save
393 394 issue.reload
394 395 orig = Issue.find(1)
395 396 assert_equal orig.subject, issue.subject
396 397 assert_equal orig.tracker, issue.tracker
397 398 assert_equal "125", issue.custom_value_for(2).value
398 399 end
399 400
400 401 def test_copy_should_copy_status
401 402 orig = Issue.find(8)
402 403 assert orig.status != IssueStatus.default
403 404
404 405 issue = Issue.new.copy_from(orig)
405 406 assert issue.save
406 407 issue.reload
407 408 assert_equal orig.status, issue.status
408 409 end
409 410
410 411 def test_should_not_call_after_project_change_on_creation
411 412 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Test', :author_id => 1)
412 413 issue.expects(:after_project_change).never
413 414 issue.save!
414 415 end
415 416
416 417 def test_should_not_call_after_project_change_on_update
417 418 issue = Issue.find(1)
418 419 issue.project = Project.find(1)
419 420 issue.subject = 'No project change'
420 421 issue.expects(:after_project_change).never
421 422 issue.save!
422 423 end
423 424
424 425 def test_should_call_after_project_change_on_project_change
425 426 issue = Issue.find(1)
426 427 issue.project = Project.find(2)
427 428 issue.expects(:after_project_change).once
428 429 issue.save!
429 430 end
430 431
431 432 def test_should_close_duplicates
432 433 # Create 3 issues
433 434 project = Project.find(1)
434 435 issue1 = Issue.generate_for_project!(project)
435 436 issue2 = Issue.generate_for_project!(project)
436 437 issue3 = Issue.generate_for_project!(project)
437 438
438 439 # 2 is a dupe of 1
439 440 IssueRelation.create!(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
440 441 # And 3 is a dupe of 2
441 442 IssueRelation.create!(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
442 443 # And 3 is a dupe of 1 (circular duplicates)
443 444 IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
444 445
445 446 assert issue1.reload.duplicates.include?(issue2)
446 447
447 448 # Closing issue 1
448 449 issue1.init_journal(User.find(:first), "Closing issue1")
449 450 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
450 451 assert issue1.save
451 452 # 2 and 3 should be also closed
452 453 assert issue2.reload.closed?
453 454 assert issue3.reload.closed?
454 455 end
455 456
456 457 def test_should_not_close_duplicated_issue
457 458 project = Project.find(1)
458 459 issue1 = Issue.generate_for_project!(project)
459 460 issue2 = Issue.generate_for_project!(project)
460 461
461 462 # 2 is a dupe of 1
462 463 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
463 464 # 2 is a dup of 1 but 1 is not a duplicate of 2
464 465 assert !issue2.reload.duplicates.include?(issue1)
465 466
466 467 # Closing issue 2
467 468 issue2.init_journal(User.find(:first), "Closing issue2")
468 469 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
469 470 assert issue2.save
470 471 # 1 should not be also closed
471 472 assert !issue1.reload.closed?
472 473 end
473 474
474 475 def test_assignable_versions
475 476 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
476 477 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
477 478 end
478 479
479 480 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
480 481 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
481 482 assert !issue.save
482 483 assert_not_nil issue.errors[:fixed_version_id]
483 484 end
484 485
485 486 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
486 487 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
487 488 assert !issue.save
488 489 assert_not_nil issue.errors[:fixed_version_id]
489 490 end
490 491
491 492 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
492 493 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
493 494 assert issue.save
494 495 end
495 496
496 497 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
497 498 issue = Issue.find(11)
498 499 assert_equal 'closed', issue.fixed_version.status
499 500 issue.subject = 'Subject changed'
500 501 assert issue.save
501 502 end
502 503
503 504 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
504 505 issue = Issue.find(11)
505 506 issue.status_id = 1
506 507 assert !issue.save
507 508 assert_not_nil issue.errors[:base]
508 509 end
509 510
510 511 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
511 512 issue = Issue.find(11)
512 513 issue.status_id = 1
513 514 issue.fixed_version_id = 3
514 515 assert issue.save
515 516 end
516 517
517 518 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
518 519 issue = Issue.find(12)
519 520 assert_equal 'locked', issue.fixed_version.status
520 521 issue.status_id = 1
521 522 assert issue.save
522 523 end
523 524
524 525 def test_move_to_another_project_with_same_category
525 526 issue = Issue.find(1)
526 527 issue.project = Project.find(2)
527 528 assert issue.save
528 529 issue.reload
529 530 assert_equal 2, issue.project_id
530 531 # Category changes
531 532 assert_equal 4, issue.category_id
532 533 # Make sure time entries were move to the target project
533 534 assert_equal 2, issue.time_entries.first.project_id
534 535 end
535 536
536 537 def test_move_to_another_project_without_same_category
537 538 issue = Issue.find(2)
538 539 issue.project = Project.find(2)
539 540 assert issue.save
540 541 issue.reload
541 542 assert_equal 2, issue.project_id
542 543 # Category cleared
543 544 assert_nil issue.category_id
544 545 end
545 546
546 547 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
547 548 issue = Issue.find(1)
548 549 issue.update_attribute(:fixed_version_id, 1)
549 550 issue.project = Project.find(2)
550 551 assert issue.save
551 552 issue.reload
552 553 assert_equal 2, issue.project_id
553 554 # Cleared fixed_version
554 555 assert_equal nil, issue.fixed_version
555 556 end
556 557
557 558 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
558 559 issue = Issue.find(1)
559 560 issue.update_attribute(:fixed_version_id, 4)
560 561 issue.project = Project.find(5)
561 562 assert issue.save
562 563 issue.reload
563 564 assert_equal 5, issue.project_id
564 565 # Keep fixed_version
565 566 assert_equal 4, issue.fixed_version_id
566 567 end
567 568
568 569 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
569 570 issue = Issue.find(1)
570 571 issue.update_attribute(:fixed_version_id, 1)
571 572 issue.project = Project.find(5)
572 573 assert issue.save
573 574 issue.reload
574 575 assert_equal 5, issue.project_id
575 576 # Cleared fixed_version
576 577 assert_equal nil, issue.fixed_version
577 578 end
578 579
579 580 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
580 581 issue = Issue.find(1)
581 582 issue.update_attribute(:fixed_version_id, 7)
582 583 issue.project = Project.find(2)
583 584 assert issue.save
584 585 issue.reload
585 586 assert_equal 2, issue.project_id
586 587 # Keep fixed_version
587 588 assert_equal 7, issue.fixed_version_id
588 589 end
589 590
590 591 def test_move_to_another_project_with_disabled_tracker
591 592 issue = Issue.find(1)
592 593 target = Project.find(2)
593 594 target.tracker_ids = [3]
594 595 target.save
595 596 issue.project = target
596 597 assert issue.save
597 598 issue.reload
598 599 assert_equal 2, issue.project_id
599 600 assert_equal 3, issue.tracker_id
600 601 end
601 602
602 603 def test_copy_to_the_same_project
603 604 issue = Issue.find(1)
604 605 copy = issue.copy
605 606 assert_difference 'Issue.count' do
606 607 copy.save!
607 608 end
608 609 assert_kind_of Issue, copy
609 610 assert_equal issue.project, copy.project
610 611 assert_equal "125", copy.custom_value_for(2).value
611 612 end
612 613
613 614 def test_copy_to_another_project_and_tracker
614 615 issue = Issue.find(1)
615 616 copy = issue.copy(:project_id => 3, :tracker_id => 2)
616 617 assert_difference 'Issue.count' do
617 618 copy.save!
618 619 end
619 620 copy.reload
620 621 assert_kind_of Issue, copy
621 622 assert_equal Project.find(3), copy.project
622 623 assert_equal Tracker.find(2), copy.tracker
623 624 # Custom field #2 is not associated with target tracker
624 625 assert_nil copy.custom_value_for(2)
625 626 end
626 627
627 628 context "#copy" do
628 629 setup do
629 630 @issue = Issue.find(1)
630 631 end
631 632
632 633 should "not create a journal" do
633 634 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
634 635 copy.save!
635 636 assert_equal 0, copy.reload.journals.size
636 637 end
637 638
638 639 should "allow assigned_to changes" do
639 640 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
640 641 assert_equal 3, copy.assigned_to_id
641 642 end
642 643
643 644 should "allow status changes" do
644 645 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
645 646 assert_equal 2, copy.status_id
646 647 end
647 648
648 649 should "allow start date changes" do
649 650 date = Date.today
650 651 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
651 652 assert_equal date, copy.start_date
652 653 end
653 654
654 655 should "allow due date changes" do
655 656 date = Date.today
656 657 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :due_date => date)
657 658 assert_equal date, copy.due_date
658 659 end
659 660
660 661 should "set current user as author" do
661 662 User.current = User.find(9)
662 663 copy = @issue.copy(:project_id => 3, :tracker_id => 2)
663 664 assert_equal User.current, copy.author
664 665 end
665 666
666 667 should "create a journal with notes" do
667 668 date = Date.today
668 669 notes = "Notes added when copying"
669 670 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
670 671 copy.init_journal(User.current, notes)
671 672 copy.save!
672 673
673 674 assert_equal 1, copy.journals.size
674 675 journal = copy.journals.first
675 676 assert_equal 0, journal.details.size
676 677 assert_equal notes, journal.notes
677 678 end
678 679 end
679 680
680 681 def test_recipients_should_not_include_users_that_cannot_view_the_issue
681 682 issue = Issue.find(12)
682 683 assert issue.recipients.include?(issue.author.mail)
683 684 # copy the issue to a private project
684 685 copy = issue.copy(:project_id => 5, :tracker_id => 2)
685 686 # author is not a member of project anymore
686 687 assert !copy.recipients.include?(copy.author.mail)
687 688 end
688 689
689 690 def test_recipients_should_include_the_assigned_group_members
690 691 group_member = User.generate_with_protected!
691 692 group = Group.generate!
692 693 group.users << group_member
693 694
694 695 issue = Issue.find(12)
695 696 issue.assigned_to = group
696 697 assert issue.recipients.include?(group_member.mail)
697 698 end
698 699
699 700 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
700 701 user = User.find(3)
701 702 issue = Issue.find(9)
702 703 Watcher.create!(:user => user, :watchable => issue)
703 704 assert issue.watched_by?(user)
704 705 assert !issue.watcher_recipients.include?(user.mail)
705 706 end
706 707
707 708 def test_issue_destroy
708 709 Issue.find(1).destroy
709 710 assert_nil Issue.find_by_id(1)
710 711 assert_nil TimeEntry.find_by_issue_id(1)
711 712 end
712 713
713 714 def test_blocked
714 715 blocked_issue = Issue.find(9)
715 716 blocking_issue = Issue.find(10)
716 717
717 718 assert blocked_issue.blocked?
718 719 assert !blocking_issue.blocked?
719 720 end
720 721
721 722 def test_blocked_issues_dont_allow_closed_statuses
722 723 blocked_issue = Issue.find(9)
723 724
724 725 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
725 726 assert !allowed_statuses.empty?
726 727 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
727 728 assert closed_statuses.empty?
728 729 end
729 730
730 731 def test_unblocked_issues_allow_closed_statuses
731 732 blocking_issue = Issue.find(10)
732 733
733 734 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
734 735 assert !allowed_statuses.empty?
735 736 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
736 737 assert !closed_statuses.empty?
737 738 end
738 739
739 740 def test_rescheduling_an_issue_should_reschedule_following_issue
740 741 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
741 742 issue2 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
742 743 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
743 744 assert_equal issue1.due_date + 1, issue2.reload.start_date
744 745
745 746 issue1.due_date = Date.today + 5
746 747 issue1.save!
747 748 assert_equal issue1.due_date + 1, issue2.reload.start_date
748 749 end
749 750
750 751 def test_overdue
751 752 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
752 753 assert !Issue.new(:due_date => Date.today).overdue?
753 754 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
754 755 assert !Issue.new(:due_date => nil).overdue?
755 756 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
756 757 end
757 758
758 759 context "#behind_schedule?" do
759 760 should "be false if the issue has no start_date" do
760 761 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
761 762 end
762 763
763 764 should "be false if the issue has no end_date" do
764 765 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
765 766 end
766 767
767 768 should "be false if the issue has more done than it's calendar time" do
768 769 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
769 770 end
770 771
771 772 should "be true if the issue hasn't been started at all" do
772 773 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
773 774 end
774 775
775 776 should "be true if the issue has used more calendar time than it's done ratio" do
776 777 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
777 778 end
778 779 end
779 780
780 781 context "#assignable_users" do
781 782 should "be Users" do
782 783 assert_kind_of User, Issue.find(1).assignable_users.first
783 784 end
784 785
785 786 should "include the issue author" do
786 787 project = Project.find(1)
787 788 non_project_member = User.generate!
788 789 issue = Issue.generate_for_project!(project, :author => non_project_member)
789 790
790 791 assert issue.assignable_users.include?(non_project_member)
791 792 end
792 793
793 794 should "include the current assignee" do
794 795 project = Project.find(1)
795 796 user = User.generate!
796 797 issue = Issue.generate_for_project!(project, :assigned_to => user)
797 798 user.lock!
798 799
799 800 assert Issue.find(issue.id).assignable_users.include?(user)
800 801 end
801 802
802 803 should "not show the issue author twice" do
803 804 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
804 805 assert_equal 2, assignable_user_ids.length
805 806
806 807 assignable_user_ids.each do |user_id|
807 808 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
808 809 end
809 810 end
810 811
811 812 context "with issue_group_assignment" do
812 813 should "include groups" do
813 814 issue = Issue.new(:project => Project.find(2))
814 815
815 816 with_settings :issue_group_assignment => '1' do
816 817 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
817 818 assert issue.assignable_users.include?(Group.find(11))
818 819 end
819 820 end
820 821 end
821 822
822 823 context "without issue_group_assignment" do
823 824 should "not include groups" do
824 825 issue = Issue.new(:project => Project.find(2))
825 826
826 827 with_settings :issue_group_assignment => '0' do
827 828 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
828 829 assert !issue.assignable_users.include?(Group.find(11))
829 830 end
830 831 end
831 832 end
832 833 end
833 834
834 835 def test_create_should_send_email_notification
835 836 ActionMailer::Base.deliveries.clear
836 837 issue = Issue.new(:project_id => 1, :tracker_id => 1,
837 838 :author_id => 3, :status_id => 1,
838 839 :priority => IssuePriority.all.first,
839 840 :subject => 'test_create', :estimated_hours => '1:30')
840 841
841 842 assert issue.save
842 843 assert_equal 1, ActionMailer::Base.deliveries.size
843 844 end
844 845
845 846 def test_stale_issue_should_not_send_email_notification
846 847 ActionMailer::Base.deliveries.clear
847 848 issue = Issue.find(1)
848 849 stale = Issue.find(1)
849 850
850 851 issue.init_journal(User.find(1))
851 852 issue.subject = 'Subjet update'
852 853 assert issue.save
853 854 assert_equal 1, ActionMailer::Base.deliveries.size
854 855 ActionMailer::Base.deliveries.clear
855 856
856 857 stale.init_journal(User.find(1))
857 858 stale.subject = 'Another subjet update'
858 859 assert_raise ActiveRecord::StaleObjectError do
859 860 stale.save
860 861 end
861 862 assert ActionMailer::Base.deliveries.empty?
862 863 end
863 864
864 865 def test_journalized_description
865 866 IssueCustomField.delete_all
866 867
867 868 i = Issue.first
868 869 old_description = i.description
869 870 new_description = "This is the new description"
870 871
871 872 i.init_journal(User.find(2))
872 873 i.description = new_description
873 874 assert_difference 'Journal.count', 1 do
874 875 assert_difference 'JournalDetail.count', 1 do
875 876 i.save!
876 877 end
877 878 end
878 879
879 880 detail = JournalDetail.first(:order => 'id DESC')
880 881 assert_equal i, detail.journal.journalized
881 882 assert_equal 'attr', detail.property
882 883 assert_equal 'description', detail.prop_key
883 884 assert_equal old_description, detail.old_value
884 885 assert_equal new_description, detail.value
885 886 end
886 887
887 888 def test_blank_descriptions_should_not_be_journalized
888 889 IssueCustomField.delete_all
889 890 Issue.update_all("description = NULL", "id=1")
890 891
891 892 i = Issue.find(1)
892 893 i.init_journal(User.find(2))
893 894 i.subject = "blank description"
894 895 i.description = "\r\n"
895 896
896 897 assert_difference 'Journal.count', 1 do
897 898 assert_difference 'JournalDetail.count', 1 do
898 899 i.save!
899 900 end
900 901 end
901 902 end
902 903
903 904 def test_description_eol_should_be_normalized
904 905 i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
905 906 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
906 907 end
907 908
908 909 def test_saving_twice_should_not_duplicate_journal_details
909 910 i = Issue.find(:first)
910 911 i.init_journal(User.find(2), 'Some notes')
911 912 # initial changes
912 913 i.subject = 'New subject'
913 914 i.done_ratio = i.done_ratio + 10
914 915 assert_difference 'Journal.count' do
915 916 assert i.save
916 917 end
917 918 # 1 more change
918 919 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
919 920 assert_no_difference 'Journal.count' do
920 921 assert_difference 'JournalDetail.count', 1 do
921 922 i.save
922 923 end
923 924 end
924 925 # no more change
925 926 assert_no_difference 'Journal.count' do
926 927 assert_no_difference 'JournalDetail.count' do
927 928 i.save
928 929 end
929 930 end
930 931 end
931 932
932 933 def test_all_dependent_issues
933 934 IssueRelation.delete_all
934 935 assert IssueRelation.create!(:issue_from => Issue.find(1),
935 936 :issue_to => Issue.find(2),
936 937 :relation_type => IssueRelation::TYPE_PRECEDES)
937 938 assert IssueRelation.create!(:issue_from => Issue.find(2),
938 939 :issue_to => Issue.find(3),
939 940 :relation_type => IssueRelation::TYPE_PRECEDES)
940 941 assert IssueRelation.create!(:issue_from => Issue.find(3),
941 942 :issue_to => Issue.find(8),
942 943 :relation_type => IssueRelation::TYPE_PRECEDES)
943 944
944 945 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
945 946 end
946 947
947 948 def test_all_dependent_issues_with_persistent_circular_dependency
948 949 IssueRelation.delete_all
949 950 assert IssueRelation.create!(:issue_from => Issue.find(1),
950 951 :issue_to => Issue.find(2),
951 952 :relation_type => IssueRelation::TYPE_PRECEDES)
952 953 assert IssueRelation.create!(:issue_from => Issue.find(2),
953 954 :issue_to => Issue.find(3),
954 955 :relation_type => IssueRelation::TYPE_PRECEDES)
955 956 # Validation skipping
956 957 assert IssueRelation.new(:issue_from => Issue.find(3),
957 958 :issue_to => Issue.find(1),
958 959 :relation_type => IssueRelation::TYPE_PRECEDES).save(false)
959 960
960 961 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
961 962 end
962 963
963 964 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
964 965 IssueRelation.delete_all
965 966 assert IssueRelation.create!(:issue_from => Issue.find(1),
966 967 :issue_to => Issue.find(2),
967 968 :relation_type => IssueRelation::TYPE_RELATES)
968 969 assert IssueRelation.create!(:issue_from => Issue.find(2),
969 970 :issue_to => Issue.find(3),
970 971 :relation_type => IssueRelation::TYPE_RELATES)
971 972 assert IssueRelation.create!(:issue_from => Issue.find(3),
972 973 :issue_to => Issue.find(8),
973 974 :relation_type => IssueRelation::TYPE_RELATES)
974 975 # Validation skipping
975 976 assert IssueRelation.new(:issue_from => Issue.find(8),
976 977 :issue_to => Issue.find(2),
977 978 :relation_type => IssueRelation::TYPE_RELATES).save(false)
978 979 assert IssueRelation.new(:issue_from => Issue.find(3),
979 980 :issue_to => Issue.find(1),
980 981 :relation_type => IssueRelation::TYPE_RELATES).save(false)
981 982
982 983 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
983 984 end
984 985
985 986 context "#done_ratio" do
986 987 setup do
987 988 @issue = Issue.find(1)
988 989 @issue_status = IssueStatus.find(1)
989 990 @issue_status.update_attribute(:default_done_ratio, 50)
990 991 @issue2 = Issue.find(2)
991 992 @issue_status2 = IssueStatus.find(2)
992 993 @issue_status2.update_attribute(:default_done_ratio, 0)
993 994 end
994 995
995 996 teardown do
996 997 Setting.issue_done_ratio = 'issue_field'
997 998 end
998 999
999 1000 context "with Setting.issue_done_ratio using the issue_field" do
1000 1001 setup do
1001 1002 Setting.issue_done_ratio = 'issue_field'
1002 1003 end
1003 1004
1004 1005 should "read the issue's field" do
1005 1006 assert_equal 0, @issue.done_ratio
1006 1007 assert_equal 30, @issue2.done_ratio
1007 1008 end
1008 1009 end
1009 1010
1010 1011 context "with Setting.issue_done_ratio using the issue_status" do
1011 1012 setup do
1012 1013 Setting.issue_done_ratio = 'issue_status'
1013 1014 end
1014 1015
1015 1016 should "read the Issue Status's default done ratio" do
1016 1017 assert_equal 50, @issue.done_ratio
1017 1018 assert_equal 0, @issue2.done_ratio
1018 1019 end
1019 1020 end
1020 1021 end
1021 1022
1022 1023 context "#update_done_ratio_from_issue_status" do
1023 1024 setup do
1024 1025 @issue = Issue.find(1)
1025 1026 @issue_status = IssueStatus.find(1)
1026 1027 @issue_status.update_attribute(:default_done_ratio, 50)
1027 1028 @issue2 = Issue.find(2)
1028 1029 @issue_status2 = IssueStatus.find(2)
1029 1030 @issue_status2.update_attribute(:default_done_ratio, 0)
1030 1031 end
1031 1032
1032 1033 context "with Setting.issue_done_ratio using the issue_field" do
1033 1034 setup do
1034 1035 Setting.issue_done_ratio = 'issue_field'
1035 1036 end
1036 1037
1037 1038 should "not change the issue" do
1038 1039 @issue.update_done_ratio_from_issue_status
1039 1040 @issue2.update_done_ratio_from_issue_status
1040 1041
1041 1042 assert_equal 0, @issue.read_attribute(:done_ratio)
1042 1043 assert_equal 30, @issue2.read_attribute(:done_ratio)
1043 1044 end
1044 1045 end
1045 1046
1046 1047 context "with Setting.issue_done_ratio using the issue_status" do
1047 1048 setup do
1048 1049 Setting.issue_done_ratio = 'issue_status'
1049 1050 end
1050 1051
1051 1052 should "change the issue's done ratio" do
1052 1053 @issue.update_done_ratio_from_issue_status
1053 1054 @issue2.update_done_ratio_from_issue_status
1054 1055
1055 1056 assert_equal 50, @issue.read_attribute(:done_ratio)
1056 1057 assert_equal 0, @issue2.read_attribute(:done_ratio)
1057 1058 end
1058 1059 end
1059 1060 end
1060 1061
1061 1062 test "#by_tracker" do
1062 1063 User.current = User.anonymous
1063 1064 groups = Issue.by_tracker(Project.find(1))
1064 1065 assert_equal 3, groups.size
1065 1066 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1066 1067 end
1067 1068
1068 1069 test "#by_version" do
1069 1070 User.current = User.anonymous
1070 1071 groups = Issue.by_version(Project.find(1))
1071 1072 assert_equal 3, groups.size
1072 1073 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1073 1074 end
1074 1075
1075 1076 test "#by_priority" do
1076 1077 User.current = User.anonymous
1077 1078 groups = Issue.by_priority(Project.find(1))
1078 1079 assert_equal 4, groups.size
1079 1080 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1080 1081 end
1081 1082
1082 1083 test "#by_category" do
1083 1084 User.current = User.anonymous
1084 1085 groups = Issue.by_category(Project.find(1))
1085 1086 assert_equal 2, groups.size
1086 1087 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1087 1088 end
1088 1089
1089 1090 test "#by_assigned_to" do
1090 1091 User.current = User.anonymous
1091 1092 groups = Issue.by_assigned_to(Project.find(1))
1092 1093 assert_equal 2, groups.size
1093 1094 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1094 1095 end
1095 1096
1096 1097 test "#by_author" do
1097 1098 User.current = User.anonymous
1098 1099 groups = Issue.by_author(Project.find(1))
1099 1100 assert_equal 4, groups.size
1100 1101 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1101 1102 end
1102 1103
1103 1104 test "#by_subproject" do
1104 1105 User.current = User.anonymous
1105 1106 groups = Issue.by_subproject(Project.find(1))
1106 1107 # Private descendant not visible
1107 1108 assert_equal 1, groups.size
1108 1109 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1109 1110 end
1110 1111
1111 1112 context ".allowed_target_projects_on_move" do
1112 1113 should "return all active projects for admin users" do
1113 1114 User.current = User.find(1)
1114 1115 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
1115 1116 end
1116 1117
1117 1118 should "return allowed projects for non admin users" do
1118 1119 User.current = User.find(2)
1119 1120 Role.non_member.remove_permission! :move_issues
1120 1121 assert_equal 3, Issue.allowed_target_projects_on_move.size
1121 1122
1122 1123 Role.non_member.add_permission! :move_issues
1123 1124 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
1124 1125 end
1125 1126 end
1126 1127
1127 1128 def test_recently_updated_with_limit_scopes
1128 1129 #should return the last updated issue
1129 1130 assert_equal 1, Issue.recently_updated.with_limit(1).length
1130 1131 assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
1131 1132 end
1132 1133
1133 1134 def test_on_active_projects_scope
1134 1135 assert Project.find(2).archive
1135 1136
1136 1137 before = Issue.on_active_project.length
1137 1138 # test inclusion to results
1138 1139 issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
1139 1140 assert_equal before + 1, Issue.on_active_project.length
1140 1141
1141 1142 # Move to an archived project
1142 1143 issue.project = Project.find(2)
1143 1144 assert issue.save
1144 1145 assert_equal before, Issue.on_active_project.length
1145 1146 end
1146 1147
1147 1148 context "Issue#recipients" do
1148 1149 setup do
1149 1150 @project = Project.find(1)
1150 1151 @author = User.generate_with_protected!
1151 1152 @assignee = User.generate_with_protected!
1152 1153 @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
1153 1154 end
1154 1155
1155 1156 should "include project recipients" do
1156 1157 assert @project.recipients.present?
1157 1158 @project.recipients.each do |project_recipient|
1158 1159 assert @issue.recipients.include?(project_recipient)
1159 1160 end
1160 1161 end
1161 1162
1162 1163 should "include the author if the author is active" do
1163 1164 assert @issue.author, "No author set for Issue"
1164 1165 assert @issue.recipients.include?(@issue.author.mail)
1165 1166 end
1166 1167
1167 1168 should "include the assigned to user if the assigned to user is active" do
1168 1169 assert @issue.assigned_to, "No assigned_to set for Issue"
1169 1170 assert @issue.recipients.include?(@issue.assigned_to.mail)
1170 1171 end
1171 1172
1172 1173 should "not include users who opt out of all email" do
1173 1174 @author.update_attribute(:mail_notification, :none)
1174 1175
1175 1176 assert !@issue.recipients.include?(@issue.author.mail)
1176 1177 end
1177 1178
1178 1179 should "not include the issue author if they are only notified of assigned issues" do
1179 1180 @author.update_attribute(:mail_notification, :only_assigned)
1180 1181
1181 1182 assert !@issue.recipients.include?(@issue.author.mail)
1182 1183 end
1183 1184
1184 1185 should "not include the assigned user if they are only notified of owned issues" do
1185 1186 @assignee.update_attribute(:mail_notification, :only_owner)
1186 1187
1187 1188 assert !@issue.recipients.include?(@issue.assigned_to.mail)
1188 1189 end
1189 1190
1190 1191 end
1191 1192 end
General Comments 0
You need to be logged in to leave comments. Login now