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