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