changed properties and the name of hyperchad to selectricity
[selectricity-live] / vendor / plugins / login_engine / test / functional / user_controller_test.rb
1 require File.dirname(__FILE__) + '/../test_helper'
2 require_dependency 'user_controller'
3
4
5 # Raise errors beyond the default web-based presentation
6 class UserController; def rescue_action(e) raise e end; end
7
8 class UserControllerTest < Test::Unit::TestCase
9   
10   # load the fixture into the developer-specified table using the custom
11   # 'fixture' method.
12   fixture :users, :table_name => LoginEngine.config(:user_table), :class_name => "User"
13   
14   def setup
15     
16     LoginEngine::CONFIG[:salt] = "test-salt"
17     
18     @controller = UserController.new
19     @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
20     @request.host = "localhost"
21   end
22
23
24   
25   #==========================================================================
26   #
27   # Login/Logout
28   #
29   #==========================================================================
30
31   def test_home_without_login
32     get :home
33     assert_redirected_to :action => "login"
34   end
35
36   def test_invalid_login
37     post :login, :user => { :login => "bob", :password => "wrong_password" }
38     assert_response :success
39
40     assert_session_has_no :user
41     assert_template "login"
42   end
43  
44   def test_login
45     @request.session['return-to'] = "/bogus/location"
46
47     post :login, :user => { :login => "bob", :password => "atest" }
48     
49     assert_response 302  # redirect
50     assert_session_has :user
51     assert_equal users(:bob), session[:user]
52     
53     assert_redirect_url "http://#{@request.host}/bogus/location"
54   end
55
56   def test_login_logoff
57
58     post :login, :user => { :login => "bob", :password => "atest" }
59     assert_session_has :user
60
61     get :logout
62     assert_session_has_no :user
63
64   end
65
66
67   #==========================================================================
68   #
69   # Signup
70   #
71   #==========================================================================
72
73   def test_signup
74     LoginEngine::CONFIG[:use_email_notification] = true
75
76     ActionMailer::Base.deliveries = []
77
78     @request.session['return-to'] = "/bogus/location"
79
80     assert_equal 5, User.count
81     post :signup, :user => { :login => "newbob", :password => "newpassword", :password_confirmation => "newpassword", :email => "newbob@test.com" }
82     assert_session_has_no :user
83
84     assert_redirect_url(@controller.url_for(:action => "login"))
85     assert_equal 1, ActionMailer::Base.deliveries.size
86     mail = ActionMailer::Base.deliveries[0]
87     assert_equal "newbob@test.com", mail.to_addrs[0].to_s
88     assert_match /login:\s+\w+\n/, mail.encoded
89     assert_match /password:\s+\w+\n/, mail.encoded
90     #mail.encoded =~ /user_id=(.*?)&key=(.*?)"/
91     user_id = /user_id=(\d+)/.match(mail.encoded)[1]
92     key = /key=([a-z0-9]+)/.match(mail.encoded)[1]
93
94     assert_not_nil user_id
95     assert_not_nil key
96
97     user = User.find_by_email("newbob@test.com")
98     assert_not_nil user
99     assert_equal 0, user.verified
100
101     # First past the expiration.
102     Time.advance_by_days = 1
103     get :home, :user_id => "#{user_id}", :key => "#{key}"
104     Time.advance_by_days = 0
105     user = User.find_by_email("newbob@test.com")
106     assert_equal 0, user.verified
107
108     # Then a bogus key.
109     get :home, :user_id => "#{user_id}", :key => "boguskey"
110     user = User.find_by_email("newbob@test.com")
111     assert_equal 0, user.verified
112
113     # Now the real one.
114     get :home, :user_id => "#{user_id}", :key => "#{key}"
115     user = User.find_by_email("newbob@test.com")
116     assert_equal 1, user.verified
117
118     post :login, :user => { :login => "newbob", :password => "newpassword" }
119     assert_session_has :user
120     get :logout
121
122   end
123   
124   def test_signup_bad_password
125     LoginEngine::CONFIG[:use_email_notification] = true
126     ActionMailer::Base.deliveries = []
127
128     @request.session['return-to'] = "/bogus/location"
129     post :signup, :user => { :login => "newbob", :password => "bad", :password_confirmation => "bad", :email => "newbob@test.com" }
130     assert_session_has_no :user
131     assert_invalid_column_on_record "user", "password"
132     assert_success
133     assert_equal 0, ActionMailer::Base.deliveries.size
134   end
135   
136   def test_signup_bad_email
137     LoginEngine::CONFIG[:use_email_notification] = true
138     ActionMailer::Base.deliveries = []
139
140     @request.session['return-to'] = "/bogus/location"
141
142     ActionMailer::Base.inject_one_error = true
143     post :signup, :user => { :login => "newbob", :password => "newpassword", :password_confirmation => "newpassword", :email => "newbob@test.com" }
144     assert_session_has_no :user
145     assert_equal 0, ActionMailer::Base.deliveries.size
146   end
147
148   def test_signup_without_email
149     LoginEngine::CONFIG[:use_email_notification] = false
150     
151     @request.session['return-to'] = "/bogus/location"
152
153     post :signup, :user => { :login => "newbob", :password => "newpassword", :password_confirmation => "newpassword", :email => "newbob@test.com" }
154
155     assert_redirect_url(@controller.url_for(:action => "login"))    
156     assert_session_has_no :user
157     assert_match /Signup successful/, flash[:notice]
158     
159     assert_not_nil User.find_by_login("newbob")
160     
161     user = User.find_by_email("newbob@test.com")
162     assert_not_nil user
163     
164     post :login, :user => { :login => "newbob", :password => "newpassword" }
165     assert_session_has :user
166     get :logout    
167   end
168
169   def test_signup_bad_details
170     @request.session['return-to'] = "/bogus/location"
171
172     # mismatched password
173     post :signup, :user => { :login => "newbob", :password => "newpassword", :password_confirmation => "wrong" }
174     assert_invalid_column_on_record "user", "password"
175     assert_success
176     
177     # login not long enough
178     post :signup, :user => { :login => "yo", :password => "newpassword", :password_confirmation => "newpassword" }
179     assert_invalid_column_on_record "user", "login"
180     assert_success
181
182     # both
183     post :signup, :user => { :login => "yo", :password => "newpassword", :password_confirmation => "wrong" }
184     assert_invalid_column_on_record "user", ["login", "password"]
185     assert_success
186     
187     # existing user
188     post :signup, :user => { :login => "bob", :password => "doesnt_matter", :password_confirmation => "doesnt_matter" }
189     assert_invalid_column_on_record "user", "login"
190     assert_success
191
192     # existing email
193     post :signup, :user => { :login => "newbob", :email => "longbob@test.com", :password => "doesnt_matter", :password_confirmation => "doesnt_matter" }
194     assert_invalid_column_on_record "user", "email"
195     assert_success
196
197   end
198   
199
200   #==========================================================================
201   #
202   # Edit
203   #
204   #==========================================================================
205   
206   def test_edit
207     post :login, :user => { :login => "bob", :password => "atest" }
208     assert_session_has :user
209
210     post :edit, :user => { "firstname" => "Bob", "form" => "edit" }
211     assert_equal @response.session[:user].firstname, "Bob"
212
213     post :edit, :user => { "firstname" => "", "form" => "edit" }
214     assert_equal @response.session[:user].firstname, ""
215
216     get :logout
217   end
218
219
220
221   #==========================================================================
222   #
223   # Delete
224   #
225   #==========================================================================
226
227   def test_delete
228     LoginEngine::CONFIG[:use_email_notification] = true
229     # Immediate delete
230     post :login, :user => { :login => "deletebob1", :password => "alongtest" }
231     assert_session_has :user
232
233     LoginEngine.config :delayed_delete, false, :force
234     post :delete
235     assert_equal 1, ActionMailer::Base.deliveries.size
236     assert_session_has_no :user
237     
238     # try and login in again, we should fail.
239     post :login, :user => { :login => "deletebob1", :password => "alongtest" }
240     assert_session_has_no :user
241     assert_template_has "login"
242     
243
244     # Now try delayed delete
245     ActionMailer::Base.deliveries = []
246
247     post :login, :user => { :login => "deletebob2", :password => "alongtest" }
248     assert_session_has :user
249
250     LoginEngine.config :delayed_delete, true, :force
251     post :delete
252     assert_equal 1, ActionMailer::Base.deliveries.size
253     mail = ActionMailer::Base.deliveries[0]
254     user_id = /user_id=(\d+)/.match(mail.encoded)[1]
255     key = /key=([a-z0-9]+)/.match(mail.encoded)[1]
256     
257     post :restore_deleted, :user_id => "#{user_id}", "key" => "badkey"
258     assert_session_has_no :user
259
260     # Advance the time past the delete date
261     Time.advance_by_days = LoginEngine.config :delayed_delete_days
262     post :restore_deleted, :user_id => "#{user_id}", "key" => "#{key}"
263     assert_session_has_no :user
264     Time.advance_by_days = 0
265
266     post :restore_deleted, :user_id => "#{user_id}", "key" => "#{key}"
267     assert_session_has :user      
268   end
269   
270   def test_delete_without_email
271     LoginEngine::CONFIG[:use_email_notification] = false
272     ActionMailer::Base.deliveries = []
273
274     # Immediate delete
275     post :login, :user => { :login => "deletebob1", :password => "alongtest" }
276     assert_session_has :user
277
278     LoginEngine.config :delayed_delete, false, :force
279     post :delete
280     assert_session_has_no :user
281     assert_nil User.find_by_login("deletebob1")
282     
283     # try and login in again, we should fail.
284     post :login, :user => { :login => "deletebob1", :password => "alongtest" }
285     assert_session_has_no :user
286     assert_template_has "login"
287     
288
289     # Now try delayed delete
290     ActionMailer::Base.deliveries = []
291
292     post :login, :user => { :login => "deletebob2", :password => "alongtest" }
293     assert_session_has :user
294
295     # delayed delete is not really relevant currently without email.
296     LoginEngine.config :delayed_delete, true, :force
297     post :delete
298     assert_equal 1, User.find_by_login("deletebob2").deleted
299   end
300
301
302
303   #==========================================================================
304   #
305   # Change Password
306   #
307   #==========================================================================
308
309   def test_change_valid_password
310     
311     LoginEngine::CONFIG[:use_email_notification] = true
312     
313     ActionMailer::Base.deliveries = []
314
315     post :login, :user => { :login => "bob", :password => "atest" }
316     assert_session_has :user
317
318     post :change_password, :user => { :password => "changed_password", :password_confirmation => "changed_password" }
319     
320     assert_equal 1, ActionMailer::Base.deliveries.size
321     mail = ActionMailer::Base.deliveries[0]
322     assert_equal "bob@test.com", mail.to_addrs[0].to_s
323     assert_match /login:\s+\w+\n/, mail.encoded
324     assert_match /password:\s+\w+\n/, mail.encoded
325
326     post :login, :user => { :login => "bob", :password => "changed_password" }
327     assert_session_has :user
328     post :change_password, :user => { :password => "atest", :password_confirmation => "atest" }
329     get :logout
330
331     post :login, :user => { :login => "bob", :password => "atest" }
332     assert_session_has :user
333
334     get :logout
335   end
336
337   def test_change_valid_password_without_email
338     
339     LoginEngine::CONFIG[:use_email_notification] = false
340     
341     ActionMailer::Base.deliveries = []
342
343     post :login, :user => { :login => "bob", :password => "atest" }
344     assert_session_has :user
345
346     post :change_password, :user => { :password => "changed_password", :password_confirmation => "changed_password" }
347     
348     assert_redirected_to :action => "change_password"
349
350     post :login, :user => { :login => "bob", :password => "changed_password" }
351     assert_session_has :user
352     post :change_password, :user => { :password => "atest", :password_confirmation => "atest" }
353     get :logout
354
355     post :login, :user => { :login => "bob", :password => "atest" }
356     assert_session_has :user
357
358     get :logout
359   end
360
361   def test_change_short_password
362     LoginEngine::CONFIG[:use_email_notification] = true
363     ActionMailer::Base.deliveries = []
364
365     post :login, :user => { :login => "bob", :password => "atest" }
366     assert_session_has :user
367
368     post :change_password, :user => { :password => "bad", :password_confirmation => "bad" }
369     assert_invalid_column_on_record "user", "password"
370     assert_success
371     assert_equal 0, ActionMailer::Base.deliveries.size    
372
373     post :login, :user => { :login => "bob", :password => "atest" }
374     assert_session_has :user
375
376     get :logout
377   end
378   
379   def test_change_short_password_without_email
380     LoginEngine::CONFIG[:use_email_notification] = false
381     post :login, :user => { :login => "bob", :password => "atest" }
382     assert_session_has :user
383
384     post :change_password, :user => { :password => "bad", :password_confirmation => "bad" }
385     assert_invalid_column_on_record "user", "password"
386     assert_success
387
388     post :login, :user => { :login => "bob", :password => "atest" }
389     assert_session_has :user
390
391     get :logout
392   end
393
394
395   def test_change_password_with_bad_email
396     LoginEngine::CONFIG[:use_email_notification] = true
397     ActionMailer::Base.deliveries = []
398     
399     # log in
400     post :login, :user => { :login => "bob", :password => "atest" }
401     assert_session_has :user
402
403     # change the password, but the email delivery will fail
404     ActionMailer::Base.inject_one_error = true
405     post :change_password, :user => { :password => "changed_password", :password_confirmation => "changed_password" }
406     assert_equal 0, ActionMailer::Base.deliveries.size
407     assert_match /Password could not be changed/, flash[:warning]
408     
409     # logout
410     get :logout
411     assert_session_has_no :user
412
413     # ensure we can log in with our original password
414     # TODO: WHY DOES THIS FAIL!! It looks like the transaction stuff in UserController#change_password isn't actually rolling back changes.
415     post :login, :user => { :login => "bob", :password => "atest" }
416     assert_session_has :user
417
418     get :logout
419   end
420
421
422
423
424   #==========================================================================
425   #
426   # Forgot Password
427   #
428   #==========================================================================
429
430   def test_forgot_password
431     LoginEngine::CONFIG[:use_email_notification] = true
432
433     do_forgot_password(false, false, false)
434     do_forgot_password(false, false, true)
435     do_forgot_password(true, false, false)
436     do_forgot_password(false, true, false)
437   end
438   
439   def do_forgot_password(bad_address, bad_email, logged_in)
440     ActionMailer::Base.deliveries = []
441
442     if logged_in
443       post :login, :user => { :login => "bob", :password => "atest" }
444       assert_session_has :user
445     end
446
447     @request.session['return-to'] = "/bogus/location"
448     if not bad_address and not bad_email
449       post :forgot_password, :user => { :email => "bob@test.com" }
450       password = "anewpassword"
451       if logged_in
452         assert_equal 0, ActionMailer::Base.deliveries.size
453         assert_redirect_url(@controller.url_for(:action => "change_password"))
454         post :change_password, :user => { :password => "#{password}", :password_confirmation => "#{password}" }
455       else
456         assert_equal 1, ActionMailer::Base.deliveries.size
457         mail = ActionMailer::Base.deliveries[0]
458         assert_equal "bob@test.com", mail.to_addrs[0].to_s
459         user_id = /user_id=(\d+)/.match(mail.encoded)[1]
460         key = /key=([a-z0-9]+)/.match(mail.encoded)[1]
461         post :change_password, :user => { :password => "#{password}", :password_confirmation => "#{password}"}, :user_id => "#{user_id}", :key => "#{key}"
462         assert_session_has :user
463         get :logout
464       end
465     elsif bad_address
466       post :forgot_password, :user => { :email => "bademail@test.com" }
467       assert_equal 0, ActionMailer::Base.deliveries.size
468     elsif bad_email
469       ActionMailer::Base.inject_one_error = true
470       post :forgot_password, :user => { :email => "bob@test.com" }
471       assert_equal 0, ActionMailer::Base.deliveries.size
472     else
473       # Invalid test case
474       assert false
475     end
476
477     if not bad_address and not bad_email
478       if logged_in
479         get :logout
480       else
481         assert_redirect_url(@controller.url_for(:action => "login"))
482       end
483       post :login, :user => { :login => "bob", :password => "#{password}" }
484     else
485       # Okay, make sure the database did not get changed
486       if logged_in
487         get :logout
488       end
489       post :login, :user => { :login => "bob", :password => "atest" }
490     end
491
492     assert_session_has :user
493
494     # Put the old settings back
495     if not bad_address and not bad_email
496       post :change_password, :user => { :password => "atest", :password_confirmation => "atest" }
497     end
498     
499     get :logout
500   end
501
502   def test_forgot_password_without_email_and_logged_in
503     LoginEngine::CONFIG[:use_email_notification] = false
504
505     post :login, :user => { :login => "bob", :password => "atest" }
506     assert_session_has :user
507
508     @request.session['return-to'] = "/bogus/location"
509     post :forgot_password, :user => { :email => "bob@test.com" }
510     password = "anewpassword"
511     assert_redirect_url(@controller.url_for(:action => "change_password"))
512     post :change_password, :user => { :password => "#{password}", :password_confirmation => "#{password}" }
513
514     get :logout
515
516     post :login, :user => { :login => "bob", :password => "#{password}" }
517
518     assert_session_has :user
519     
520     get :logout
521   end
522
523   def forgot_password_without_email_and_not_logged_in
524     LoginEngine::CONFIG[:use_email_notification] = false
525
526     @request.session['return-to'] = "/bogus/location"
527     post :forgot_password, :user => { :email => "bob@test.com" }
528     password = "anewpassword"
529
530     # wothout email, you can't retrieve your forgotten password...
531     assert_match /Please contact the system admin/, flash[:message]
532     assert_session_has_no :user
533
534     assert_redirect_url "http://#{@request.host}/bogus/location"
535   end  
536 end

Benjamin Mako Hill || Want to submit a patch?