thoughtbot-clearance 0.3.8 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. data/README.textile +17 -16
  2. data/Rakefile +8 -7
  3. data/TODO.textile +3 -3
  4. data/generators/clearance/clearance_generator.rb +1 -1
  5. data/generators/clearance/templates/app/views/clearance_mailer/change_password.html.erb +1 -1
  6. data/generators/clearance/templates/app/views/passwords/edit.html.erb +1 -1
  7. data/generators/clearance/templates/app/views/sessions/new.html.erb +2 -2
  8. data/generators/clearance/templates/db/migrate/create_users_with_clearance_columns.rb +3 -3
  9. data/generators/clearance/templates/db/migrate/update_users_with_clearance_columns.rb +14 -13
  10. data/generators/clearance/templates/test/factories/clearance.rb +16 -0
  11. data/lib/clearance/app/controllers/application_controller.rb +26 -14
  12. data/lib/clearance/app/controllers/confirmations_controller.rb +6 -3
  13. data/lib/clearance/app/controllers/passwords_controller.rb +15 -9
  14. data/lib/clearance/app/controllers/sessions_controller.rb +21 -17
  15. data/lib/clearance/app/controllers/users_controller.rb +4 -3
  16. data/lib/clearance/app/models/clearance_mailer.rb +1 -1
  17. data/lib/clearance/app/models/user.rb +15 -16
  18. data/lib/clearance/test/functional/confirmations_controller_test.rb +18 -30
  19. data/lib/clearance/test/functional/passwords_controller_test.rb +27 -45
  20. data/lib/clearance/test/functional/sessions_controller_test.rb +23 -27
  21. data/lib/clearance/test/functional/users_controller_test.rb +38 -28
  22. data/lib/clearance/test/test_helper.rb +7 -2
  23. data/lib/clearance/test/unit/clearance_mailer_test.rb +7 -5
  24. data/lib/clearance/test/unit/user_test.rb +107 -138
  25. data/shoulda_macros/clearance.rb +134 -6
  26. metadata +7 -3
  27. data/generators/clearance/templates/test/factories/clearance_user.rb +0 -9
@@ -5,8 +5,8 @@ module Clearance
5
5
 
6
6
  def self.included(controller)
7
7
  controller.class_eval do
8
- before_filter :redirect_to_root, :only => [:new, :create], :if => :logged_in?
9
-
8
+
9
+ before_filter :redirect_to_root, :only => [:new, :create], :if => :signed_in?
10
10
  filter_parameter_logging :password
11
11
 
12
12
  def new
@@ -17,7 +17,8 @@ module Clearance
17
17
  @user = User.new params[:user]
18
18
  if @user.save
19
19
  ClearanceMailer.deliver_confirmation @user
20
- flash[:notice] = "You will receive an email within the next few minutes. It contains instructions for you to confirm your account."
20
+ flash[:notice] = "You will receive an email within the next few minutes. " <<
21
+ "It contains instructions for you to confirm your account."
21
22
  redirect_to url_after_create
22
23
  else
23
24
  render :action => "new"
@@ -14,8 +14,8 @@ module Clearance
14
14
  end
15
15
 
16
16
  def confirmation(user)
17
- recipients user.email
18
17
  from DO_NOT_REPLY
18
+ recipients user.email
19
19
  subject "Account confirmation"
20
20
  body :user => user
21
21
  end
@@ -17,27 +17,22 @@ module Clearance
17
17
  validates_uniqueness_of :email, :case_sensitive => false
18
18
  validates_format_of :email, :with => %r{.+@.+\..+}
19
19
 
20
- before_save :initialize_salt, :encrypt_password
20
+ before_save :initialize_salt, :encrypt_password, :downcase_email
21
21
 
22
22
  def self.authenticate(email, password)
23
23
  user = find(:first, :conditions => ['LOWER(email) = ?', email.to_s.downcase])
24
24
  user && user.authenticated?(password) ? user : nil
25
25
  end
26
-
27
- def email=(value)
28
- value = value.to_s.downcase if value
29
- write_attribute(:email, value.to_s)
30
- end
31
26
 
32
27
  def authenticated?(password)
33
- crypted_password == encrypt(password)
28
+ encrypted_password == encrypt(password)
34
29
  end
35
30
 
36
- def encrypt(password)
37
- Digest::SHA512.hexdigest "--#{salt}--#{password}--"
31
+ def encrypt(string)
32
+ Digest::SHA512.hexdigest("--#{salt}--#{string}--")
38
33
  end
39
34
 
40
- def remember_token?
35
+ def remember?
41
36
  remember_token_expires_at && Time.now.utc < remember_token_expires_at
42
37
  end
43
38
 
@@ -48,7 +43,7 @@ module Clearance
48
43
  def remember_me_until(time)
49
44
  self.update_attribute :remember_token_expires_at, time
50
45
  self.update_attribute :remember_token,
51
- encrypt("#{email}--#{remember_token_expires_at}")
46
+ encrypt("--#{remember_token_expires_at}--#{password}--")
52
47
  end
53
48
 
54
49
  def forget_me!
@@ -56,25 +51,29 @@ module Clearance
56
51
  self.update_attribute :remember_token, nil
57
52
  end
58
53
 
59
- def confirm!
60
- self.update_attribute :confirmed, true
54
+ def confirm_email!
55
+ self.update_attribute :email_confirmed, true
61
56
  end
62
57
 
63
58
  protected
64
59
 
65
60
  def initialize_salt
66
61
  if new_record?
67
- self.salt = Digest::SHA512.hexdigest("--#{Time.now.to_s}--#{email}--")
62
+ self.salt = encrypt("--#{Time.now.utc.to_s}--#{password}--")
68
63
  end
69
64
  end
70
65
 
71
66
  def encrypt_password
72
67
  return if password.blank?
73
- self.crypted_password = encrypt(password)
68
+ self.encrypted_password = encrypt(password)
74
69
  end
75
70
 
76
71
  def password_required?
77
- crypted_password.blank? || !password.blank?
72
+ encrypted_password.blank? || !password.blank?
73
+ end
74
+
75
+ def downcase_email
76
+ self.email = email.to_s.downcase
78
77
  end
79
78
 
80
79
  end
@@ -3,48 +3,36 @@ module Clearance
3
3
  module Functional
4
4
  module ConfirmationsControllerTest
5
5
 
6
- def self.included(base)
7
- base.class_eval do
8
-
9
- context 'A GET to #new' do
10
- context "with the User with the given id's salt" do
6
+ def self.included(controller_test)
7
+ controller_test.class_eval do
8
+
9
+ should_filter_params :salt
10
+
11
+ context "Given a user whose email has not been confirmed" do
12
+ setup { @user = Factory(:registered_user) }
13
+
14
+ context "on GET to #new with correct id and salt" do
11
15
  setup do
12
- @user = Factory :clearance_user
13
16
  get :new, :user_id => @user.to_param, :salt => @user.salt
14
17
  end
15
18
 
16
- should 'find the User record with the given id and salt' do
17
- assert_equal @user, assigns(:user)
18
- end
19
-
20
- should 'confirm the User record with the given id' do
21
- assert assigns(:user).confirmed?
22
- end
23
-
24
- should 'log the User in' do
25
- assert_equal @user.id, session[:user_id]
26
- end
27
-
28
- should_redirect_to "@controller.send(:url_after_create)"
19
+ should_be_signed_in_and_email_confirmed_as { @user }
20
+ should_redirect_to_url_after_create
29
21
  end
30
-
31
- context "without the User with the given id's salt" do
22
+
23
+ context "on GET to #new with incorrect salt" do
32
24
  setup do
33
- user = Factory :clearance_user
34
- salt = ''
35
- assert_not_equal salt, user.salt
25
+ salt = ""
26
+ assert_not_equal salt, @user.salt
36
27
 
37
- get :new, :user_id => user.to_param, :salt => ''
28
+ get :new, :user_id => @user.to_param, :salt => salt
38
29
  end
39
30
 
40
31
  should_respond_with :not_found
41
-
42
- should 'render nothing' do
43
- assert @response.body.blank?
44
- end
32
+ should_render_nothing
45
33
  end
46
34
  end
47
-
35
+
48
36
  end
49
37
  end
50
38
 
@@ -3,13 +3,14 @@ module Clearance
3
3
  module Functional
4
4
  module PasswordsControllerTest
5
5
 
6
- def self.included(base)
7
- base.class_eval do
6
+ def self.included(controller_test)
7
+ controller_test.class_eval do
8
8
 
9
- should_route :get, '/users/1/password/edit', :action => 'edit', :user_id => '1'
9
+ should_route :get, '/users/1/password/edit',
10
+ :action => 'edit', :user_id => '1'
10
11
 
11
12
  context 'with a user' do
12
- setup { @user = Factory :clearance_user }
13
+ setup { @user = Factory(:registered_user) }
13
14
 
14
15
  context 'A GET to #new' do
15
16
  setup { get :new, :user_id => @user.to_param }
@@ -35,10 +36,10 @@ module Clearance
35
36
  assert_match /#{@user.email}/, flash[:notice]
36
37
  end
37
38
 
38
- should_redirect_to "@controller.send(:url_after_create)"
39
+ should_redirect_to_url_after_create
39
40
  end
40
41
 
41
- context 'with a non-existing email address' do
42
+ context 'with a non-existent email address' do
42
43
  setup do
43
44
  email = 'user1@example.com'
44
45
  assert ! User.exists?(['email = ?', email])
@@ -51,8 +52,8 @@ module Clearance
51
52
  assert ActionMailer::Base.deliveries.empty?
52
53
  end
53
54
 
54
- should 'set a :warning flash' do
55
- assert_not_nil flash.now[:warning]
55
+ should 'set a :notice flash' do
56
+ assert_not_nil flash.now[:notice]
56
57
  end
57
58
 
58
59
  should_render_template "new"
@@ -64,7 +65,7 @@ module Clearance
64
65
  setup do
65
66
  get :edit,
66
67
  :user_id => @user.to_param,
67
- :password => @user.crypted_password,
68
+ :password => @user.encrypted_password,
68
69
  :email => @user.email
69
70
  end
70
71
 
@@ -77,7 +78,7 @@ module Clearance
77
78
 
78
79
  should "have a form for the user's email, password, and password confirm" do
79
80
  update_path = ERB::Util.h(user_password_path(@user,
80
- :password => @user.crypted_password,
81
+ :password => @user.encrypted_password,
81
82
  :email => @user.email))
82
83
 
83
84
  assert_select 'form[action=?]', update_path do
@@ -94,10 +95,7 @@ module Clearance
94
95
  end
95
96
 
96
97
  should_respond_with :not_found
97
-
98
- should 'render an empty response' do
99
- assert @response.body.blank?
100
- end
98
+ should_render_nothing
101
99
  end
102
100
  end
103
101
 
@@ -108,31 +106,24 @@ module Clearance
108
106
  end
109
107
 
110
108
  should "not update the user's password" do
111
- assert_not_equal @encrypted_new_password, @user.crypted_password
112
- end
113
-
114
- should 'not log the user in' do
115
- assert_nil session[:user_id]
109
+ assert_not_equal @encrypted_new_password, @user.encrypted_password
116
110
  end
117
111
 
112
+ should_not_be_signed_in
118
113
  should_respond_with :not_found
119
-
120
- should 'render an empty response' do
121
- assert @response.body.blank?
122
- end
114
+ should_render_nothing
123
115
  end
124
116
 
125
117
  context 'with a matching password and password confirmation' do
126
118
  setup do
127
119
  new_password = 'new_password'
128
- encryption_format = "--#{@user.salt}--#{new_password}--"
129
- @encrypted_new_password = Digest::SHA512.hexdigest encryption_format
130
- assert_not_equal @encrypted_new_password, @user.crypted_password
120
+ @encrypted_new_password = @user.encrypt(new_password)
121
+ assert_not_equal @encrypted_new_password, @user.encrypted_password
131
122
 
132
123
  put(:update,
133
124
  :user_id => @user,
134
125
  :email => @user.email,
135
- :password => @user.crypted_password,
126
+ :password => @user.encrypted_password,
136
127
  :user => {
137
128
  :password => new_password,
138
129
  :password_confirmation => new_password
@@ -141,25 +132,21 @@ module Clearance
141
132
  end
142
133
 
143
134
  should "update the user's password" do
144
- assert_equal @encrypted_new_password, @user.crypted_password
135
+ assert_equal @encrypted_new_password, @user.encrypted_password
145
136
  end
146
137
 
147
- should 'log the user in' do
148
- assert_equal session[:user_id], @user.id
149
- end
150
-
151
- should_redirect_to "user_path(@user)"
138
+ should_be_signed_in_as { @user }
139
+ should_redirect_to_url_after_update
152
140
  end
153
141
 
154
142
  context 'with password but blank password confirmation' do
155
143
  setup do
156
144
  new_password = 'new_password'
157
- encryption_format = "--#{@user.salt}--#{new_password}--"
158
- @encrypted_new_password = Digest::SHA512.hexdigest encryption_format
145
+ @encrypted_new_password = @user.encrypt(new_password)
159
146
 
160
147
  put(:update,
161
148
  :user_id => @user.to_param,
162
- :password => @user.crypted_password,
149
+ :password => @user.encrypted_password,
163
150
  :user => {
164
151
  :password => new_password,
165
152
  :password_confirmation => ''
@@ -168,21 +155,16 @@ module Clearance
168
155
  end
169
156
 
170
157
  should "not update the user's password" do
171
- assert_not_equal @encrypted_new_password, @user.crypted_password
172
- end
173
-
174
- should 'not log the user in' do
175
- assert_nil session[:user_id]
158
+ assert_not_equal @encrypted_new_password, @user.encrypted_password
176
159
  end
177
160
 
161
+ should_not_be_signed_in
178
162
  should_respond_with :not_found
179
-
180
- should 'render an empty response' do
181
- assert @response.body.blank?
182
- end
163
+ should_render_nothing
183
164
  end
184
165
  end
185
166
  end
167
+
186
168
  end
187
169
  end
188
170
 
@@ -3,8 +3,9 @@ module Clearance
3
3
  module Functional
4
4
  module SessionsControllerTest
5
5
 
6
- def self.included(base)
7
- base.class_eval do
6
+ def self.included(controller_test)
7
+ controller_test.class_eval do
8
+
8
9
  should_filter_params :password
9
10
 
10
11
  context "on GET to /sessions/new" do
@@ -13,9 +14,10 @@ module Clearance
13
14
  should_respond_with :success
14
15
  should_render_template :new
15
16
  should_not_set_the_flash
17
+
16
18
  should 'display a "sign in" form' do
17
19
  assert_select "form[action=#{session_path}][method=post]",
18
- true, "There must be a form to log in" do
20
+ true, "There must be a form to sign in" do
19
21
  assert_select "input[type=text][name=?]",
20
22
  "session[email]", true, "There must be an email field"
21
23
  assert_select "input[type=password][name=?]",
@@ -28,10 +30,8 @@ module Clearance
28
30
  end
29
31
  end
30
32
 
31
- context "Given an unconfirmed user" do
32
- setup do
33
- @user = Factory(:clearance_user, :confirmed => false)
34
- end
33
+ context "Given a registered user" do
34
+ setup { @user = Factory(:registered_user) }
35
35
 
36
36
  context "a POST to #create with good credentials" do
37
37
  setup do
@@ -42,16 +42,11 @@ module Clearance
42
42
  end
43
43
 
44
44
  should_deny_access(:flash => /confirm/i)
45
-
46
- should "send the confirmation email" do
47
- assert_not_nil email = ActionMailer::Base.deliveries[0]
48
- assert_match /account confirmation/i, email.subject
49
- end
50
45
  end
51
46
  end
52
47
 
53
- context "Given a confirmed user" do
54
- setup { @user = Factory(:clearance_user, :confirmed => true) }
48
+ context "Given an email confirmed user" do
49
+ setup { @user = Factory(:email_confirmed_user) }
55
50
 
56
51
  context "a POST to #create with good credentials" do
57
52
  setup do
@@ -61,8 +56,8 @@ module Clearance
61
56
  end
62
57
 
63
58
  should_set_the_flash_to /success/i
64
- should_redirect_to '@controller.send(:url_after_create)'
65
- should_return_from_session :user_id, "@user.id"
59
+ should_redirect_to_url_after_create
60
+ should_be_signed_in_as { @user }
66
61
  end
67
62
 
68
63
  context "a POST to #create with bad credentials" do
@@ -74,7 +69,7 @@ module Clearance
74
69
 
75
70
  should_set_the_flash_to /bad/i
76
71
  should_render_template :new
77
- should_return_from_session :user_id, "nil"
72
+ should_not_be_signed_in
78
73
  end
79
74
 
80
75
  context "a POST to #create with good credentials and remember me" do
@@ -86,11 +81,11 @@ module Clearance
86
81
  end
87
82
 
88
83
  should_set_the_flash_to /success/i
89
- should_redirect_to "@controller.send(:url_after_create)"
90
- should_return_from_session :user_id, "@user.id"
84
+ should_redirect_to_url_after_create
85
+ should_be_signed_in_as { @user }
91
86
 
92
87
  should 'set the cookie' do
93
- assert ! cookies['auth_token'].empty?
88
+ assert ! cookies['remember_token'].empty?
94
89
  end
95
90
 
96
91
  should 'set the remember me token in users table' do
@@ -112,7 +107,7 @@ module Clearance
112
107
  should_return_from_session :user_id, "nil"
113
108
 
114
109
  should 'not create the cookie' do
115
- assert_nil cookies['auth_token']
110
+ assert_nil cookies['remember_token']
116
111
  end
117
112
 
118
113
  should 'not set the remember me token in users table' do
@@ -161,26 +156,26 @@ module Clearance
161
156
  public_context do
162
157
  context "logging out again" do
163
158
  setup { delete :destroy }
164
- should_redirect_to '@controller.send(:url_after_destroy)'
159
+ should_redirect_to_url_after_destroy
165
160
  end
166
161
  end
167
162
 
168
- logged_in_user_context do
163
+ signed_in_user_context do
169
164
  context "a DELETE to #destroy without a cookie" do
170
165
  setup { delete :destroy }
171
166
 
172
- should_set_the_flash_to(/logged out/i)
173
- should_redirect_to '@controller.send(:url_after_destroy)'
167
+ should_set_the_flash_to(/signed out/i)
168
+ should_redirect_to_url_after_destroy
174
169
  end
175
170
 
176
171
  context 'a DELETE to #destroy with a cookie' do
177
172
  setup do
178
- cookies['auth_token'] = CGI::Cookie.new 'token', 'value'
173
+ cookies['remember_token'] = CGI::Cookie.new 'token', 'value'
179
174
  delete :destroy
180
175
  end
181
176
 
182
177
  should 'delete the cookie' do
183
- assert cookies['auth_token'].empty?
178
+ assert cookies['remember_token'].empty?
184
179
  end
185
180
 
186
181
  should 'delete the remember me token in users table' do
@@ -189,6 +184,7 @@ module Clearance
189
184
  end
190
185
  end
191
186
  end
187
+
192
188
  end
193
189
  end
194
190