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