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