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