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