diff test/unit/project_test.rb @ 1115:433d4f72a19b redmine-2.2

Update to Redmine SVN revision 11137 on 2.2-stable branch
author Chris Cannam
date Mon, 07 Jan 2013 12:01:42 +0000
parents 5f33065ddc4b
children 622f24f53b42 261b3d9a4903
line wrap: on
line diff
--- a/test/unit/project_test.rb	Wed Jun 27 14:54:18 2012 +0100
+++ b/test/unit/project_test.rb	Mon Jan 07 12:01:42 2013 +0000
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
+# Copyright (C) 2006-2012  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,8 +19,13 @@
 
 class ProjectTest < ActiveSupport::TestCase
   fixtures :projects, :trackers, :issue_statuses, :issues,
+           :journals, :journal_details,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
+           :custom_fields,
+           :custom_fields_projects,
+           :custom_fields_trackers,
+           :custom_values,
            :roles,
            :member_roles,
            :members,
@@ -29,43 +34,18 @@
            :versions,
            :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
            :groups_users,
-           :boards
+           :boards, :messages,
+           :repositories,
+           :news, :comments,
+           :documents
 
   def setup
     @ecookbook = Project.find(1)
     @ecookbook_sub1 = Project.find(3)
+    set_tmp_attachments_directory
     User.current = nil
   end
 
-  should_validate_presence_of :name
-  should_validate_presence_of :identifier
-
-  should_validate_uniqueness_of :identifier
-
-  context "associations" do
-    should_have_many :members
-    should_have_many :users, :through => :members
-    should_have_many :member_principals
-    should_have_many :principals, :through => :member_principals
-    should_have_many :enabled_modules
-    should_have_many :issues
-    should_have_many :issue_changes, :through => :issues
-    should_have_many :versions
-    should_have_many :time_entries
-    should_have_many :queries
-    should_have_many :documents
-    should_have_many :news
-    should_have_many :issue_categories
-    should_have_many :boards
-    should_have_many :changesets, :through => :repository
-
-    should_have_one :repository
-    should_have_one :wiki
-
-    should_have_and_belong_to_many :trackers
-    should_have_and_belong_to_many :issue_custom_fields
-  end
-
   def test_truth
     assert_kind_of Project, @ecookbook
     assert_equal "eCookbook", @ecookbook.name
@@ -112,6 +92,7 @@
     to_test = {"abc" => true,
                "ab12" => true,
                "ab-12" => true,
+               "ab_12" => true,
                "12" => false,
                "new" => false}
 
@@ -119,10 +100,28 @@
       p = Project.new
       p.identifier = identifier
       p.valid?
-      assert_equal valid, p.errors['identifier'].nil?
+      if valid
+        assert p.errors['identifier'].blank?, "identifier #{identifier} was not valid"
+      else
+        assert p.errors['identifier'].present?, "identifier #{identifier} was valid"
+      end
     end
   end
 
+  def test_identifier_should_not_be_frozen_for_a_new_project
+    assert_equal false, Project.new.identifier_frozen?
+  end
+
+  def test_identifier_should_not_be_frozen_for_a_saved_project_with_blank_identifier
+    Project.update_all(["identifier = ''"], "id = 1")
+
+    assert_equal false, Project.find(1).identifier_frozen?
+  end
+
+  def test_identifier_should_be_frozen_for_a_saved_project_with_valid_identifier
+    assert_equal true, Project.find(1).identifier_frozen?
+  end
+
   def test_members_should_be_active_users
     Project.all.each do |project|
       assert_nil project.members.detect {|m| !(m.user.is_a?(User) && m.user.active?) }
@@ -135,6 +134,10 @@
     end
   end
 
+  def test_open_scope_on_issues_association
+    assert_kind_of Issue, Project.find(1).issues.open.first
+  end
+
   def test_archive
     user = @ecookbook.members.first.user
     @ecookbook.archive
@@ -193,6 +196,18 @@
     assert_nil Issue.first(:conditions => {:project_id => @ecookbook.id})
   end
 
+  def test_destroy_should_destroy_subtasks
+    issues = (0..2).to_a.map {Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test')}
+    issues[0].update_attribute :parent_issue_id, issues[1].id
+    issues[2].update_attribute :parent_issue_id, issues[1].id
+    assert_equal 2, issues[1].children.count
+
+    assert_nothing_raised do
+      Project.find(1).destroy
+    end
+    assert Issue.find_all_by_id(issues.map(&:id)).empty?
+  end
+
   def test_destroying_root_projects_should_clear_data
     Project.roots.each do |root|
       root.destroy
@@ -204,7 +219,7 @@
     assert_equal 0, Issue.count
     assert_equal 0, Journal.count
     assert_equal 0, JournalDetail.count
-    assert_equal 0, Attachment.count
+    assert_equal 0, Attachment.count, "Attachments were not deleted: #{Attachment.all.inspect}"
     assert_equal 0, EnabledModule.count
     assert_equal 0, IssueCategory.count
     assert_equal 0, IssueRelation.count
@@ -273,26 +288,9 @@
 
     parent.reload
     assert_equal 4, parent.children.size
-    assert_equal parent.children.sort_by(&:name), parent.children
+    assert_equal parent.children.all.sort_by(&:name), parent.children.all
   end
 
-  def test_rebuild_should_sort_children_alphabetically
-    ProjectCustomField.delete_all
-    parent = Project.create!(:name => 'Parent', :identifier => 'parent')
-    Project.create!(:name => 'Project C', :identifier => 'project-c').move_to_child_of(parent)
-    Project.create!(:name => 'Project B', :identifier => 'project-b').move_to_child_of(parent)
-    Project.create!(:name => 'Project D', :identifier => 'project-d').move_to_child_of(parent)
-    Project.create!(:name => 'Project A', :identifier => 'project-a').move_to_child_of(parent)
-
-    Project.update_all("lft = NULL, rgt = NULL")
-    Project.rebuild!
-
-    parent.reload
-    assert_equal 4, parent.children.size
-    assert_equal parent.children.sort_by(&:name), parent.children
-  end
-
-
   def test_set_parent_should_update_issue_fixed_version_associations_when_a_fixed_version_is_moved_out_of_the_hierarchy
     # Parent issue with a hierarchy project's fixed version
     parent_issue = Issue.find(1)
@@ -759,7 +757,7 @@
     project = Project.find(1)
     system_activity = TimeEntryActivity.find_by_name('Design')
     assert system_activity.active?
-    overridden_activity = TimeEntryActivity.generate!(:project => project, :parent => system_activity, :active => false)
+    overridden_activity = TimeEntryActivity.create!(:name => "Project", :project => project, :parent => system_activity, :active => false)
     assert overridden_activity.save!
 
     assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity not found"
@@ -810,16 +808,33 @@
       assert_equal "Closed", copied_issue.status.name
     end
 
+    should "copy issues assigned to a locked version" do
+      User.current = User.find(1)
+      assigned_version = Version.generate!(:name => "Assigned Issues")
+      @source_project.versions << assigned_version
+      Issue.generate!(:project => @source_project,
+                      :fixed_version_id => assigned_version.id,
+                      :subject => "copy issues assigned to a locked version")
+      assigned_version.update_attribute :status, 'locked'
+
+      assert @project.copy(@source_project)
+      @project.reload
+      copied_issue = @project.issues.first(:conditions => {:subject => "copy issues assigned to a locked version"})
+
+      assert copied_issue
+      assert copied_issue.fixed_version
+      assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
+      assert_equal 'locked', copied_issue.fixed_version.status
+    end
+
     should "change the new issues to use the copied version" do
       User.current = User.find(1)
       assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open')
       @source_project.versions << assigned_version
       assert_equal 3, @source_project.versions.size
-      Issue.generate_for_project!(@source_project,
-                                  :fixed_version_id => assigned_version.id,
-                                  :subject => "change the new issues to use the copied version",
-                                  :tracker_id => 1,
-                                  :project_id => @source_project.id)
+      Issue.generate!(:project => @source_project,
+                      :fixed_version_id => assigned_version.id,
+                      :subject => "change the new issues to use the copied version")
 
       assert @project.copy(@source_project)
       @project.reload
@@ -831,6 +846,20 @@
       assert_not_equal assigned_version.id, copied_issue.fixed_version.id # Different record
     end
 
+    should "keep target shared versions from other project" do
+      assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open', :project_id => 1, :sharing => 'system')
+      issue = Issue.generate!(:project => @source_project,
+                              :fixed_version => assigned_version,
+                              :subject => "keep target shared versions")
+
+      assert @project.copy(@source_project)
+      @project.reload
+      copied_issue = @project.issues.first(:conditions => {:subject => "keep target shared versions"})
+
+      assert copied_issue
+      assert_equal assigned_version, copied_issue.fixed_version
+    end
+
     should "copy issue relations" do
       Setting.cross_project_issue_relations = '1'
 
@@ -839,10 +868,10 @@
                                      :tracker_id => 1,
                                      :assigned_to_id => 2,
                                      :project_id => @source_project.id)
-      source_relation = IssueRelation.generate!(:issue_from => Issue.find(4),
+      source_relation = IssueRelation.create!(:issue_from => Issue.find(4),
                                                 :issue_to => second_issue,
                                                 :relation_type => "relates")
-      source_relation_cross_project = IssueRelation.generate!(:issue_from => Issue.find(1),
+      source_relation_cross_project = IssueRelation.create!(:issue_from => Issue.find(1),
                                                               :issue_to => second_issue,
                                                               :relation_type => "duplicates")
 
@@ -866,6 +895,18 @@
       assert_not_equal source_relation_cross_project.id, copied_relation.id
     end
 
+    should "copy issue attachments" do
+      issue = Issue.generate!(:subject => "copy with attachment", :tracker_id => 1, :project_id => @source_project.id)
+      Attachment.create!(:container => issue, :file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 1)
+      @source_project.issues << issue
+      assert @project.copy(@source_project)
+
+      copied_issue = @project.issues.first(:conditions => {:subject => "copy with attachment"})
+      assert_not_nil copied_issue
+      assert_equal 1, copied_issue.attachments.count, "Attachment not copied"
+      assert_equal "testfile.txt", copied_issue.attachments.first.filename
+    end
+
     should "copy memberships" do
       assert @project.valid?
       assert @project.members.empty?
@@ -993,7 +1034,23 @@
       assert @project.issue_categories.any?
       assert @project.issues.empty?
     end
+  end
 
+  def test_copy_should_copy_subtasks
+    source = Project.generate!(:tracker_ids => [1])
+    issue = Issue.generate_with_descendants!(:project => source)
+    project = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1])
+
+    assert_difference 'Project.count' do
+      assert_difference 'Issue.count', 1+issue.descendants.count do
+        assert project.copy(source.reload)
+      end
+    end
+    copy = Issue.where(:parent_id => nil).order("id DESC").first
+    assert_equal project, copy.project
+    assert_equal issue.descendants.count, copy.descendants.count
+    child_copy = copy.children.detect {|c| c.subject == 'Child1'}
+    assert child_copy.descendants.any?
   end
 
   context "#start_date" do
@@ -1011,8 +1068,8 @@
 
     should "be the earliest start date of it's issues" do
       early = 7.days.ago.to_date
-      Issue.generate_for_project!(@project, :start_date => Date.today)
-      Issue.generate_for_project!(@project, :start_date => early)
+      Issue.generate!(:project => @project, :start_date => Date.today)
+      Issue.generate!(:project => @project, :start_date => early)
 
       assert_equal early, @project.start_date
     end
@@ -1034,8 +1091,8 @@
 
     should "be the latest due date of it's issues" do
       future = 7.days.from_now.to_date
-      Issue.generate_for_project!(@project, :due_date => future)
-      Issue.generate_for_project!(@project, :due_date => Date.today)
+      Issue.generate!(:project => @project, :due_date => future)
+      Issue.generate!(:project => @project, :due_date => Date.today)
 
       assert_equal future, @project.due_date
     end
@@ -1053,7 +1110,7 @@
     should "pick the latest date from it's issues and versions" do
       future = 7.days.from_now.to_date
       far_future = 14.days.from_now.to_date
-      Issue.generate_for_project!(@project, :due_date => far_future)
+      Issue.generate!(:project => @project, :due_date => far_future)
       @project.versions << Version.generate!(:effective_date => future)
 
       assert_equal far_future, @project.due_date
@@ -1084,18 +1141,18 @@
 
       should "return 100 if the version has only closed issues" do
         v1 = Version.generate!(:project => @project)
-        Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
+        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
         v2 = Version.generate!(:project => @project)
-        Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
+        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
 
         assert_equal 100, @project.completed_percent
       end
 
       should "return the averaged completed percent of the versions (not weighted)" do
         v1 = Version.generate!(:project => @project)
-        Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
+        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
         v2 = Version.generate!(:project => @project)
-        Issue.generate_for_project!(@project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
+        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
 
         assert_equal 50, @project.completed_percent
       end
@@ -1109,22 +1166,22 @@
       @role = Role.generate!
 
       @user_with_membership_notification = User.generate!(:mail_notification => 'selected')
-      Member.generate!(:project => @project, :roles => [@role], :principal => @user_with_membership_notification, :mail_notification => true)
+      Member.create!(:project => @project, :roles => [@role], :principal => @user_with_membership_notification, :mail_notification => true)
 
       @all_events_user = User.generate!(:mail_notification => 'all')
-      Member.generate!(:project => @project, :roles => [@role], :principal => @all_events_user)
+      Member.create!(:project => @project, :roles => [@role], :principal => @all_events_user)
 
       @no_events_user = User.generate!(:mail_notification => 'none')
-      Member.generate!(:project => @project, :roles => [@role], :principal => @no_events_user)
+      Member.create!(:project => @project, :roles => [@role], :principal => @no_events_user)
 
       @only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
-      Member.generate!(:project => @project, :roles => [@role], :principal => @only_my_events_user)
+      Member.create!(:project => @project, :roles => [@role], :principal => @only_my_events_user)
 
       @only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
-      Member.generate!(:project => @project, :roles => [@role], :principal => @only_assigned_user)
+      Member.create!(:project => @project, :roles => [@role], :principal => @only_assigned_user)
 
       @only_owned_user = User.generate!(:mail_notification => 'only_owner')
-      Member.generate!(:project => @project, :roles => [@role], :principal => @only_owned_user)
+      Member.create!(:project => @project, :roles => [@role], :principal => @only_owned_user)
     end
 
     should "include members with a mail notification" do