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