##// END OF EJS Templates
Makes assertion Rails3 compatible....
Jean-Philippe Lang -
r8266:4f9f68046cd4
parent child
Show More
@@ -1,1155 +1,1159
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 ProjectTest < ActiveSupport::TestCase
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :journals, :journal_details,
23 23 :enumerations, :users, :issue_categories,
24 24 :projects_trackers,
25 25 :custom_fields,
26 26 :custom_fields_projects,
27 27 :custom_fields_trackers,
28 28 :custom_values,
29 29 :roles,
30 30 :member_roles,
31 31 :members,
32 32 :enabled_modules,
33 33 :workflows,
34 34 :versions,
35 35 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
36 36 :groups_users,
37 37 :boards,
38 38 :repositories
39 39
40 40 def setup
41 41 @ecookbook = Project.find(1)
42 42 @ecookbook_sub1 = Project.find(3)
43 43 set_tmp_attachments_directory
44 44 User.current = nil
45 45 end
46 46
47 47 should_validate_presence_of :name
48 48 should_validate_presence_of :identifier
49 49
50 50 should_validate_uniqueness_of :identifier
51 51
52 52 context "associations" do
53 53 should_have_many :members
54 54 should_have_many :users, :through => :members
55 55 should_have_many :member_principals
56 56 should_have_many :principals, :through => :member_principals
57 57 should_have_many :enabled_modules
58 58 should_have_many :issues
59 59 should_have_many :issue_changes, :through => :issues
60 60 should_have_many :versions
61 61 should_have_many :time_entries
62 62 should_have_many :queries
63 63 should_have_many :documents
64 64 should_have_many :news
65 65 should_have_many :issue_categories
66 66 should_have_many :boards
67 67 should_have_many :changesets, :through => :repository
68 68
69 69 should_have_one :repository
70 70 should_have_one :wiki
71 71
72 72 should_have_and_belong_to_many :trackers
73 73 should_have_and_belong_to_many :issue_custom_fields
74 74 end
75 75
76 76 def test_truth
77 77 assert_kind_of Project, @ecookbook
78 78 assert_equal "eCookbook", @ecookbook.name
79 79 end
80 80
81 81 def test_default_attributes
82 82 with_settings :default_projects_public => '1' do
83 83 assert_equal true, Project.new.is_public
84 84 assert_equal false, Project.new(:is_public => false).is_public
85 85 end
86 86
87 87 with_settings :default_projects_public => '0' do
88 88 assert_equal false, Project.new.is_public
89 89 assert_equal true, Project.new(:is_public => true).is_public
90 90 end
91 91
92 92 with_settings :sequential_project_identifiers => '1' do
93 93 assert !Project.new.identifier.blank?
94 94 assert Project.new(:identifier => '').identifier.blank?
95 95 end
96 96
97 97 with_settings :sequential_project_identifiers => '0' do
98 98 assert Project.new.identifier.blank?
99 99 assert !Project.new(:identifier => 'test').blank?
100 100 end
101 101
102 102 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
103 103 assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
104 104 end
105 105
106 106 assert_equal Tracker.all, Project.new.trackers
107 107 assert_equal Tracker.find(1, 3), Project.new(:tracker_ids => [1, 3]).trackers
108 108 end
109 109
110 110 def test_update
111 111 assert_equal "eCookbook", @ecookbook.name
112 112 @ecookbook.name = "eCook"
113 113 assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
114 114 @ecookbook.reload
115 115 assert_equal "eCook", @ecookbook.name
116 116 end
117 117
118 118 def test_validate_identifier
119 119 to_test = {"abc" => true,
120 120 "ab12" => true,
121 121 "ab-12" => true,
122 122 "12" => false,
123 123 "new" => false}
124 124
125 125 to_test.each do |identifier, valid|
126 126 p = Project.new
127 127 p.identifier = identifier
128 128 p.valid?
129 assert_equal valid, p.errors['identifier'].nil?
129 if valid
130 assert p.errors['identifier'].blank?, "identifier #{identifier} was not valid"
131 else
132 assert p.errors['identifier'].present?, "identifier #{identifier} was valid"
133 end
130 134 end
131 135 end
132 136
133 137 def test_members_should_be_active_users
134 138 Project.all.each do |project|
135 139 assert_nil project.members.detect {|m| !(m.user.is_a?(User) && m.user.active?) }
136 140 end
137 141 end
138 142
139 143 def test_users_should_be_active_users
140 144 Project.all.each do |project|
141 145 assert_nil project.users.detect {|u| !(u.is_a?(User) && u.active?) }
142 146 end
143 147 end
144 148
145 149 def test_archive
146 150 user = @ecookbook.members.first.user
147 151 @ecookbook.archive
148 152 @ecookbook.reload
149 153
150 154 assert !@ecookbook.active?
151 155 assert @ecookbook.archived?
152 156 assert !user.projects.include?(@ecookbook)
153 157 # Subproject are also archived
154 158 assert !@ecookbook.children.empty?
155 159 assert @ecookbook.descendants.active.empty?
156 160 end
157 161
158 162 def test_archive_should_fail_if_versions_are_used_by_non_descendant_projects
159 163 # Assign an issue of a project to a version of a child project
160 164 Issue.find(4).update_attribute :fixed_version_id, 4
161 165
162 166 assert_no_difference "Project.count(:all, :conditions => 'status = #{Project::STATUS_ARCHIVED}')" do
163 167 assert_equal false, @ecookbook.archive
164 168 end
165 169 @ecookbook.reload
166 170 assert @ecookbook.active?
167 171 end
168 172
169 173 def test_unarchive
170 174 user = @ecookbook.members.first.user
171 175 @ecookbook.archive
172 176 # A subproject of an archived project can not be unarchived
173 177 assert !@ecookbook_sub1.unarchive
174 178
175 179 # Unarchive project
176 180 assert @ecookbook.unarchive
177 181 @ecookbook.reload
178 182 assert @ecookbook.active?
179 183 assert !@ecookbook.archived?
180 184 assert user.projects.include?(@ecookbook)
181 185 # Subproject can now be unarchived
182 186 @ecookbook_sub1.reload
183 187 assert @ecookbook_sub1.unarchive
184 188 end
185 189
186 190 def test_destroy
187 191 # 2 active members
188 192 assert_equal 2, @ecookbook.members.size
189 193 # and 1 is locked
190 194 assert_equal 3, Member.find(:all, :conditions => ['project_id = ?', @ecookbook.id]).size
191 195 # some boards
192 196 assert @ecookbook.boards.any?
193 197
194 198 @ecookbook.destroy
195 199 # make sure that the project non longer exists
196 200 assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
197 201 # make sure related data was removed
198 202 assert_nil Member.first(:conditions => {:project_id => @ecookbook.id})
199 203 assert_nil Board.first(:conditions => {:project_id => @ecookbook.id})
200 204 assert_nil Issue.first(:conditions => {:project_id => @ecookbook.id})
201 205 end
202 206
203 207 def test_destroying_root_projects_should_clear_data
204 208 Project.roots.each do |root|
205 209 root.destroy
206 210 end
207 211
208 212 assert_equal 0, Project.count, "Projects were not deleted: #{Project.all.inspect}"
209 213 assert_equal 0, Member.count, "Members were not deleted: #{Member.all.inspect}"
210 214 assert_equal 0, MemberRole.count
211 215 assert_equal 0, Issue.count
212 216 assert_equal 0, Journal.count
213 217 assert_equal 0, JournalDetail.count
214 218 assert_equal 0, Attachment.count
215 219 assert_equal 0, EnabledModule.count
216 220 assert_equal 0, IssueCategory.count
217 221 assert_equal 0, IssueRelation.count
218 222 assert_equal 0, Board.count
219 223 assert_equal 0, Message.count
220 224 assert_equal 0, News.count
221 225 assert_equal 0, Query.count(:conditions => "project_id IS NOT NULL")
222 226 assert_equal 0, Repository.count
223 227 assert_equal 0, Changeset.count
224 228 assert_equal 0, Change.count
225 229 assert_equal 0, Comment.count
226 230 assert_equal 0, TimeEntry.count
227 231 assert_equal 0, Version.count
228 232 assert_equal 0, Watcher.count
229 233 assert_equal 0, Wiki.count
230 234 assert_equal 0, WikiPage.count
231 235 assert_equal 0, WikiContent.count
232 236 assert_equal 0, WikiContent::Version.count
233 237 assert_equal 0, Project.connection.select_all("SELECT * FROM projects_trackers").size
234 238 assert_equal 0, Project.connection.select_all("SELECT * FROM custom_fields_projects").size
235 239 assert_equal 0, CustomValue.count(:conditions => {:customized_type => ['Project', 'Issue', 'TimeEntry', 'Version']})
236 240 end
237 241
238 242 def test_move_an_orphan_project_to_a_root_project
239 243 sub = Project.find(2)
240 244 sub.set_parent! @ecookbook
241 245 assert_equal @ecookbook.id, sub.parent.id
242 246 @ecookbook.reload
243 247 assert_equal 4, @ecookbook.children.size
244 248 end
245 249
246 250 def test_move_an_orphan_project_to_a_subproject
247 251 sub = Project.find(2)
248 252 assert sub.set_parent!(@ecookbook_sub1)
249 253 end
250 254
251 255 def test_move_a_root_project_to_a_project
252 256 sub = @ecookbook
253 257 assert sub.set_parent!(Project.find(2))
254 258 end
255 259
256 260 def test_should_not_move_a_project_to_its_children
257 261 sub = @ecookbook
258 262 assert !(sub.set_parent!(Project.find(3)))
259 263 end
260 264
261 265 def test_set_parent_should_add_roots_in_alphabetical_order
262 266 ProjectCustomField.delete_all
263 267 Project.delete_all
264 268 Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(nil)
265 269 Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(nil)
266 270 Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(nil)
267 271 Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(nil)
268 272
269 273 assert_equal 4, Project.count
270 274 assert_equal Project.all.sort_by(&:name), Project.all.sort_by(&:lft)
271 275 end
272 276
273 277 def test_set_parent_should_add_children_in_alphabetical_order
274 278 ProjectCustomField.delete_all
275 279 parent = Project.create!(:name => 'Parent', :identifier => 'parent')
276 280 Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(parent)
277 281 Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(parent)
278 282 Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(parent)
279 283 Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(parent)
280 284
281 285 parent.reload
282 286 assert_equal 4, parent.children.size
283 287 assert_equal parent.children.all.sort_by(&:name), parent.children.all
284 288 end
285 289
286 290 def test_rebuild_should_sort_children_alphabetically
287 291 ProjectCustomField.delete_all
288 292 parent = Project.create!(:name => 'Parent', :identifier => 'parent')
289 293 Project.create!(:name => 'Project C', :identifier => 'project-c').move_to_child_of(parent)
290 294 Project.create!(:name => 'Project B', :identifier => 'project-b').move_to_child_of(parent)
291 295 Project.create!(:name => 'Project D', :identifier => 'project-d').move_to_child_of(parent)
292 296 Project.create!(:name => 'Project A', :identifier => 'project-a').move_to_child_of(parent)
293 297
294 298 Project.update_all("lft = NULL, rgt = NULL")
295 299 Project.rebuild!
296 300
297 301 parent.reload
298 302 assert_equal 4, parent.children.size
299 303 assert_equal parent.children.all.sort_by(&:name), parent.children.all
300 304 end
301 305
302 306
303 307 def test_set_parent_should_update_issue_fixed_version_associations_when_a_fixed_version_is_moved_out_of_the_hierarchy
304 308 # Parent issue with a hierarchy project's fixed version
305 309 parent_issue = Issue.find(1)
306 310 parent_issue.update_attribute(:fixed_version_id, 4)
307 311 parent_issue.reload
308 312 assert_equal 4, parent_issue.fixed_version_id
309 313
310 314 # Should keep fixed versions for the issues
311 315 issue_with_local_fixed_version = Issue.find(5)
312 316 issue_with_local_fixed_version.update_attribute(:fixed_version_id, 4)
313 317 issue_with_local_fixed_version.reload
314 318 assert_equal 4, issue_with_local_fixed_version.fixed_version_id
315 319
316 320 # Local issue with hierarchy fixed_version
317 321 issue_with_hierarchy_fixed_version = Issue.find(13)
318 322 issue_with_hierarchy_fixed_version.update_attribute(:fixed_version_id, 6)
319 323 issue_with_hierarchy_fixed_version.reload
320 324 assert_equal 6, issue_with_hierarchy_fixed_version.fixed_version_id
321 325
322 326 # Move project out of the issue's hierarchy
323 327 moved_project = Project.find(3)
324 328 moved_project.set_parent!(Project.find(2))
325 329 parent_issue.reload
326 330 issue_with_local_fixed_version.reload
327 331 issue_with_hierarchy_fixed_version.reload
328 332
329 333 assert_equal 4, issue_with_local_fixed_version.fixed_version_id, "Fixed version was not keep on an issue local to the moved project"
330 334 assert_equal nil, issue_with_hierarchy_fixed_version.fixed_version_id, "Fixed version is still set after moving the Project out of the hierarchy where the version is defined in"
331 335 assert_equal nil, parent_issue.fixed_version_id, "Fixed version is still set after moving the Version out of the hierarchy for the issue."
332 336 end
333 337
334 338 def test_parent
335 339 p = Project.find(6).parent
336 340 assert p.is_a?(Project)
337 341 assert_equal 5, p.id
338 342 end
339 343
340 344 def test_ancestors
341 345 a = Project.find(6).ancestors
342 346 assert a.first.is_a?(Project)
343 347 assert_equal [1, 5], a.collect(&:id)
344 348 end
345 349
346 350 def test_root
347 351 r = Project.find(6).root
348 352 assert r.is_a?(Project)
349 353 assert_equal 1, r.id
350 354 end
351 355
352 356 def test_children
353 357 c = Project.find(1).children
354 358 assert c.first.is_a?(Project)
355 359 assert_equal [5, 3, 4], c.collect(&:id)
356 360 end
357 361
358 362 def test_descendants
359 363 d = Project.find(1).descendants
360 364 assert d.first.is_a?(Project)
361 365 assert_equal [5, 6, 3, 4], d.collect(&:id)
362 366 end
363 367
364 368 def test_allowed_parents_should_be_empty_for_non_member_user
365 369 Role.non_member.add_permission!(:add_project)
366 370 user = User.find(9)
367 371 assert user.memberships.empty?
368 372 User.current = user
369 373 assert Project.new.allowed_parents.compact.empty?
370 374 end
371 375
372 376 def test_allowed_parents_with_add_subprojects_permission
373 377 Role.find(1).remove_permission!(:add_project)
374 378 Role.find(1).add_permission!(:add_subprojects)
375 379 User.current = User.find(2)
376 380 # new project
377 381 assert !Project.new.allowed_parents.include?(nil)
378 382 assert Project.new.allowed_parents.include?(Project.find(1))
379 383 # existing root project
380 384 assert Project.find(1).allowed_parents.include?(nil)
381 385 # existing child
382 386 assert Project.find(3).allowed_parents.include?(Project.find(1))
383 387 assert !Project.find(3).allowed_parents.include?(nil)
384 388 end
385 389
386 390 def test_allowed_parents_with_add_project_permission
387 391 Role.find(1).add_permission!(:add_project)
388 392 Role.find(1).remove_permission!(:add_subprojects)
389 393 User.current = User.find(2)
390 394 # new project
391 395 assert Project.new.allowed_parents.include?(nil)
392 396 assert !Project.new.allowed_parents.include?(Project.find(1))
393 397 # existing root project
394 398 assert Project.find(1).allowed_parents.include?(nil)
395 399 # existing child
396 400 assert Project.find(3).allowed_parents.include?(Project.find(1))
397 401 assert Project.find(3).allowed_parents.include?(nil)
398 402 end
399 403
400 404 def test_allowed_parents_with_add_project_and_subprojects_permission
401 405 Role.find(1).add_permission!(:add_project)
402 406 Role.find(1).add_permission!(:add_subprojects)
403 407 User.current = User.find(2)
404 408 # new project
405 409 assert Project.new.allowed_parents.include?(nil)
406 410 assert Project.new.allowed_parents.include?(Project.find(1))
407 411 # existing root project
408 412 assert Project.find(1).allowed_parents.include?(nil)
409 413 # existing child
410 414 assert Project.find(3).allowed_parents.include?(Project.find(1))
411 415 assert Project.find(3).allowed_parents.include?(nil)
412 416 end
413 417
414 418 def test_users_by_role
415 419 users_by_role = Project.find(1).users_by_role
416 420 assert_kind_of Hash, users_by_role
417 421 role = Role.find(1)
418 422 assert_kind_of Array, users_by_role[role]
419 423 assert users_by_role[role].include?(User.find(2))
420 424 end
421 425
422 426 def test_rolled_up_trackers
423 427 parent = Project.find(1)
424 428 parent.trackers = Tracker.find([1,2])
425 429 child = parent.children.find(3)
426 430
427 431 assert_equal [1, 2], parent.tracker_ids
428 432 assert_equal [2, 3], child.trackers.collect(&:id)
429 433
430 434 assert_kind_of Tracker, parent.rolled_up_trackers.first
431 435 assert_equal Tracker.find(1), parent.rolled_up_trackers.first
432 436
433 437 assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id)
434 438 assert_equal [2, 3], child.rolled_up_trackers.collect(&:id)
435 439 end
436 440
437 441 def test_rolled_up_trackers_should_ignore_archived_subprojects
438 442 parent = Project.find(1)
439 443 parent.trackers = Tracker.find([1,2])
440 444 child = parent.children.find(3)
441 445 child.trackers = Tracker.find([1,3])
442 446 parent.children.each(&:archive)
443 447
444 448 assert_equal [1,2], parent.rolled_up_trackers.collect(&:id)
445 449 end
446 450
447 451 context "#rolled_up_versions" do
448 452 setup do
449 453 @project = Project.generate!
450 454 @parent_version_1 = Version.generate!(:project => @project)
451 455 @parent_version_2 = Version.generate!(:project => @project)
452 456 end
453 457
454 458 should "include the versions for the current project" do
455 459 assert_same_elements [@parent_version_1, @parent_version_2], @project.rolled_up_versions
456 460 end
457 461
458 462 should "include versions for a subproject" do
459 463 @subproject = Project.generate!
460 464 @subproject.set_parent!(@project)
461 465 @subproject_version = Version.generate!(:project => @subproject)
462 466
463 467 assert_same_elements [
464 468 @parent_version_1,
465 469 @parent_version_2,
466 470 @subproject_version
467 471 ], @project.rolled_up_versions
468 472 end
469 473
470 474 should "include versions for a sub-subproject" do
471 475 @subproject = Project.generate!
472 476 @subproject.set_parent!(@project)
473 477 @sub_subproject = Project.generate!
474 478 @sub_subproject.set_parent!(@subproject)
475 479 @sub_subproject_version = Version.generate!(:project => @sub_subproject)
476 480
477 481 @project.reload
478 482
479 483 assert_same_elements [
480 484 @parent_version_1,
481 485 @parent_version_2,
482 486 @sub_subproject_version
483 487 ], @project.rolled_up_versions
484 488 end
485 489
486 490 should "only check active projects" do
487 491 @subproject = Project.generate!
488 492 @subproject.set_parent!(@project)
489 493 @subproject_version = Version.generate!(:project => @subproject)
490 494 assert @subproject.archive
491 495
492 496 @project.reload
493 497
494 498 assert !@subproject.active?
495 499 assert_same_elements [@parent_version_1, @parent_version_2], @project.rolled_up_versions
496 500 end
497 501 end
498 502
499 503 def test_shared_versions_none_sharing
500 504 p = Project.find(5)
501 505 v = Version.create!(:name => 'none_sharing', :project => p, :sharing => 'none')
502 506 assert p.shared_versions.include?(v)
503 507 assert !p.children.first.shared_versions.include?(v)
504 508 assert !p.root.shared_versions.include?(v)
505 509 assert !p.siblings.first.shared_versions.include?(v)
506 510 assert !p.root.siblings.first.shared_versions.include?(v)
507 511 end
508 512
509 513 def test_shared_versions_descendants_sharing
510 514 p = Project.find(5)
511 515 v = Version.create!(:name => 'descendants_sharing', :project => p, :sharing => 'descendants')
512 516 assert p.shared_versions.include?(v)
513 517 assert p.children.first.shared_versions.include?(v)
514 518 assert !p.root.shared_versions.include?(v)
515 519 assert !p.siblings.first.shared_versions.include?(v)
516 520 assert !p.root.siblings.first.shared_versions.include?(v)
517 521 end
518 522
519 523 def test_shared_versions_hierarchy_sharing
520 524 p = Project.find(5)
521 525 v = Version.create!(:name => 'hierarchy_sharing', :project => p, :sharing => 'hierarchy')
522 526 assert p.shared_versions.include?(v)
523 527 assert p.children.first.shared_versions.include?(v)
524 528 assert p.root.shared_versions.include?(v)
525 529 assert !p.siblings.first.shared_versions.include?(v)
526 530 assert !p.root.siblings.first.shared_versions.include?(v)
527 531 end
528 532
529 533 def test_shared_versions_tree_sharing
530 534 p = Project.find(5)
531 535 v = Version.create!(:name => 'tree_sharing', :project => p, :sharing => 'tree')
532 536 assert p.shared_versions.include?(v)
533 537 assert p.children.first.shared_versions.include?(v)
534 538 assert p.root.shared_versions.include?(v)
535 539 assert p.siblings.first.shared_versions.include?(v)
536 540 assert !p.root.siblings.first.shared_versions.include?(v)
537 541 end
538 542
539 543 def test_shared_versions_system_sharing
540 544 p = Project.find(5)
541 545 v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
542 546 assert p.shared_versions.include?(v)
543 547 assert p.children.first.shared_versions.include?(v)
544 548 assert p.root.shared_versions.include?(v)
545 549 assert p.siblings.first.shared_versions.include?(v)
546 550 assert p.root.siblings.first.shared_versions.include?(v)
547 551 end
548 552
549 553 def test_shared_versions
550 554 parent = Project.find(1)
551 555 child = parent.children.find(3)
552 556 private_child = parent.children.find(5)
553 557
554 558 assert_equal [1,2,3], parent.version_ids.sort
555 559 assert_equal [4], child.version_ids
556 560 assert_equal [6], private_child.version_ids
557 561 assert_equal [7], Version.find_all_by_sharing('system').collect(&:id)
558 562
559 563 assert_equal 6, parent.shared_versions.size
560 564 parent.shared_versions.each do |version|
561 565 assert_kind_of Version, version
562 566 end
563 567
564 568 assert_equal [1,2,3,4,6,7], parent.shared_versions.collect(&:id).sort
565 569 end
566 570
567 571 def test_shared_versions_should_ignore_archived_subprojects
568 572 parent = Project.find(1)
569 573 child = parent.children.find(3)
570 574 child.archive
571 575 parent.reload
572 576
573 577 assert_equal [1,2,3], parent.version_ids.sort
574 578 assert_equal [4], child.version_ids
575 579 assert !parent.shared_versions.collect(&:id).include?(4)
576 580 end
577 581
578 582 def test_shared_versions_visible_to_user
579 583 user = User.find(3)
580 584 parent = Project.find(1)
581 585 child = parent.children.find(5)
582 586
583 587 assert_equal [1,2,3], parent.version_ids.sort
584 588 assert_equal [6], child.version_ids
585 589
586 590 versions = parent.shared_versions.visible(user)
587 591
588 592 assert_equal 4, versions.size
589 593 versions.each do |version|
590 594 assert_kind_of Version, version
591 595 end
592 596
593 597 assert !versions.collect(&:id).include?(6)
594 598 end
595 599
596 600 def test_next_identifier
597 601 ProjectCustomField.delete_all
598 602 Project.create!(:name => 'last', :identifier => 'p2008040')
599 603 assert_equal 'p2008041', Project.next_identifier
600 604 end
601 605
602 606 def test_next_identifier_first_project
603 607 Project.delete_all
604 608 assert_nil Project.next_identifier
605 609 end
606 610
607 611 def test_enabled_module_names
608 612 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
609 613 project = Project.new
610 614
611 615 project.enabled_module_names = %w(issue_tracking news)
612 616 assert_equal %w(issue_tracking news), project.enabled_module_names.sort
613 617 end
614 618 end
615 619
616 620 context "enabled_modules" do
617 621 setup do
618 622 @project = Project.find(1)
619 623 end
620 624
621 625 should "define module by names and preserve ids" do
622 626 # Remove one module
623 627 modules = @project.enabled_modules.slice(0..-2)
624 628 assert modules.any?
625 629 assert_difference 'EnabledModule.count', -1 do
626 630 @project.enabled_module_names = modules.collect(&:name)
627 631 end
628 632 @project.reload
629 633 # Ids should be preserved
630 634 assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
631 635 end
632 636
633 637 should "enable a module" do
634 638 @project.enabled_module_names = []
635 639 @project.reload
636 640 assert_equal [], @project.enabled_module_names
637 641 #with string
638 642 @project.enable_module!("issue_tracking")
639 643 assert_equal ["issue_tracking"], @project.enabled_module_names
640 644 #with symbol
641 645 @project.enable_module!(:gantt)
642 646 assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
643 647 #don't add a module twice
644 648 @project.enable_module!("issue_tracking")
645 649 assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
646 650 end
647 651
648 652 should "disable a module" do
649 653 #with string
650 654 assert @project.enabled_module_names.include?("issue_tracking")
651 655 @project.disable_module!("issue_tracking")
652 656 assert ! @project.reload.enabled_module_names.include?("issue_tracking")
653 657 #with symbol
654 658 assert @project.enabled_module_names.include?("gantt")
655 659 @project.disable_module!(:gantt)
656 660 assert ! @project.reload.enabled_module_names.include?("gantt")
657 661 #with EnabledModule object
658 662 first_module = @project.enabled_modules.first
659 663 @project.disable_module!(first_module)
660 664 assert ! @project.reload.enabled_module_names.include?(first_module.name)
661 665 end
662 666 end
663 667
664 668 def test_enabled_module_names_should_not_recreate_enabled_modules
665 669 project = Project.find(1)
666 670 # Remove one module
667 671 modules = project.enabled_modules.slice(0..-2)
668 672 assert modules.any?
669 673 assert_difference 'EnabledModule.count', -1 do
670 674 project.enabled_module_names = modules.collect(&:name)
671 675 end
672 676 project.reload
673 677 # Ids should be preserved
674 678 assert_equal project.enabled_module_ids.sort, modules.collect(&:id).sort
675 679 end
676 680
677 681 def test_copy_from_existing_project
678 682 source_project = Project.find(1)
679 683 copied_project = Project.copy_from(1)
680 684
681 685 assert copied_project
682 686 # Cleared attributes
683 687 assert copied_project.id.blank?
684 688 assert copied_project.name.blank?
685 689 assert copied_project.identifier.blank?
686 690
687 691 # Duplicated attributes
688 692 assert_equal source_project.description, copied_project.description
689 693 assert_equal source_project.enabled_modules, copied_project.enabled_modules
690 694 assert_equal source_project.trackers, copied_project.trackers
691 695
692 696 # Default attributes
693 697 assert_equal 1, copied_project.status
694 698 end
695 699
696 700 def test_activities_should_use_the_system_activities
697 701 project = Project.find(1)
698 702 assert_equal project.activities, TimeEntryActivity.find(:all, :conditions => {:active => true} )
699 703 end
700 704
701 705
702 706 def test_activities_should_use_the_project_specific_activities
703 707 project = Project.find(1)
704 708 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project})
705 709 assert overridden_activity.save!
706 710
707 711 assert project.activities.include?(overridden_activity), "Project specific Activity not found"
708 712 end
709 713
710 714 def test_activities_should_not_include_the_inactive_project_specific_activities
711 715 project = Project.find(1)
712 716 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.find(:first), :active => false})
713 717 assert overridden_activity.save!
714 718
715 719 assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity found"
716 720 end
717 721
718 722 def test_activities_should_not_include_project_specific_activities_from_other_projects
719 723 project = Project.find(1)
720 724 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(2)})
721 725 assert overridden_activity.save!
722 726
723 727 assert !project.activities.include?(overridden_activity), "Project specific Activity found on a different project"
724 728 end
725 729
726 730 def test_activities_should_handle_nils
727 731 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(1), :parent => TimeEntryActivity.find(:first)})
728 732 TimeEntryActivity.delete_all
729 733
730 734 # No activities
731 735 project = Project.find(1)
732 736 assert project.activities.empty?
733 737
734 738 # No system, one overridden
735 739 assert overridden_activity.save!
736 740 project.reload
737 741 assert_equal [overridden_activity], project.activities
738 742 end
739 743
740 744 def test_activities_should_override_system_activities_with_project_activities
741 745 project = Project.find(1)
742 746 parent_activity = TimeEntryActivity.find(:first)
743 747 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => parent_activity})
744 748 assert overridden_activity.save!
745 749
746 750 assert project.activities.include?(overridden_activity), "Project specific Activity not found"
747 751 assert !project.activities.include?(parent_activity), "System Activity found when it should have been overridden"
748 752 end
749 753
750 754 def test_activities_should_include_inactive_activities_if_specified
751 755 project = Project.find(1)
752 756 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.find(:first), :active => false})
753 757 assert overridden_activity.save!
754 758
755 759 assert project.activities(true).include?(overridden_activity), "Inactive Project specific Activity not found"
756 760 end
757 761
758 762 test 'activities should not include active System activities if the project has an override that is inactive' do
759 763 project = Project.find(1)
760 764 system_activity = TimeEntryActivity.find_by_name('Design')
761 765 assert system_activity.active?
762 766 overridden_activity = TimeEntryActivity.generate!(:project => project, :parent => system_activity, :active => false)
763 767 assert overridden_activity.save!
764 768
765 769 assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity not found"
766 770 assert !project.activities.include?(system_activity), "System activity found when the project has an inactive override"
767 771 end
768 772
769 773 def test_close_completed_versions
770 774 Version.update_all("status = 'open'")
771 775 project = Project.find(1)
772 776 assert_not_nil project.versions.detect {|v| v.completed? && v.status == 'open'}
773 777 assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
774 778 project.close_completed_versions
775 779 project.reload
776 780 assert_nil project.versions.detect {|v| v.completed? && v.status != 'closed'}
777 781 assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
778 782 end
779 783
780 784 context "Project#copy" do
781 785 setup do
782 786 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
783 787 Project.destroy_all :identifier => "copy-test"
784 788 @source_project = Project.find(2)
785 789 @project = Project.new(:name => 'Copy Test', :identifier => 'copy-test')
786 790 @project.trackers = @source_project.trackers
787 791 @project.enabled_module_names = @source_project.enabled_modules.collect(&:name)
788 792 end
789 793
790 794 should "copy issues" do
791 795 @source_project.issues << Issue.generate!(:status => IssueStatus.find_by_name('Closed'),
792 796 :subject => "copy issue status",
793 797 :tracker_id => 1,
794 798 :assigned_to_id => 2,
795 799 :project_id => @source_project.id)
796 800 assert @project.valid?
797 801 assert @project.issues.empty?
798 802 assert @project.copy(@source_project)
799 803
800 804 assert_equal @source_project.issues.size, @project.issues.size
801 805 @project.issues.each do |issue|
802 806 assert issue.valid?
803 807 assert ! issue.assigned_to.blank?
804 808 assert_equal @project, issue.project
805 809 end
806 810
807 811 copied_issue = @project.issues.first(:conditions => {:subject => "copy issue status"})
808 812 assert copied_issue
809 813 assert copied_issue.status
810 814 assert_equal "Closed", copied_issue.status.name
811 815 end
812 816
813 817 should "change the new issues to use the copied version" do
814 818 User.current = User.find(1)
815 819 assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open')
816 820 @source_project.versions << assigned_version
817 821 assert_equal 3, @source_project.versions.size
818 822 Issue.generate_for_project!(@source_project,
819 823 :fixed_version_id => assigned_version.id,
820 824 :subject => "change the new issues to use the copied version",
821 825 :tracker_id => 1,
822 826 :project_id => @source_project.id)
823 827
824 828 assert @project.copy(@source_project)
825 829 @project.reload
826 830 copied_issue = @project.issues.first(:conditions => {:subject => "change the new issues to use the copied version"})
827 831
828 832 assert copied_issue
829 833 assert copied_issue.fixed_version
830 834 assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
831 835 assert_not_equal assigned_version.id, copied_issue.fixed_version.id # Different record
832 836 end
833 837
834 838 should "copy issue relations" do
835 839 Setting.cross_project_issue_relations = '1'
836 840
837 841 second_issue = Issue.generate!(:status_id => 5,
838 842 :subject => "copy issue relation",
839 843 :tracker_id => 1,
840 844 :assigned_to_id => 2,
841 845 :project_id => @source_project.id)
842 846 source_relation = IssueRelation.generate!(:issue_from => Issue.find(4),
843 847 :issue_to => second_issue,
844 848 :relation_type => "relates")
845 849 source_relation_cross_project = IssueRelation.generate!(:issue_from => Issue.find(1),
846 850 :issue_to => second_issue,
847 851 :relation_type => "duplicates")
848 852
849 853 assert @project.copy(@source_project)
850 854 assert_equal @source_project.issues.count, @project.issues.count
851 855 copied_issue = @project.issues.find_by_subject("Issue on project 2") # Was #4
852 856 copied_second_issue = @project.issues.find_by_subject("copy issue relation")
853 857
854 858 # First issue with a relation on project
855 859 assert_equal 1, copied_issue.relations.size, "Relation not copied"
856 860 copied_relation = copied_issue.relations.first
857 861 assert_equal "relates", copied_relation.relation_type
858 862 assert_equal copied_second_issue.id, copied_relation.issue_to_id
859 863 assert_not_equal source_relation.id, copied_relation.id
860 864
861 865 # Second issue with a cross project relation
862 866 assert_equal 2, copied_second_issue.relations.size, "Relation not copied"
863 867 copied_relation = copied_second_issue.relations.select {|r| r.relation_type == 'duplicates'}.first
864 868 assert_equal "duplicates", copied_relation.relation_type
865 869 assert_equal 1, copied_relation.issue_from_id, "Cross project relation not kept"
866 870 assert_not_equal source_relation_cross_project.id, copied_relation.id
867 871 end
868 872
869 873 should "copy memberships" do
870 874 assert @project.valid?
871 875 assert @project.members.empty?
872 876 assert @project.copy(@source_project)
873 877
874 878 assert_equal @source_project.memberships.size, @project.memberships.size
875 879 @project.memberships.each do |membership|
876 880 assert membership
877 881 assert_equal @project, membership.project
878 882 end
879 883 end
880 884
881 885 should "copy memberships with groups and additional roles" do
882 886 group = Group.create!(:lastname => "Copy group")
883 887 user = User.find(7)
884 888 group.users << user
885 889 # group role
886 890 Member.create!(:project_id => @source_project.id, :principal => group, :role_ids => [2])
887 891 member = Member.find_by_user_id_and_project_id(user.id, @source_project.id)
888 892 # additional role
889 893 member.role_ids = [1]
890 894
891 895 assert @project.copy(@source_project)
892 896 member = Member.find_by_user_id_and_project_id(user.id, @project.id)
893 897 assert_not_nil member
894 898 assert_equal [1, 2], member.role_ids.sort
895 899 end
896 900
897 901 should "copy project specific queries" do
898 902 assert @project.valid?
899 903 assert @project.queries.empty?
900 904 assert @project.copy(@source_project)
901 905
902 906 assert_equal @source_project.queries.size, @project.queries.size
903 907 @project.queries.each do |query|
904 908 assert query
905 909 assert_equal @project, query.project
906 910 end
907 911 assert_equal @source_project.queries.map(&:user_id).sort, @project.queries.map(&:user_id).sort
908 912 end
909 913
910 914 should "copy versions" do
911 915 @source_project.versions << Version.generate!
912 916 @source_project.versions << Version.generate!
913 917
914 918 assert @project.versions.empty?
915 919 assert @project.copy(@source_project)
916 920
917 921 assert_equal @source_project.versions.size, @project.versions.size
918 922 @project.versions.each do |version|
919 923 assert version
920 924 assert_equal @project, version.project
921 925 end
922 926 end
923 927
924 928 should "copy wiki" do
925 929 assert_difference 'Wiki.count' do
926 930 assert @project.copy(@source_project)
927 931 end
928 932
929 933 assert @project.wiki
930 934 assert_not_equal @source_project.wiki, @project.wiki
931 935 assert_equal "Start page", @project.wiki.start_page
932 936 end
933 937
934 938 should "copy wiki pages and content with hierarchy" do
935 939 assert_difference 'WikiPage.count', @source_project.wiki.pages.size do
936 940 assert @project.copy(@source_project)
937 941 end
938 942
939 943 assert @project.wiki
940 944 assert_equal @source_project.wiki.pages.size, @project.wiki.pages.size
941 945
942 946 @project.wiki.pages.each do |wiki_page|
943 947 assert wiki_page.content
944 948 assert !@source_project.wiki.pages.include?(wiki_page)
945 949 end
946 950
947 951 parent = @project.wiki.find_page('Parent_page')
948 952 child1 = @project.wiki.find_page('Child_page_1')
949 953 child2 = @project.wiki.find_page('Child_page_2')
950 954 assert_equal parent, child1.parent
951 955 assert_equal parent, child2.parent
952 956 end
953 957
954 958 should "copy issue categories" do
955 959 assert @project.copy(@source_project)
956 960
957 961 assert_equal 2, @project.issue_categories.size
958 962 @project.issue_categories.each do |issue_category|
959 963 assert !@source_project.issue_categories.include?(issue_category)
960 964 end
961 965 end
962 966
963 967 should "copy boards" do
964 968 assert @project.copy(@source_project)
965 969
966 970 assert_equal 1, @project.boards.size
967 971 @project.boards.each do |board|
968 972 assert !@source_project.boards.include?(board)
969 973 end
970 974 end
971 975
972 976 should "change the new issues to use the copied issue categories" do
973 977 issue = Issue.find(4)
974 978 issue.update_attribute(:category_id, 3)
975 979
976 980 assert @project.copy(@source_project)
977 981
978 982 @project.issues.each do |issue|
979 983 assert issue.category
980 984 assert_equal "Stock management", issue.category.name # Same name
981 985 assert_not_equal IssueCategory.find(3), issue.category # Different record
982 986 end
983 987 end
984 988
985 989 should "limit copy with :only option" do
986 990 assert @project.members.empty?
987 991 assert @project.issue_categories.empty?
988 992 assert @source_project.issues.any?
989 993
990 994 assert @project.copy(@source_project, :only => ['members', 'issue_categories'])
991 995
992 996 assert @project.members.any?
993 997 assert @project.issue_categories.any?
994 998 assert @project.issues.empty?
995 999 end
996 1000
997 1001 end
998 1002
999 1003 context "#start_date" do
1000 1004 setup do
1001 1005 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
1002 1006 @project = Project.generate!(:identifier => 'test0')
1003 1007 @project.trackers << Tracker.generate!
1004 1008 end
1005 1009
1006 1010 should "be nil if there are no issues on the project" do
1007 1011 assert_nil @project.start_date
1008 1012 end
1009 1013
1010 1014 should "be tested when issues have no start date"
1011 1015
1012 1016 should "be the earliest start date of it's issues" do
1013 1017 early = 7.days.ago.to_date
1014 1018 Issue.generate_for_project!(@project, :start_date => Date.today)
1015 1019 Issue.generate_for_project!(@project, :start_date => early)
1016 1020
1017 1021 assert_equal early, @project.start_date
1018 1022 end
1019 1023
1020 1024 end
1021 1025
1022 1026 context "#due_date" do
1023 1027 setup do
1024 1028 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
1025 1029 @project = Project.generate!(:identifier => 'test0')
1026 1030 @project.trackers << Tracker.generate!
1027 1031 end
1028 1032
1029 1033 should "be nil if there are no issues on the project" do
1030 1034 assert_nil @project.due_date
1031 1035 end
1032 1036
1033 1037 should "be tested when issues have no due date"
1034 1038
1035 1039 should "be the latest due date of it's issues" do
1036 1040 future = 7.days.from_now.to_date
1037 1041 Issue.generate_for_project!(@project, :due_date => future)
1038 1042 Issue.generate_for_project!(@project, :due_date => Date.today)
1039 1043
1040 1044 assert_equal future, @project.due_date
1041 1045 end
1042 1046
1043 1047 should "be the latest due date of it's versions" do
1044 1048 future = 7.days.from_now.to_date
1045 1049 @project.versions << Version.generate!(:effective_date => future)
1046 1050 @project.versions << Version.generate!(:effective_date => Date.today)
1047 1051
1048 1052
1049 1053 assert_equal future, @project.due_date
1050 1054
1051 1055 end
1052 1056
1053 1057 should "pick the latest date from it's issues and versions" do
1054 1058 future = 7.days.from_now.to_date
1055 1059 far_future = 14.days.from_now.to_date
1056 1060 Issue.generate_for_project!(@project, :due_date => far_future)
1057 1061 @project.versions << Version.generate!(:effective_date => future)
1058 1062
1059 1063 assert_equal far_future, @project.due_date
1060 1064 end
1061 1065
1062 1066 end
1063 1067
1064 1068 context "Project#completed_percent" do
1065 1069 setup do
1066 1070 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
1067 1071 @project = Project.generate!(:identifier => 'test0')
1068 1072 @project.trackers << Tracker.generate!
1069 1073 end
1070 1074
1071 1075 context "no versions" do
1072 1076 should "be 100" do
1073 1077 assert_equal 100, @project.completed_percent
1074 1078 end
1075 1079 end
1076 1080
1077 1081 context "with versions" do
1078 1082 should "return 0 if the versions have no issues" do
1079 1083 Version.generate!(:project => @project)
1080 1084 Version.generate!(:project => @project)
1081 1085
1082 1086 assert_equal 0, @project.completed_percent
1083 1087 end
1084 1088
1085 1089 should "return 100 if the version has only closed issues" do
1086 1090 v1 = Version.generate!(:project => @project)
1087 1091 Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
1088 1092 v2 = Version.generate!(:project => @project)
1089 1093 Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
1090 1094
1091 1095 assert_equal 100, @project.completed_percent
1092 1096 end
1093 1097
1094 1098 should "return the averaged completed percent of the versions (not weighted)" do
1095 1099 v1 = Version.generate!(:project => @project)
1096 1100 Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
1097 1101 v2 = Version.generate!(:project => @project)
1098 1102 Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
1099 1103
1100 1104 assert_equal 50, @project.completed_percent
1101 1105 end
1102 1106
1103 1107 end
1104 1108 end
1105 1109
1106 1110 context "#notified_users" do
1107 1111 setup do
1108 1112 @project = Project.generate!
1109 1113 @role = Role.generate!
1110 1114
1111 1115 @user_with_membership_notification = User.generate!(:mail_notification => 'selected')
1112 1116 Member.generate!(:project => @project, :roles => [@role], :principal => @user_with_membership_notification, :mail_notification => true)
1113 1117
1114 1118 @all_events_user = User.generate!(:mail_notification => 'all')
1115 1119 Member.generate!(:project => @project, :roles => [@role], :principal => @all_events_user)
1116 1120
1117 1121 @no_events_user = User.generate!(:mail_notification => 'none')
1118 1122 Member.generate!(:project => @project, :roles => [@role], :principal => @no_events_user)
1119 1123
1120 1124 @only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
1121 1125 Member.generate!(:project => @project, :roles => [@role], :principal => @only_my_events_user)
1122 1126
1123 1127 @only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
1124 1128 Member.generate!(:project => @project, :roles => [@role], :principal => @only_assigned_user)
1125 1129
1126 1130 @only_owned_user = User.generate!(:mail_notification => 'only_owner')
1127 1131 Member.generate!(:project => @project, :roles => [@role], :principal => @only_owned_user)
1128 1132 end
1129 1133
1130 1134 should "include members with a mail notification" do
1131 1135 assert @project.notified_users.include?(@user_with_membership_notification)
1132 1136 end
1133 1137
1134 1138 should "include users with the 'all' notification option" do
1135 1139 assert @project.notified_users.include?(@all_events_user)
1136 1140 end
1137 1141
1138 1142 should "not include users with the 'none' notification option" do
1139 1143 assert !@project.notified_users.include?(@no_events_user)
1140 1144 end
1141 1145
1142 1146 should "not include users with the 'only_my_events' notification option" do
1143 1147 assert !@project.notified_users.include?(@only_my_events_user)
1144 1148 end
1145 1149
1146 1150 should "not include users with the 'only_assigned' notification option" do
1147 1151 assert !@project.notified_users.include?(@only_assigned_user)
1148 1152 end
1149 1153
1150 1154 should "not include users with the 'only_owner' notification option" do
1151 1155 assert !@project.notified_users.include?(@only_owned_user)
1152 1156 end
1153 1157 end
1154 1158
1155 1159 end
General Comments 0
You need to be logged in to leave comments. Login now