##// END OF EJS Templates
Changed assertions to make them work with Rails2/3 ruby1.8/1.9 different behaviours....
Jean-Philippe Lang -
r8987:97ca65d1b217
parent child
Show More
@@ -1,887 +1,884
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_include I18n.translate('activerecord.errors.messages.blank'), u.errors[:mail]
58 u.errors[:mail].to_s
59 end
58 end
60
59
61 def test_login_length_validation
60 def test_login_length_validation
62 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
61 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
63 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
62 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
64 assert !user.valid?
63 assert !user.valid?
65
64
66 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
65 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
67 assert user.valid?
66 assert user.valid?
68 assert user.save
67 assert user.save
69 end
68 end
70
69
71 def test_create
70 def test_create
72 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
71 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
73
72
74 user.login = "jsmith"
73 user.login = "jsmith"
75 user.password, user.password_confirmation = "password", "password"
74 user.password, user.password_confirmation = "password", "password"
76 # login uniqueness
75 # login uniqueness
77 assert !user.save
76 assert !user.save
78 assert_equal 1, user.errors.count
77 assert_equal 1, user.errors.count
79
78
80 user.login = "newuser"
79 user.login = "newuser"
81 user.password, user.password_confirmation = "passwd", "password"
80 user.password, user.password_confirmation = "passwd", "password"
82 # password confirmation
81 # password confirmation
83 assert !user.save
82 assert !user.save
84 assert_equal 1, user.errors.count
83 assert_equal 1, user.errors.count
85
84
86 user.password, user.password_confirmation = "password", "password"
85 user.password, user.password_confirmation = "password", "password"
87 assert user.save
86 assert user.save
88 end
87 end
89
88
90 context "User#before_create" do
89 context "User#before_create" do
91 should "set the mail_notification to the default Setting" do
90 should "set the mail_notification to the default Setting" do
92 @user1 = User.generate_with_protected!
91 @user1 = User.generate_with_protected!
93 assert_equal 'only_my_events', @user1.mail_notification
92 assert_equal 'only_my_events', @user1.mail_notification
94
93
95 with_settings :default_notification_option => 'all' do
94 with_settings :default_notification_option => 'all' do
96 @user2 = User.generate_with_protected!
95 @user2 = User.generate_with_protected!
97 assert_equal 'all', @user2.mail_notification
96 assert_equal 'all', @user2.mail_notification
98 end
97 end
99 end
98 end
100 end
99 end
101
100
102 context "User.login" do
101 context "User.login" do
103 should "be case-insensitive." do
102 should "be case-insensitive." do
104 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
103 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
105 u.login = 'newuser'
104 u.login = 'newuser'
106 u.password, u.password_confirmation = "password", "password"
105 u.password, u.password_confirmation = "password", "password"
107 assert u.save
106 assert u.save
108
107
109 u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
108 u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
110 u.login = 'NewUser'
109 u.login = 'NewUser'
111 u.password, u.password_confirmation = "password", "password"
110 u.password, u.password_confirmation = "password", "password"
112 assert !u.save
111 assert !u.save
113 assert_equal I18n.translate('activerecord.errors.messages.taken'),
112 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
114 u.errors[:login].to_s
115 end
113 end
116 end
114 end
117
115
118 def test_mail_uniqueness_should_not_be_case_sensitive
116 def test_mail_uniqueness_should_not_be_case_sensitive
119 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
117 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
120 u.login = 'newuser1'
118 u.login = 'newuser1'
121 u.password, u.password_confirmation = "password", "password"
119 u.password, u.password_confirmation = "password", "password"
122 assert u.save
120 assert u.save
123
121
124 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
122 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
125 u.login = 'newuser2'
123 u.login = 'newuser2'
126 u.password, u.password_confirmation = "password", "password"
124 u.password, u.password_confirmation = "password", "password"
127 assert !u.save
125 assert !u.save
128 assert_equal I18n.translate('activerecord.errors.messages.taken'),
126 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:mail]
129 u.errors[:mail].to_s
130 end
127 end
131
128
132 def test_update
129 def test_update
133 assert_equal "admin", @admin.login
130 assert_equal "admin", @admin.login
134 @admin.login = "john"
131 @admin.login = "john"
135 assert @admin.save, @admin.errors.full_messages.join("; ")
132 assert @admin.save, @admin.errors.full_messages.join("; ")
136 @admin.reload
133 @admin.reload
137 assert_equal "john", @admin.login
134 assert_equal "john", @admin.login
138 end
135 end
139
136
140 def test_destroy_should_delete_members_and_roles
137 def test_destroy_should_delete_members_and_roles
141 members = Member.find_all_by_user_id(2)
138 members = Member.find_all_by_user_id(2)
142 ms = members.size
139 ms = members.size
143 rs = members.collect(&:roles).flatten.size
140 rs = members.collect(&:roles).flatten.size
144
141
145 assert_difference 'Member.count', - ms do
142 assert_difference 'Member.count', - ms do
146 assert_difference 'MemberRole.count', - rs do
143 assert_difference 'MemberRole.count', - rs do
147 User.find(2).destroy
144 User.find(2).destroy
148 end
145 end
149 end
146 end
150
147
151 assert_nil User.find_by_id(2)
148 assert_nil User.find_by_id(2)
152 assert Member.find_all_by_user_id(2).empty?
149 assert Member.find_all_by_user_id(2).empty?
153 end
150 end
154
151
155 def test_destroy_should_update_attachments
152 def test_destroy_should_update_attachments
156 attachment = Attachment.create!(:container => Project.find(1),
153 attachment = Attachment.create!(:container => Project.find(1),
157 :file => uploaded_test_file("testfile.txt", "text/plain"),
154 :file => uploaded_test_file("testfile.txt", "text/plain"),
158 :author_id => 2)
155 :author_id => 2)
159
156
160 User.find(2).destroy
157 User.find(2).destroy
161 assert_nil User.find_by_id(2)
158 assert_nil User.find_by_id(2)
162 assert_equal User.anonymous, attachment.reload.author
159 assert_equal User.anonymous, attachment.reload.author
163 end
160 end
164
161
165 def test_destroy_should_update_comments
162 def test_destroy_should_update_comments
166 comment = Comment.create!(
163 comment = Comment.create!(
167 :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'),
164 :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'),
168 :author => User.find(2),
165 :author => User.find(2),
169 :comments => 'foo'
166 :comments => 'foo'
170 )
167 )
171
168
172 User.find(2).destroy
169 User.find(2).destroy
173 assert_nil User.find_by_id(2)
170 assert_nil User.find_by_id(2)
174 assert_equal User.anonymous, comment.reload.author
171 assert_equal User.anonymous, comment.reload.author
175 end
172 end
176
173
177 def test_destroy_should_update_issues
174 def test_destroy_should_update_issues
178 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
175 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
179
176
180 User.find(2).destroy
177 User.find(2).destroy
181 assert_nil User.find_by_id(2)
178 assert_nil User.find_by_id(2)
182 assert_equal User.anonymous, issue.reload.author
179 assert_equal User.anonymous, issue.reload.author
183 end
180 end
184
181
185 def test_destroy_should_unassign_issues
182 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)
183 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
187
184
188 User.find(2).destroy
185 User.find(2).destroy
189 assert_nil User.find_by_id(2)
186 assert_nil User.find_by_id(2)
190 assert_nil issue.reload.assigned_to
187 assert_nil issue.reload.assigned_to
191 end
188 end
192
189
193 def test_destroy_should_update_journals
190 def test_destroy_should_update_journals
194 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
191 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
195 issue.init_journal(User.find(2), "update")
192 issue.init_journal(User.find(2), "update")
196 issue.save!
193 issue.save!
197
194
198 User.find(2).destroy
195 User.find(2).destroy
199 assert_nil User.find_by_id(2)
196 assert_nil User.find_by_id(2)
200 assert_equal User.anonymous, issue.journals.first.reload.user
197 assert_equal User.anonymous, issue.journals.first.reload.user
201 end
198 end
202
199
203 def test_destroy_should_update_journal_details_old_value
200 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)
201 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")
202 issue.init_journal(User.find(1), "update")
206 issue.assigned_to_id = nil
203 issue.assigned_to_id = nil
207 assert_difference 'JournalDetail.count' do
204 assert_difference 'JournalDetail.count' do
208 issue.save!
205 issue.save!
209 end
206 end
210 journal_detail = JournalDetail.first(:order => 'id DESC')
207 journal_detail = JournalDetail.first(:order => 'id DESC')
211 assert_equal '2', journal_detail.old_value
208 assert_equal '2', journal_detail.old_value
212
209
213 User.find(2).destroy
210 User.find(2).destroy
214 assert_nil User.find_by_id(2)
211 assert_nil User.find_by_id(2)
215 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
212 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
216 end
213 end
217
214
218 def test_destroy_should_update_journal_details_value
215 def test_destroy_should_update_journal_details_value
219 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
216 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
220 issue.init_journal(User.find(1), "update")
217 issue.init_journal(User.find(1), "update")
221 issue.assigned_to_id = 2
218 issue.assigned_to_id = 2
222 assert_difference 'JournalDetail.count' do
219 assert_difference 'JournalDetail.count' do
223 issue.save!
220 issue.save!
224 end
221 end
225 journal_detail = JournalDetail.first(:order => 'id DESC')
222 journal_detail = JournalDetail.first(:order => 'id DESC')
226 assert_equal '2', journal_detail.value
223 assert_equal '2', journal_detail.value
227
224
228 User.find(2).destroy
225 User.find(2).destroy
229 assert_nil User.find_by_id(2)
226 assert_nil User.find_by_id(2)
230 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
227 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
231 end
228 end
232
229
233 def test_destroy_should_update_messages
230 def test_destroy_should_update_messages
234 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
231 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')
232 message = Message.create!(:board_id => board.id, :author_id => 2, :subject => 'foo', :content => 'foo')
236
233
237 User.find(2).destroy
234 User.find(2).destroy
238 assert_nil User.find_by_id(2)
235 assert_nil User.find_by_id(2)
239 assert_equal User.anonymous, message.reload.author
236 assert_equal User.anonymous, message.reload.author
240 end
237 end
241
238
242 def test_destroy_should_update_news
239 def test_destroy_should_update_news
243 news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo')
240 news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo')
244
241
245 User.find(2).destroy
242 User.find(2).destroy
246 assert_nil User.find_by_id(2)
243 assert_nil User.find_by_id(2)
247 assert_equal User.anonymous, news.reload.author
244 assert_equal User.anonymous, news.reload.author
248 end
245 end
249
246
250 def test_destroy_should_delete_private_queries
247 def test_destroy_should_delete_private_queries
251 query = Query.new(:name => 'foo', :is_public => false)
248 query = Query.new(:name => 'foo', :is_public => false)
252 query.project_id = 1
249 query.project_id = 1
253 query.user_id = 2
250 query.user_id = 2
254 query.save!
251 query.save!
255
252
256 User.find(2).destroy
253 User.find(2).destroy
257 assert_nil User.find_by_id(2)
254 assert_nil User.find_by_id(2)
258 assert_nil Query.find_by_id(query.id)
255 assert_nil Query.find_by_id(query.id)
259 end
256 end
260
257
261 def test_destroy_should_update_public_queries
258 def test_destroy_should_update_public_queries
262 query = Query.new(:name => 'foo', :is_public => true)
259 query = Query.new(:name => 'foo', :is_public => true)
263 query.project_id = 1
260 query.project_id = 1
264 query.user_id = 2
261 query.user_id = 2
265 query.save!
262 query.save!
266
263
267 User.find(2).destroy
264 User.find(2).destroy
268 assert_nil User.find_by_id(2)
265 assert_nil User.find_by_id(2)
269 assert_equal User.anonymous, query.reload.user
266 assert_equal User.anonymous, query.reload.user
270 end
267 end
271
268
272 def test_destroy_should_update_time_entries
269 def test_destroy_should_update_time_entries
273 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo'))
270 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo'))
274 entry.project_id = 1
271 entry.project_id = 1
275 entry.user_id = 2
272 entry.user_id = 2
276 entry.save!
273 entry.save!
277
274
278 User.find(2).destroy
275 User.find(2).destroy
279 assert_nil User.find_by_id(2)
276 assert_nil User.find_by_id(2)
280 assert_equal User.anonymous, entry.reload.user
277 assert_equal User.anonymous, entry.reload.user
281 end
278 end
282
279
283 def test_destroy_should_delete_tokens
280 def test_destroy_should_delete_tokens
284 token = Token.create!(:user_id => 2, :value => 'foo')
281 token = Token.create!(:user_id => 2, :value => 'foo')
285
282
286 User.find(2).destroy
283 User.find(2).destroy
287 assert_nil User.find_by_id(2)
284 assert_nil User.find_by_id(2)
288 assert_nil Token.find_by_id(token.id)
285 assert_nil Token.find_by_id(token.id)
289 end
286 end
290
287
291 def test_destroy_should_delete_watchers
288 def test_destroy_should_delete_watchers
292 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
289 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
293 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
290 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
294
291
295 User.find(2).destroy
292 User.find(2).destroy
296 assert_nil User.find_by_id(2)
293 assert_nil User.find_by_id(2)
297 assert_nil Watcher.find_by_id(watcher.id)
294 assert_nil Watcher.find_by_id(watcher.id)
298 end
295 end
299
296
300 def test_destroy_should_update_wiki_contents
297 def test_destroy_should_update_wiki_contents
301 wiki_content = WikiContent.create!(
298 wiki_content = WikiContent.create!(
302 :text => 'foo',
299 :text => 'foo',
303 :author_id => 2,
300 :author_id => 2,
304 :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start'))
301 :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start'))
305 )
302 )
306 wiki_content.text = 'bar'
303 wiki_content.text = 'bar'
307 assert_difference 'WikiContent::Version.count' do
304 assert_difference 'WikiContent::Version.count' do
308 wiki_content.save!
305 wiki_content.save!
309 end
306 end
310
307
311 User.find(2).destroy
308 User.find(2).destroy
312 assert_nil User.find_by_id(2)
309 assert_nil User.find_by_id(2)
313 assert_equal User.anonymous, wiki_content.reload.author
310 assert_equal User.anonymous, wiki_content.reload.author
314 wiki_content.versions.each do |version|
311 wiki_content.versions.each do |version|
315 assert_equal User.anonymous, version.reload.author
312 assert_equal User.anonymous, version.reload.author
316 end
313 end
317 end
314 end
318
315
319 def test_destroy_should_nullify_issue_categories
316 def test_destroy_should_nullify_issue_categories
320 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
317 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
321
318
322 User.find(2).destroy
319 User.find(2).destroy
323 assert_nil User.find_by_id(2)
320 assert_nil User.find_by_id(2)
324 assert_nil category.reload.assigned_to_id
321 assert_nil category.reload.assigned_to_id
325 end
322 end
326
323
327 def test_destroy_should_nullify_changesets
324 def test_destroy_should_nullify_changesets
328 changeset = Changeset.create!(
325 changeset = Changeset.create!(
329 :repository => Repository::Subversion.generate!(
326 :repository => Repository::Subversion.generate!(
330 :project_id => 1
327 :project_id => 1
331 ),
328 ),
332 :revision => '12',
329 :revision => '12',
333 :committed_on => Time.now,
330 :committed_on => Time.now,
334 :committer => 'jsmith'
331 :committer => 'jsmith'
335 )
332 )
336 assert_equal 2, changeset.user_id
333 assert_equal 2, changeset.user_id
337
334
338 User.find(2).destroy
335 User.find(2).destroy
339 assert_nil User.find_by_id(2)
336 assert_nil User.find_by_id(2)
340 assert_nil changeset.reload.user_id
337 assert_nil changeset.reload.user_id
341 end
338 end
342
339
343 def test_anonymous_user_should_not_be_destroyable
340 def test_anonymous_user_should_not_be_destroyable
344 assert_no_difference 'User.count' do
341 assert_no_difference 'User.count' do
345 assert_equal false, User.anonymous.destroy
342 assert_equal false, User.anonymous.destroy
346 end
343 end
347 end
344 end
348
345
349 def test_validate_login_presence
346 def test_validate_login_presence
350 @admin.login = ""
347 @admin.login = ""
351 assert !@admin.save
348 assert !@admin.save
352 assert_equal 1, @admin.errors.count
349 assert_equal 1, @admin.errors.count
353 end
350 end
354
351
355 def test_validate_mail_notification_inclusion
352 def test_validate_mail_notification_inclusion
356 u = User.new
353 u = User.new
357 u.mail_notification = 'foo'
354 u.mail_notification = 'foo'
358 u.save
355 u.save
359 assert_not_nil u.errors[:mail_notification]
356 assert_not_nil u.errors[:mail_notification]
360 end
357 end
361
358
362 context "User#try_to_login" do
359 context "User#try_to_login" do
363 should "fall-back to case-insensitive if user login is not found as-typed." do
360 should "fall-back to case-insensitive if user login is not found as-typed." do
364 user = User.try_to_login("AdMin", "admin")
361 user = User.try_to_login("AdMin", "admin")
365 assert_kind_of User, user
362 assert_kind_of User, user
366 assert_equal "admin", user.login
363 assert_equal "admin", user.login
367 end
364 end
368
365
369 should "select the exact matching user first" do
366 should "select the exact matching user first" do
370 case_sensitive_user = User.generate_with_protected!(
367 case_sensitive_user = User.generate_with_protected!(
371 :login => 'changed', :password => 'admin',
368 :login => 'changed', :password => 'admin',
372 :password_confirmation => 'admin')
369 :password_confirmation => 'admin')
373 # bypass validations to make it appear like existing data
370 # bypass validations to make it appear like existing data
374 case_sensitive_user.update_attribute(:login, 'ADMIN')
371 case_sensitive_user.update_attribute(:login, 'ADMIN')
375
372
376 user = User.try_to_login("ADMIN", "admin")
373 user = User.try_to_login("ADMIN", "admin")
377 assert_kind_of User, user
374 assert_kind_of User, user
378 assert_equal "ADMIN", user.login
375 assert_equal "ADMIN", user.login
379
376
380 end
377 end
381 end
378 end
382
379
383 def test_password
380 def test_password
384 user = User.try_to_login("admin", "admin")
381 user = User.try_to_login("admin", "admin")
385 assert_kind_of User, user
382 assert_kind_of User, user
386 assert_equal "admin", user.login
383 assert_equal "admin", user.login
387 user.password = "hello"
384 user.password = "hello"
388 assert user.save
385 assert user.save
389
386
390 user = User.try_to_login("admin", "hello")
387 user = User.try_to_login("admin", "hello")
391 assert_kind_of User, user
388 assert_kind_of User, user
392 assert_equal "admin", user.login
389 assert_equal "admin", user.login
393 end
390 end
394
391
395 def test_validate_password_length
392 def test_validate_password_length
396 with_settings :password_min_length => '100' do
393 with_settings :password_min_length => '100' do
397 user = User.new(:firstname => "new100", :lastname => "user100", :mail => "newuser100@somenet.foo")
394 user = User.new(:firstname => "new100", :lastname => "user100", :mail => "newuser100@somenet.foo")
398 user.login = "newuser100"
395 user.login = "newuser100"
399 user.password, user.password_confirmation = "password100", "password100"
396 user.password, user.password_confirmation = "password100", "password100"
400 assert !user.save
397 assert !user.save
401 assert_equal 1, user.errors.count
398 assert_equal 1, user.errors.count
402 end
399 end
403 end
400 end
404
401
405 def test_name_format
402 def test_name_format
406 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
403 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
407 with_settings :user_format => :firstname_lastname do
404 with_settings :user_format => :firstname_lastname do
408 assert_equal 'John Smith', @jsmith.reload.name
405 assert_equal 'John Smith', @jsmith.reload.name
409 end
406 end
410 with_settings :user_format => :username do
407 with_settings :user_format => :username do
411 assert_equal 'jsmith', @jsmith.reload.name
408 assert_equal 'jsmith', @jsmith.reload.name
412 end
409 end
413 end
410 end
414
411
415 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
412 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
416 with_settings :user_format => 'lastname_coma_firstname' do
413 with_settings :user_format => 'lastname_coma_firstname' do
417 assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
414 assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
418 end
415 end
419 end
416 end
420
417
421 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
418 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
422 with_settings :user_format => 'lastname_firstname' do
419 with_settings :user_format => 'lastname_firstname' do
423 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
420 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
424 end
421 end
425 end
422 end
426
423
427 def test_fields_for_order_statement_with_blank_format_should_return_default
424 def test_fields_for_order_statement_with_blank_format_should_return_default
428 with_settings :user_format => '' do
425 with_settings :user_format => '' do
429 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
426 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
430 end
427 end
431 end
428 end
432
429
433 def test_fields_for_order_statement_with_invalid_format_should_return_default
430 def test_fields_for_order_statement_with_invalid_format_should_return_default
434 with_settings :user_format => 'foo' do
431 with_settings :user_format => 'foo' do
435 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
432 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
436 end
433 end
437 end
434 end
438
435
439 def test_lock
436 def test_lock
440 user = User.try_to_login("jsmith", "jsmith")
437 user = User.try_to_login("jsmith", "jsmith")
441 assert_equal @jsmith, user
438 assert_equal @jsmith, user
442
439
443 @jsmith.status = User::STATUS_LOCKED
440 @jsmith.status = User::STATUS_LOCKED
444 assert @jsmith.save
441 assert @jsmith.save
445
442
446 user = User.try_to_login("jsmith", "jsmith")
443 user = User.try_to_login("jsmith", "jsmith")
447 assert_equal nil, user
444 assert_equal nil, user
448 end
445 end
449
446
450 context ".try_to_login" do
447 context ".try_to_login" do
451 context "with good credentials" do
448 context "with good credentials" do
452 should "return the user" do
449 should "return the user" do
453 user = User.try_to_login("admin", "admin")
450 user = User.try_to_login("admin", "admin")
454 assert_kind_of User, user
451 assert_kind_of User, user
455 assert_equal "admin", user.login
452 assert_equal "admin", user.login
456 end
453 end
457 end
454 end
458
455
459 context "with wrong credentials" do
456 context "with wrong credentials" do
460 should "return nil" do
457 should "return nil" do
461 assert_nil User.try_to_login("admin", "foo")
458 assert_nil User.try_to_login("admin", "foo")
462 end
459 end
463 end
460 end
464 end
461 end
465
462
466 if ldap_configured?
463 if ldap_configured?
467 context "#try_to_login using LDAP" do
464 context "#try_to_login using LDAP" do
468 context "with failed connection to the LDAP server" do
465 context "with failed connection to the LDAP server" do
469 should "return nil" do
466 should "return nil" do
470 @auth_source = AuthSourceLdap.find(1)
467 @auth_source = AuthSourceLdap.find(1)
471 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
468 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
472
469
473 assert_equal nil, User.try_to_login('edavis', 'wrong')
470 assert_equal nil, User.try_to_login('edavis', 'wrong')
474 end
471 end
475 end
472 end
476
473
477 context "with an unsuccessful authentication" do
474 context "with an unsuccessful authentication" do
478 should "return nil" do
475 should "return nil" do
479 assert_equal nil, User.try_to_login('edavis', 'wrong')
476 assert_equal nil, User.try_to_login('edavis', 'wrong')
480 end
477 end
481 end
478 end
482
479
483 context "on the fly registration" do
480 context "on the fly registration" do
484 setup do
481 setup do
485 @auth_source = AuthSourceLdap.find(1)
482 @auth_source = AuthSourceLdap.find(1)
486 @auth_source.update_attribute :onthefly_register, true
483 @auth_source.update_attribute :onthefly_register, true
487 end
484 end
488
485
489 context "with a successful authentication" do
486 context "with a successful authentication" do
490 should "create a new user account if it doesn't exist" do
487 should "create a new user account if it doesn't exist" do
491 assert_difference('User.count') do
488 assert_difference('User.count') do
492 user = User.try_to_login('edavis', '123456')
489 user = User.try_to_login('edavis', '123456')
493 assert !user.admin?
490 assert !user.admin?
494 end
491 end
495 end
492 end
496
493
497 should "retrieve existing user" do
494 should "retrieve existing user" do
498 user = User.try_to_login('edavis', '123456')
495 user = User.try_to_login('edavis', '123456')
499 user.admin = true
496 user.admin = true
500 user.save!
497 user.save!
501
498
502 assert_no_difference('User.count') do
499 assert_no_difference('User.count') do
503 user = User.try_to_login('edavis', '123456')
500 user = User.try_to_login('edavis', '123456')
504 assert user.admin?
501 assert user.admin?
505 end
502 end
506 end
503 end
507 end
504 end
508 end
505 end
509 end
506 end
510
507
511 else
508 else
512 puts "Skipping LDAP tests."
509 puts "Skipping LDAP tests."
513 end
510 end
514
511
515 def test_create_anonymous
512 def test_create_anonymous
516 AnonymousUser.delete_all
513 AnonymousUser.delete_all
517 anon = User.anonymous
514 anon = User.anonymous
518 assert !anon.new_record?
515 assert !anon.new_record?
519 assert_kind_of AnonymousUser, anon
516 assert_kind_of AnonymousUser, anon
520 end
517 end
521
518
522 def test_ensure_single_anonymous_user
519 def test_ensure_single_anonymous_user
523 AnonymousUser.delete_all
520 AnonymousUser.delete_all
524 anon1 = User.anonymous
521 anon1 = User.anonymous
525 assert !anon1.new_record?
522 assert !anon1.new_record?
526 assert_kind_of AnonymousUser, anon1
523 assert_kind_of AnonymousUser, anon1
527 anon2 = AnonymousUser.create(
524 anon2 = AnonymousUser.create(
528 :lastname => 'Anonymous', :firstname => '',
525 :lastname => 'Anonymous', :firstname => '',
529 :mail => '', :login => '', :status => 0)
526 :mail => '', :login => '', :status => 0)
530 assert_equal 1, anon2.errors.count
527 assert_equal 1, anon2.errors.count
531 end
528 end
532
529
533 def test_rss_key
530 def test_rss_key
534 assert_nil @jsmith.rss_token
531 assert_nil @jsmith.rss_token
535 key = @jsmith.rss_key
532 key = @jsmith.rss_key
536 assert_equal 40, key.length
533 assert_equal 40, key.length
537
534
538 @jsmith.reload
535 @jsmith.reload
539 assert_equal key, @jsmith.rss_key
536 assert_equal key, @jsmith.rss_key
540 end
537 end
541
538
542 context "User#api_key" do
539 context "User#api_key" do
543 should "generate a new one if the user doesn't have one" do
540 should "generate a new one if the user doesn't have one" do
544 user = User.generate_with_protected!(:api_token => nil)
541 user = User.generate_with_protected!(:api_token => nil)
545 assert_nil user.api_token
542 assert_nil user.api_token
546
543
547 key = user.api_key
544 key = user.api_key
548 assert_equal 40, key.length
545 assert_equal 40, key.length
549 user.reload
546 user.reload
550 assert_equal key, user.api_key
547 assert_equal key, user.api_key
551 end
548 end
552
549
553 should "return the existing api token value" do
550 should "return the existing api token value" do
554 user = User.generate_with_protected!
551 user = User.generate_with_protected!
555 token = Token.generate!(:action => 'api')
552 token = Token.generate!(:action => 'api')
556 user.api_token = token
553 user.api_token = token
557 assert user.save
554 assert user.save
558
555
559 assert_equal token.value, user.api_key
556 assert_equal token.value, user.api_key
560 end
557 end
561 end
558 end
562
559
563 context "User#find_by_api_key" do
560 context "User#find_by_api_key" do
564 should "return nil if no matching key is found" do
561 should "return nil if no matching key is found" do
565 assert_nil User.find_by_api_key('zzzzzzzzz')
562 assert_nil User.find_by_api_key('zzzzzzzzz')
566 end
563 end
567
564
568 should "return nil if the key is found for an inactive user" do
565 should "return nil if the key is found for an inactive user" do
569 user = User.generate_with_protected!(:status => User::STATUS_LOCKED)
566 user = User.generate_with_protected!(:status => User::STATUS_LOCKED)
570 token = Token.generate!(:action => 'api')
567 token = Token.generate!(:action => 'api')
571 user.api_token = token
568 user.api_token = token
572 user.save
569 user.save
573
570
574 assert_nil User.find_by_api_key(token.value)
571 assert_nil User.find_by_api_key(token.value)
575 end
572 end
576
573
577 should "return the user if the key is found for an active user" do
574 should "return the user if the key is found for an active user" do
578 user = User.generate_with_protected!(:status => User::STATUS_ACTIVE)
575 user = User.generate_with_protected!(:status => User::STATUS_ACTIVE)
579 token = Token.generate!(:action => 'api')
576 token = Token.generate!(:action => 'api')
580 user.api_token = token
577 user.api_token = token
581 user.save
578 user.save
582
579
583 assert_equal user, User.find_by_api_key(token.value)
580 assert_equal user, User.find_by_api_key(token.value)
584 end
581 end
585 end
582 end
586
583
587 def test_roles_for_project
584 def test_roles_for_project
588 # user with a role
585 # user with a role
589 roles = @jsmith.roles_for_project(Project.find(1))
586 roles = @jsmith.roles_for_project(Project.find(1))
590 assert_kind_of Role, roles.first
587 assert_kind_of Role, roles.first
591 assert_equal "Manager", roles.first.name
588 assert_equal "Manager", roles.first.name
592
589
593 # user with no role
590 # user with no role
594 assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
591 assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
595 end
592 end
596
593
597 def test_projects_by_role_for_user_with_role
594 def test_projects_by_role_for_user_with_role
598 user = User.find(2)
595 user = User.find(2)
599 assert_kind_of Hash, user.projects_by_role
596 assert_kind_of Hash, user.projects_by_role
600 assert_equal 2, user.projects_by_role.size
597 assert_equal 2, user.projects_by_role.size
601 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
598 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
602 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
599 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
603 end
600 end
604
601
605 def test_projects_by_role_for_user_with_no_role
602 def test_projects_by_role_for_user_with_no_role
606 user = User.generate!
603 user = User.generate!
607 assert_equal({}, user.projects_by_role)
604 assert_equal({}, user.projects_by_role)
608 end
605 end
609
606
610 def test_projects_by_role_for_anonymous
607 def test_projects_by_role_for_anonymous
611 assert_equal({}, User.anonymous.projects_by_role)
608 assert_equal({}, User.anonymous.projects_by_role)
612 end
609 end
613
610
614 def test_valid_notification_options
611 def test_valid_notification_options
615 # without memberships
612 # without memberships
616 assert_equal 5, User.find(7).valid_notification_options.size
613 assert_equal 5, User.find(7).valid_notification_options.size
617 # with memberships
614 # with memberships
618 assert_equal 6, User.find(2).valid_notification_options.size
615 assert_equal 6, User.find(2).valid_notification_options.size
619 end
616 end
620
617
621 def test_valid_notification_options_class_method
618 def test_valid_notification_options_class_method
622 assert_equal 5, User.valid_notification_options.size
619 assert_equal 5, User.valid_notification_options.size
623 assert_equal 5, User.valid_notification_options(User.find(7)).size
620 assert_equal 5, User.valid_notification_options(User.find(7)).size
624 assert_equal 6, User.valid_notification_options(User.find(2)).size
621 assert_equal 6, User.valid_notification_options(User.find(2)).size
625 end
622 end
626
623
627 def test_mail_notification_all
624 def test_mail_notification_all
628 @jsmith.mail_notification = 'all'
625 @jsmith.mail_notification = 'all'
629 @jsmith.notified_project_ids = []
626 @jsmith.notified_project_ids = []
630 @jsmith.save
627 @jsmith.save
631 @jsmith.reload
628 @jsmith.reload
632 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
629 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
633 end
630 end
634
631
635 def test_mail_notification_selected
632 def test_mail_notification_selected
636 @jsmith.mail_notification = 'selected'
633 @jsmith.mail_notification = 'selected'
637 @jsmith.notified_project_ids = [1]
634 @jsmith.notified_project_ids = [1]
638 @jsmith.save
635 @jsmith.save
639 @jsmith.reload
636 @jsmith.reload
640 assert Project.find(1).recipients.include?(@jsmith.mail)
637 assert Project.find(1).recipients.include?(@jsmith.mail)
641 end
638 end
642
639
643 def test_mail_notification_only_my_events
640 def test_mail_notification_only_my_events
644 @jsmith.mail_notification = 'only_my_events'
641 @jsmith.mail_notification = 'only_my_events'
645 @jsmith.notified_project_ids = []
642 @jsmith.notified_project_ids = []
646 @jsmith.save
643 @jsmith.save
647 @jsmith.reload
644 @jsmith.reload
648 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
645 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
649 end
646 end
650
647
651 def test_comments_sorting_preference
648 def test_comments_sorting_preference
652 assert !@jsmith.wants_comments_in_reverse_order?
649 assert !@jsmith.wants_comments_in_reverse_order?
653 @jsmith.pref.comments_sorting = 'asc'
650 @jsmith.pref.comments_sorting = 'asc'
654 assert !@jsmith.wants_comments_in_reverse_order?
651 assert !@jsmith.wants_comments_in_reverse_order?
655 @jsmith.pref.comments_sorting = 'desc'
652 @jsmith.pref.comments_sorting = 'desc'
656 assert @jsmith.wants_comments_in_reverse_order?
653 assert @jsmith.wants_comments_in_reverse_order?
657 end
654 end
658
655
659 def test_find_by_mail_should_be_case_insensitive
656 def test_find_by_mail_should_be_case_insensitive
660 u = User.find_by_mail('JSmith@somenet.foo')
657 u = User.find_by_mail('JSmith@somenet.foo')
661 assert_not_nil u
658 assert_not_nil u
662 assert_equal 'jsmith@somenet.foo', u.mail
659 assert_equal 'jsmith@somenet.foo', u.mail
663 end
660 end
664
661
665 def test_random_password
662 def test_random_password
666 u = User.new
663 u = User.new
667 u.random_password
664 u.random_password
668 assert !u.password.blank?
665 assert !u.password.blank?
669 assert !u.password_confirmation.blank?
666 assert !u.password_confirmation.blank?
670 end
667 end
671
668
672 context "#change_password_allowed?" do
669 context "#change_password_allowed?" do
673 should "be allowed if no auth source is set" do
670 should "be allowed if no auth source is set" do
674 user = User.generate_with_protected!
671 user = User.generate_with_protected!
675 assert user.change_password_allowed?
672 assert user.change_password_allowed?
676 end
673 end
677
674
678 should "delegate to the auth source" do
675 should "delegate to the auth source" do
679 user = User.generate_with_protected!
676 user = User.generate_with_protected!
680
677
681 allowed_auth_source = AuthSource.generate!
678 allowed_auth_source = AuthSource.generate!
682 def allowed_auth_source.allow_password_changes?; true; end
679 def allowed_auth_source.allow_password_changes?; true; end
683
680
684 denied_auth_source = AuthSource.generate!
681 denied_auth_source = AuthSource.generate!
685 def denied_auth_source.allow_password_changes?; false; end
682 def denied_auth_source.allow_password_changes?; false; end
686
683
687 assert user.change_password_allowed?
684 assert user.change_password_allowed?
688
685
689 user.auth_source = allowed_auth_source
686 user.auth_source = allowed_auth_source
690 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
687 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
691
688
692 user.auth_source = denied_auth_source
689 user.auth_source = denied_auth_source
693 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
690 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
694 end
691 end
695
692
696 end
693 end
697
694
698 context "#allowed_to?" do
695 context "#allowed_to?" do
699 context "with a unique project" do
696 context "with a unique project" do
700 should "return false if project is archived" do
697 should "return false if project is archived" do
701 project = Project.find(1)
698 project = Project.find(1)
702 Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
699 Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
703 assert ! @admin.allowed_to?(:view_issues, Project.find(1))
700 assert ! @admin.allowed_to?(:view_issues, Project.find(1))
704 end
701 end
705
702
706 should "return false if related module is disabled" do
703 should "return false if related module is disabled" do
707 project = Project.find(1)
704 project = Project.find(1)
708 project.enabled_module_names = ["issue_tracking"]
705 project.enabled_module_names = ["issue_tracking"]
709 assert @admin.allowed_to?(:add_issues, project)
706 assert @admin.allowed_to?(:add_issues, project)
710 assert ! @admin.allowed_to?(:view_wiki_pages, project)
707 assert ! @admin.allowed_to?(:view_wiki_pages, project)
711 end
708 end
712
709
713 should "authorize nearly everything for admin users" do
710 should "authorize nearly everything for admin users" do
714 project = Project.find(1)
711 project = Project.find(1)
715 assert ! @admin.member_of?(project)
712 assert ! @admin.member_of?(project)
716 %w(edit_issues delete_issues manage_news manage_documents manage_wiki).each do |p|
713 %w(edit_issues delete_issues manage_news manage_documents manage_wiki).each do |p|
717 assert @admin.allowed_to?(p.to_sym, project)
714 assert @admin.allowed_to?(p.to_sym, project)
718 end
715 end
719 end
716 end
720
717
721 should "authorize normal users depending on their roles" do
718 should "authorize normal users depending on their roles" do
722 project = Project.find(1)
719 project = Project.find(1)
723 assert @jsmith.allowed_to?(:delete_messages, project) #Manager
720 assert @jsmith.allowed_to?(:delete_messages, project) #Manager
724 assert ! @dlopper.allowed_to?(:delete_messages, project) #Developper
721 assert ! @dlopper.allowed_to?(:delete_messages, project) #Developper
725 end
722 end
726 end
723 end
727
724
728 context "with multiple projects" do
725 context "with multiple projects" do
729 should "return false if array is empty" do
726 should "return false if array is empty" do
730 assert ! @admin.allowed_to?(:view_project, [])
727 assert ! @admin.allowed_to?(:view_project, [])
731 end
728 end
732
729
733 should "return true only if user has permission on all these projects" do
730 should "return true only if user has permission on all these projects" do
734 assert @admin.allowed_to?(:view_project, Project.all)
731 assert @admin.allowed_to?(:view_project, Project.all)
735 assert ! @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2)
732 assert ! @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2)
736 assert @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere
733 assert @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere
737 assert ! @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers
734 assert ! @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers
738 end
735 end
739
736
740 should "behave correctly with arrays of 1 project" do
737 should "behave correctly with arrays of 1 project" do
741 assert ! User.anonymous.allowed_to?(:delete_issues, [Project.first])
738 assert ! User.anonymous.allowed_to?(:delete_issues, [Project.first])
742 end
739 end
743 end
740 end
744
741
745 context "with options[:global]" do
742 context "with options[:global]" do
746 should "authorize if user has at least one role that has this permission" do
743 should "authorize if user has at least one role that has this permission" do
747 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
744 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
748 @anonymous = User.find(6)
745 @anonymous = User.find(6)
749 assert @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
746 assert @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
750 assert ! @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
747 assert ! @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
751 assert @dlopper2.allowed_to?(:add_issues, nil, :global => true)
748 assert @dlopper2.allowed_to?(:add_issues, nil, :global => true)
752 assert ! @anonymous.allowed_to?(:add_issues, nil, :global => true)
749 assert ! @anonymous.allowed_to?(:add_issues, nil, :global => true)
753 assert @anonymous.allowed_to?(:view_issues, nil, :global => true)
750 assert @anonymous.allowed_to?(:view_issues, nil, :global => true)
754 end
751 end
755 end
752 end
756 end
753 end
757
754
758 context "User#notify_about?" do
755 context "User#notify_about?" do
759 context "Issues" do
756 context "Issues" do
760 setup do
757 setup do
761 @project = Project.find(1)
758 @project = Project.find(1)
762 @author = User.generate_with_protected!
759 @author = User.generate_with_protected!
763 @assignee = User.generate_with_protected!
760 @assignee = User.generate_with_protected!
764 @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
761 @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
765 end
762 end
766
763
767 should "be true for a user with :all" do
764 should "be true for a user with :all" do
768 @author.update_attribute(:mail_notification, 'all')
765 @author.update_attribute(:mail_notification, 'all')
769 assert @author.notify_about?(@issue)
766 assert @author.notify_about?(@issue)
770 end
767 end
771
768
772 should "be false for a user with :none" do
769 should "be false for a user with :none" do
773 @author.update_attribute(:mail_notification, 'none')
770 @author.update_attribute(:mail_notification, 'none')
774 assert ! @author.notify_about?(@issue)
771 assert ! @author.notify_about?(@issue)
775 end
772 end
776
773
777 should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
774 should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
778 @user = User.generate_with_protected!(:mail_notification => 'only_my_events')
775 @user = User.generate_with_protected!(:mail_notification => 'only_my_events')
779 Member.create!(:user => @user, :project => @project, :role_ids => [1])
776 Member.create!(:user => @user, :project => @project, :role_ids => [1])
780 assert ! @user.notify_about?(@issue)
777 assert ! @user.notify_about?(@issue)
781 end
778 end
782
779
783 should "be true for a user with :only_my_events and is the author" do
780 should "be true for a user with :only_my_events and is the author" do
784 @author.update_attribute(:mail_notification, 'only_my_events')
781 @author.update_attribute(:mail_notification, 'only_my_events')
785 assert @author.notify_about?(@issue)
782 assert @author.notify_about?(@issue)
786 end
783 end
787
784
788 should "be true for a user with :only_my_events and is the assignee" do
785 should "be true for a user with :only_my_events and is the assignee" do
789 @assignee.update_attribute(:mail_notification, 'only_my_events')
786 @assignee.update_attribute(:mail_notification, 'only_my_events')
790 assert @assignee.notify_about?(@issue)
787 assert @assignee.notify_about?(@issue)
791 end
788 end
792
789
793 should "be true for a user with :only_assigned and is the assignee" do
790 should "be true for a user with :only_assigned and is the assignee" do
794 @assignee.update_attribute(:mail_notification, 'only_assigned')
791 @assignee.update_attribute(:mail_notification, 'only_assigned')
795 assert @assignee.notify_about?(@issue)
792 assert @assignee.notify_about?(@issue)
796 end
793 end
797
794
798 should "be false for a user with :only_assigned and is not the assignee" do
795 should "be false for a user with :only_assigned and is not the assignee" do
799 @author.update_attribute(:mail_notification, 'only_assigned')
796 @author.update_attribute(:mail_notification, 'only_assigned')
800 assert ! @author.notify_about?(@issue)
797 assert ! @author.notify_about?(@issue)
801 end
798 end
802
799
803 should "be true for a user with :only_owner and is the author" do
800 should "be true for a user with :only_owner and is the author" do
804 @author.update_attribute(:mail_notification, 'only_owner')
801 @author.update_attribute(:mail_notification, 'only_owner')
805 assert @author.notify_about?(@issue)
802 assert @author.notify_about?(@issue)
806 end
803 end
807
804
808 should "be false for a user with :only_owner and is not the author" do
805 should "be false for a user with :only_owner and is not the author" do
809 @assignee.update_attribute(:mail_notification, 'only_owner')
806 @assignee.update_attribute(:mail_notification, 'only_owner')
810 assert ! @assignee.notify_about?(@issue)
807 assert ! @assignee.notify_about?(@issue)
811 end
808 end
812
809
813 should "be true for a user with :selected and is the author" do
810 should "be true for a user with :selected and is the author" do
814 @author.update_attribute(:mail_notification, 'selected')
811 @author.update_attribute(:mail_notification, 'selected')
815 assert @author.notify_about?(@issue)
812 assert @author.notify_about?(@issue)
816 end
813 end
817
814
818 should "be true for a user with :selected and is the assignee" do
815 should "be true for a user with :selected and is the assignee" do
819 @assignee.update_attribute(:mail_notification, 'selected')
816 @assignee.update_attribute(:mail_notification, 'selected')
820 assert @assignee.notify_about?(@issue)
817 assert @assignee.notify_about?(@issue)
821 end
818 end
822
819
823 should "be false for a user with :selected and is not the author or assignee" do
820 should "be false for a user with :selected and is not the author or assignee" do
824 @user = User.generate_with_protected!(:mail_notification => 'selected')
821 @user = User.generate_with_protected!(:mail_notification => 'selected')
825 Member.create!(:user => @user, :project => @project, :role_ids => [1])
822 Member.create!(:user => @user, :project => @project, :role_ids => [1])
826 assert ! @user.notify_about?(@issue)
823 assert ! @user.notify_about?(@issue)
827 end
824 end
828 end
825 end
829
826
830 context "other events" do
827 context "other events" do
831 should 'be added and tested'
828 should 'be added and tested'
832 end
829 end
833 end
830 end
834
831
835 def test_salt_unsalted_passwords
832 def test_salt_unsalted_passwords
836 # Restore a user with an unsalted password
833 # Restore a user with an unsalted password
837 user = User.find(1)
834 user = User.find(1)
838 user.salt = nil
835 user.salt = nil
839 user.hashed_password = User.hash_password("unsalted")
836 user.hashed_password = User.hash_password("unsalted")
840 user.save!
837 user.save!
841
838
842 User.salt_unsalted_passwords!
839 User.salt_unsalted_passwords!
843
840
844 user.reload
841 user.reload
845 # Salt added
842 # Salt added
846 assert !user.salt.blank?
843 assert !user.salt.blank?
847 # Password still valid
844 # Password still valid
848 assert user.check_password?("unsalted")
845 assert user.check_password?("unsalted")
849 assert_equal user, User.try_to_login(user.login, "unsalted")
846 assert_equal user, User.try_to_login(user.login, "unsalted")
850 end
847 end
851
848
852 if Object.const_defined?(:OpenID)
849 if Object.const_defined?(:OpenID)
853
850
854 def test_setting_identity_url
851 def test_setting_identity_url
855 normalized_open_id_url = 'http://example.com/'
852 normalized_open_id_url = 'http://example.com/'
856 u = User.new( :identity_url => 'http://example.com/' )
853 u = User.new( :identity_url => 'http://example.com/' )
857 assert_equal normalized_open_id_url, u.identity_url
854 assert_equal normalized_open_id_url, u.identity_url
858 end
855 end
859
856
860 def test_setting_identity_url_without_trailing_slash
857 def test_setting_identity_url_without_trailing_slash
861 normalized_open_id_url = 'http://example.com/'
858 normalized_open_id_url = 'http://example.com/'
862 u = User.new( :identity_url => 'http://example.com' )
859 u = User.new( :identity_url => 'http://example.com' )
863 assert_equal normalized_open_id_url, u.identity_url
860 assert_equal normalized_open_id_url, u.identity_url
864 end
861 end
865
862
866 def test_setting_identity_url_without_protocol
863 def test_setting_identity_url_without_protocol
867 normalized_open_id_url = 'http://example.com/'
864 normalized_open_id_url = 'http://example.com/'
868 u = User.new( :identity_url => 'example.com' )
865 u = User.new( :identity_url => 'example.com' )
869 assert_equal normalized_open_id_url, u.identity_url
866 assert_equal normalized_open_id_url, u.identity_url
870 end
867 end
871
868
872 def test_setting_blank_identity_url
869 def test_setting_blank_identity_url
873 u = User.new( :identity_url => 'example.com' )
870 u = User.new( :identity_url => 'example.com' )
874 u.identity_url = ''
871 u.identity_url = ''
875 assert u.identity_url.blank?
872 assert u.identity_url.blank?
876 end
873 end
877
874
878 def test_setting_invalid_identity_url
875 def test_setting_invalid_identity_url
879 u = User.new( :identity_url => 'this is not an openid url' )
876 u = User.new( :identity_url => 'this is not an openid url' )
880 assert u.identity_url.blank?
877 assert u.identity_url.blank?
881 end
878 end
882
879
883 else
880 else
884 puts "Skipping openid tests."
881 puts "Skipping openid tests."
885 end
882 end
886
883
887 end
884 end
@@ -1,229 +1,229
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 VersionTest < ActiveSupport::TestCase
20 class VersionTest < ActiveSupport::TestCase
21 fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions
21 fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions
22
22
23 def setup
23 def setup
24 end
24 end
25
25
26 def test_create
26 def test_create
27 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
27 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
28 assert v.save
28 assert v.save
29 assert_equal 'open', v.status
29 assert_equal 'open', v.status
30 assert_equal 'none', v.sharing
30 assert_equal 'none', v.sharing
31 end
31 end
32
32
33 def test_invalid_effective_date_validation
33 def test_invalid_effective_date_validation
34 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
34 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
35 assert !v.save
35 assert !v.save
36 assert_equal I18n.translate('activerecord.errors.messages.not_a_date'),
36 assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
37 v.errors[:effective_date].to_s
37 v.errors[:effective_date]
38 end
38 end
39
39
40 def test_progress_should_be_0_with_no_assigned_issues
40 def test_progress_should_be_0_with_no_assigned_issues
41 project = Project.find(1)
41 project = Project.find(1)
42 v = Version.create!(:project => project, :name => 'Progress')
42 v = Version.create!(:project => project, :name => 'Progress')
43 assert_equal 0, v.completed_pourcent
43 assert_equal 0, v.completed_pourcent
44 assert_equal 0, v.closed_pourcent
44 assert_equal 0, v.closed_pourcent
45 end
45 end
46
46
47 def test_progress_should_be_0_with_unbegun_assigned_issues
47 def test_progress_should_be_0_with_unbegun_assigned_issues
48 project = Project.find(1)
48 project = Project.find(1)
49 v = Version.create!(:project => project, :name => 'Progress')
49 v = Version.create!(:project => project, :name => 'Progress')
50 add_issue(v)
50 add_issue(v)
51 add_issue(v, :done_ratio => 0)
51 add_issue(v, :done_ratio => 0)
52 assert_progress_equal 0, v.completed_pourcent
52 assert_progress_equal 0, v.completed_pourcent
53 assert_progress_equal 0, v.closed_pourcent
53 assert_progress_equal 0, v.closed_pourcent
54 end
54 end
55
55
56 def test_progress_should_be_100_with_closed_assigned_issues
56 def test_progress_should_be_100_with_closed_assigned_issues
57 project = Project.find(1)
57 project = Project.find(1)
58 status = IssueStatus.find(:first, :conditions => {:is_closed => true})
58 status = IssueStatus.find(:first, :conditions => {:is_closed => true})
59 v = Version.create!(:project => project, :name => 'Progress')
59 v = Version.create!(:project => project, :name => 'Progress')
60 add_issue(v, :status => status)
60 add_issue(v, :status => status)
61 add_issue(v, :status => status, :done_ratio => 20)
61 add_issue(v, :status => status, :done_ratio => 20)
62 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
62 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
63 add_issue(v, :status => status, :estimated_hours => 15)
63 add_issue(v, :status => status, :estimated_hours => 15)
64 assert_progress_equal 100.0, v.completed_pourcent
64 assert_progress_equal 100.0, v.completed_pourcent
65 assert_progress_equal 100.0, v.closed_pourcent
65 assert_progress_equal 100.0, v.closed_pourcent
66 end
66 end
67
67
68 def test_progress_should_consider_done_ratio_of_open_assigned_issues
68 def test_progress_should_consider_done_ratio_of_open_assigned_issues
69 project = Project.find(1)
69 project = Project.find(1)
70 v = Version.create!(:project => project, :name => 'Progress')
70 v = Version.create!(:project => project, :name => 'Progress')
71 add_issue(v)
71 add_issue(v)
72 add_issue(v, :done_ratio => 20)
72 add_issue(v, :done_ratio => 20)
73 add_issue(v, :done_ratio => 70)
73 add_issue(v, :done_ratio => 70)
74 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent
74 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent
75 assert_progress_equal 0, v.closed_pourcent
75 assert_progress_equal 0, v.closed_pourcent
76 end
76 end
77
77
78 def test_progress_should_consider_closed_issues_as_completed
78 def test_progress_should_consider_closed_issues_as_completed
79 project = Project.find(1)
79 project = Project.find(1)
80 v = Version.create!(:project => project, :name => 'Progress')
80 v = Version.create!(:project => project, :name => 'Progress')
81 add_issue(v)
81 add_issue(v)
82 add_issue(v, :done_ratio => 20)
82 add_issue(v, :done_ratio => 20)
83 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
83 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
84 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent
84 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent
85 assert_progress_equal (100.0)/3, v.closed_pourcent
85 assert_progress_equal (100.0)/3, v.closed_pourcent
86 end
86 end
87
87
88 def test_progress_should_consider_estimated_hours_to_weigth_issues
88 def test_progress_should_consider_estimated_hours_to_weigth_issues
89 project = Project.find(1)
89 project = Project.find(1)
90 v = Version.create!(:project => project, :name => 'Progress')
90 v = Version.create!(:project => project, :name => 'Progress')
91 add_issue(v, :estimated_hours => 10)
91 add_issue(v, :estimated_hours => 10)
92 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
92 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
93 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
93 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
94 add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
94 add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
95 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent
95 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent
96 assert_progress_equal 25.0/95.0*100, v.closed_pourcent
96 assert_progress_equal 25.0/95.0*100, v.closed_pourcent
97 end
97 end
98
98
99 def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
99 def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
100 project = Project.find(1)
100 project = Project.find(1)
101 v = Version.create!(:project => project, :name => 'Progress')
101 v = Version.create!(:project => project, :name => 'Progress')
102 add_issue(v, :done_ratio => 20)
102 add_issue(v, :done_ratio => 20)
103 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
103 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
104 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
104 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
105 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
105 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
106 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_pourcent
106 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_pourcent
107 assert_progress_equal 25.0/100.0*100, v.closed_pourcent
107 assert_progress_equal 25.0/100.0*100, v.closed_pourcent
108 end
108 end
109
109
110 context "#behind_schedule?" do
110 context "#behind_schedule?" do
111 setup do
111 setup do
112 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
112 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
113 @project = Project.create!(:name => 'test0', :identifier => 'test0')
113 @project = Project.create!(:name => 'test0', :identifier => 'test0')
114 @project.trackers << Tracker.create!(:name => 'track')
114 @project.trackers << Tracker.create!(:name => 'track')
115
115
116 @version = Version.create!(:project => @project, :effective_date => nil, :name => 'version')
116 @version = Version.create!(:project => @project, :effective_date => nil, :name => 'version')
117 end
117 end
118
118
119 should "be false if there are no issues assigned" do
119 should "be false if there are no issues assigned" do
120 @version.update_attribute(:effective_date, Date.yesterday)
120 @version.update_attribute(:effective_date, Date.yesterday)
121 assert_equal false, @version.behind_schedule?
121 assert_equal false, @version.behind_schedule?
122 end
122 end
123
123
124 should "be false if there is no effective_date" do
124 should "be false if there is no effective_date" do
125 assert_equal false, @version.behind_schedule?
125 assert_equal false, @version.behind_schedule?
126 end
126 end
127
127
128 should "be false if all of the issues are ahead of schedule" do
128 should "be false if all of the issues are ahead of schedule" do
129 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
129 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
130 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
130 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
131 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
131 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
132 assert_equal 60, @version.completed_pourcent
132 assert_equal 60, @version.completed_pourcent
133 assert_equal false, @version.behind_schedule?
133 assert_equal false, @version.behind_schedule?
134 end
134 end
135
135
136 should "be true if any of the issues are behind schedule" do
136 should "be true if any of the issues are behind schedule" do
137 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
137 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
138 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
138 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
139 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
139 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
140 assert_equal 40, @version.completed_pourcent
140 assert_equal 40, @version.completed_pourcent
141 assert_equal true, @version.behind_schedule?
141 assert_equal true, @version.behind_schedule?
142 end
142 end
143
143
144 should "be false if all of the issues are complete" do
144 should "be false if all of the issues are complete" do
145 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
145 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
146 add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
146 add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
147 add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
147 add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
148 assert_equal 100, @version.completed_pourcent
148 assert_equal 100, @version.completed_pourcent
149 assert_equal false, @version.behind_schedule?
149 assert_equal false, @version.behind_schedule?
150 end
150 end
151 end
151 end
152
152
153 context "#estimated_hours" do
153 context "#estimated_hours" do
154 setup do
154 setup do
155 @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
155 @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
156 end
156 end
157
157
158 should "return 0 with no assigned issues" do
158 should "return 0 with no assigned issues" do
159 assert_equal 0, @version.estimated_hours
159 assert_equal 0, @version.estimated_hours
160 end
160 end
161
161
162 should "return 0 with no estimated hours" do
162 should "return 0 with no estimated hours" do
163 add_issue(@version)
163 add_issue(@version)
164 assert_equal 0, @version.estimated_hours
164 assert_equal 0, @version.estimated_hours
165 end
165 end
166
166
167 should "return the sum of estimated hours" do
167 should "return the sum of estimated hours" do
168 add_issue(@version, :estimated_hours => 2.5)
168 add_issue(@version, :estimated_hours => 2.5)
169 add_issue(@version, :estimated_hours => 5)
169 add_issue(@version, :estimated_hours => 5)
170 assert_equal 7.5, @version.estimated_hours
170 assert_equal 7.5, @version.estimated_hours
171 end
171 end
172
172
173 should "return the sum of leaves estimated hours" do
173 should "return the sum of leaves estimated hours" do
174 parent = add_issue(@version)
174 parent = add_issue(@version)
175 add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
175 add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
176 add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
176 add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
177 assert_equal 7.5, @version.estimated_hours
177 assert_equal 7.5, @version.estimated_hours
178 end
178 end
179 end
179 end
180
180
181 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
181 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
182 User.current = User.find(1) # Need the admin's permissions
182 User.current = User.find(1) # Need the admin's permissions
183
183
184 @version = Version.find(7)
184 @version = Version.find(7)
185 # Separate hierarchy
185 # Separate hierarchy
186 project_1_issue = Issue.find(1)
186 project_1_issue = Issue.find(1)
187 project_1_issue.fixed_version = @version
187 project_1_issue.fixed_version = @version
188 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
188 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
189
189
190 project_5_issue = Issue.find(6)
190 project_5_issue = Issue.find(6)
191 project_5_issue.fixed_version = @version
191 project_5_issue.fixed_version = @version
192 assert project_5_issue.save
192 assert project_5_issue.save
193
193
194 # Project
194 # Project
195 project_2_issue = Issue.find(4)
195 project_2_issue = Issue.find(4)
196 project_2_issue.fixed_version = @version
196 project_2_issue.fixed_version = @version
197 assert project_2_issue.save
197 assert project_2_issue.save
198
198
199 # Update the sharing
199 # Update the sharing
200 @version.sharing = 'none'
200 @version.sharing = 'none'
201 assert @version.save
201 assert @version.save
202
202
203 # Project 1 now out of the shared scope
203 # Project 1 now out of the shared scope
204 project_1_issue.reload
204 project_1_issue.reload
205 assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
205 assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
206
206
207 # Project 5 now out of the shared scope
207 # Project 5 now out of the shared scope
208 project_5_issue.reload
208 project_5_issue.reload
209 assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
209 assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
210
210
211 # Project 2 issue remains
211 # Project 2 issue remains
212 project_2_issue.reload
212 project_2_issue.reload
213 assert_equal @version, project_2_issue.fixed_version
213 assert_equal @version, project_2_issue.fixed_version
214 end
214 end
215
215
216 private
216 private
217
217
218 def add_issue(version, attributes={})
218 def add_issue(version, attributes={})
219 Issue.create!({:project => version.project,
219 Issue.create!({:project => version.project,
220 :fixed_version => version,
220 :fixed_version => version,
221 :subject => 'Test',
221 :subject => 'Test',
222 :author => User.find(:first),
222 :author => User.find(:first),
223 :tracker => version.project.trackers.find(:first)}.merge(attributes))
223 :tracker => version.project.trackers.find(:first)}.merge(attributes))
224 end
224 end
225
225
226 def assert_progress_equal(expected_float, actual_float, message="")
226 def assert_progress_equal(expected_float, actual_float, message="")
227 assert_in_delta(expected_float, actual_float, 0.000001, message="")
227 assert_in_delta(expected_float, actual_float, 0.000001, message="")
228 end
228 end
229 end
229 end
@@ -1,134 +1,134
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 WikiPageTest < ActiveSupport::TestCase
20 class WikiPageTest < ActiveSupport::TestCase
21 fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
21 fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
22
22
23 def setup
23 def setup
24 @wiki = Wiki.find(1)
24 @wiki = Wiki.find(1)
25 @page = @wiki.pages.first
25 @page = @wiki.pages.first
26 end
26 end
27
27
28 def test_create
28 def test_create
29 page = WikiPage.new(:wiki => @wiki)
29 page = WikiPage.new(:wiki => @wiki)
30 assert !page.save
30 assert !page.save
31 assert_equal 1, page.errors.count
31 assert_equal 1, page.errors.count
32
32
33 page.title = "Page"
33 page.title = "Page"
34 assert page.save
34 assert page.save
35 page.reload
35 page.reload
36 assert !page.protected?
36 assert !page.protected?
37
37
38 @wiki.reload
38 @wiki.reload
39 assert @wiki.pages.include?(page)
39 assert @wiki.pages.include?(page)
40 end
40 end
41
41
42 def test_sidebar_should_be_protected_by_default
42 def test_sidebar_should_be_protected_by_default
43 page = @wiki.find_or_new_page('sidebar')
43 page = @wiki.find_or_new_page('sidebar')
44 assert page.new_record?
44 assert page.new_record?
45 assert page.protected?
45 assert page.protected?
46 end
46 end
47
47
48 def test_find_or_new_page
48 def test_find_or_new_page
49 page = @wiki.find_or_new_page("CookBook documentation")
49 page = @wiki.find_or_new_page("CookBook documentation")
50 assert_kind_of WikiPage, page
50 assert_kind_of WikiPage, page
51 assert !page.new_record?
51 assert !page.new_record?
52
52
53 page = @wiki.find_or_new_page("Non existing page")
53 page = @wiki.find_or_new_page("Non existing page")
54 assert_kind_of WikiPage, page
54 assert_kind_of WikiPage, page
55 assert page.new_record?
55 assert page.new_record?
56 end
56 end
57
57
58 def test_parent_title
58 def test_parent_title
59 page = WikiPage.find_by_title('Another_page')
59 page = WikiPage.find_by_title('Another_page')
60 assert_nil page.parent_title
60 assert_nil page.parent_title
61
61
62 page = WikiPage.find_by_title('Page_with_an_inline_image')
62 page = WikiPage.find_by_title('Page_with_an_inline_image')
63 assert_equal 'CookBook documentation', page.parent_title
63 assert_equal 'CookBook documentation', page.parent_title
64 end
64 end
65
65
66 def test_assign_parent
66 def test_assign_parent
67 page = WikiPage.find_by_title('Another_page')
67 page = WikiPage.find_by_title('Another_page')
68 page.parent_title = 'CookBook documentation'
68 page.parent_title = 'CookBook documentation'
69 assert page.save
69 assert page.save
70 page.reload
70 page.reload
71 assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
71 assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
72 end
72 end
73
73
74 def test_unassign_parent
74 def test_unassign_parent
75 page = WikiPage.find_by_title('Page_with_an_inline_image')
75 page = WikiPage.find_by_title('Page_with_an_inline_image')
76 page.parent_title = ''
76 page.parent_title = ''
77 assert page.save
77 assert page.save
78 page.reload
78 page.reload
79 assert_nil page.parent
79 assert_nil page.parent
80 end
80 end
81
81
82 def test_parent_validation
82 def test_parent_validation
83 page = WikiPage.find_by_title('CookBook_documentation')
83 page = WikiPage.find_by_title('CookBook_documentation')
84
84
85 # A page that doesn't exist
85 # A page that doesn't exist
86 page.parent_title = 'Unknown title'
86 page.parent_title = 'Unknown title'
87 assert !page.save
87 assert !page.save
88 assert_equal I18n.translate('activerecord.errors.messages.invalid'),
88 assert_include I18n.translate('activerecord.errors.messages.invalid'),
89 page.errors[:parent_title].to_s
89 page.errors[:parent_title]
90 # A child page
90 # A child page
91 page.parent_title = 'Page_with_an_inline_image'
91 page.parent_title = 'Page_with_an_inline_image'
92 assert !page.save
92 assert !page.save
93 assert_equal I18n.translate('activerecord.errors.messages.circular_dependency'),
93 assert_include I18n.translate('activerecord.errors.messages.circular_dependency'),
94 page.errors[:parent_title].to_s
94 page.errors[:parent_title]
95 # The page itself
95 # The page itself
96 page.parent_title = 'CookBook_documentation'
96 page.parent_title = 'CookBook_documentation'
97 assert !page.save
97 assert !page.save
98 assert_equal I18n.translate('activerecord.errors.messages.circular_dependency'),
98 assert_include I18n.translate('activerecord.errors.messages.circular_dependency'),
99 page.errors[:parent_title].to_s
99 page.errors[:parent_title]
100 page.parent_title = 'Another_page'
100 page.parent_title = 'Another_page'
101 assert page.save
101 assert page.save
102 end
102 end
103
103
104 def test_destroy
104 def test_destroy
105 page = WikiPage.find(1)
105 page = WikiPage.find(1)
106 page.destroy
106 page.destroy
107 assert_nil WikiPage.find_by_id(1)
107 assert_nil WikiPage.find_by_id(1)
108 # make sure that page content and its history are deleted
108 # make sure that page content and its history are deleted
109 assert WikiContent.find_all_by_page_id(1).empty?
109 assert WikiContent.find_all_by_page_id(1).empty?
110 assert WikiContent.versioned_class.find_all_by_page_id(1).empty?
110 assert WikiContent.versioned_class.find_all_by_page_id(1).empty?
111 end
111 end
112
112
113 def test_destroy_should_not_nullify_children
113 def test_destroy_should_not_nullify_children
114 page = WikiPage.find(2)
114 page = WikiPage.find(2)
115 child_ids = page.child_ids
115 child_ids = page.child_ids
116 assert child_ids.any?
116 assert child_ids.any?
117 page.destroy
117 page.destroy
118 assert_nil WikiPage.find_by_id(2)
118 assert_nil WikiPage.find_by_id(2)
119
119
120 children = WikiPage.find_all_by_id(child_ids)
120 children = WikiPage.find_all_by_id(child_ids)
121 assert_equal child_ids.size, children.size
121 assert_equal child_ids.size, children.size
122 children.each do |child|
122 children.each do |child|
123 assert_nil child.parent_id
123 assert_nil child.parent_id
124 end
124 end
125 end
125 end
126
126
127 def test_updated_on_eager_load
127 def test_updated_on_eager_load
128 page = WikiPage.with_updated_on.first(:order => 'id')
128 page = WikiPage.with_updated_on.first(:order => 'id')
129 assert page.is_a?(WikiPage)
129 assert page.is_a?(WikiPage)
130 assert_not_nil page.read_attribute(:updated_on)
130 assert_not_nil page.read_attribute(:updated_on)
131 assert_equal Time.gm(2007, 3, 6, 23, 10, 51), page.content.updated_on
131 assert_equal Time.gm(2007, 3, 6, 23, 10, 51), page.content.updated_on
132 assert_equal page.content.updated_on, page.updated_on
132 assert_equal page.content.updated_on, page.updated_on
133 end
133 end
134 end
134 end
General Comments 0
You need to be logged in to leave comments. Login now