clearance 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. data/CHANGELOG.textile +12 -1
  2. data/README.textile +27 -44
  3. data/Rakefile +20 -36
  4. data/VERSION +1 -0
  5. data/app/controllers/clearance/confirmations_controller.rb +1 -1
  6. data/app/controllers/clearance/passwords_controller.rb +2 -2
  7. data/app/controllers/clearance/sessions_controller.rb +3 -3
  8. data/app/controllers/clearance/users_controller.rb +1 -1
  9. data/app/models/clearance_mailer.rb +2 -4
  10. data/app/views/sessions/new.html.erb +1 -1
  11. data/generators/clearance/clearance_generator.rb +6 -0
  12. data/generators/clearance/lib/insert_commands.rb +1 -1
  13. data/generators/clearance/templates/README +13 -11
  14. data/generators/clearance/templates/clearance.rb +3 -0
  15. data/generators/clearance_features/templates/features/step_definitions/clearance_steps.rb +12 -8
  16. data/generators/clearance_features/templates/features/support/paths.rb +10 -9
  17. data/generators/clearance_views/templates/formtastic/sessions/new.html.erb +1 -1
  18. data/lib/clearance.rb +2 -1
  19. data/lib/clearance/authentication.rb +2 -2
  20. data/lib/clearance/configuration.rb +25 -0
  21. data/lib/clearance/routes.rb +49 -0
  22. data/lib/clearance/user.rb +0 -18
  23. data/shoulda_macros/clearance.rb +1 -1
  24. data/test/controllers/confirmations_controller_test.rb +100 -0
  25. data/test/controllers/passwords_controller_test.rb +183 -0
  26. data/test/controllers/sessions_controller_test.rb +141 -0
  27. data/test/controllers/users_controller_test.rb +65 -0
  28. data/test/models/clearance_mailer_test.rb +55 -0
  29. data/test/models/user_test.rb +227 -0
  30. data/test/rails_root/app/controllers/accounts_controller.rb +10 -0
  31. data/test/rails_root/app/controllers/application_controller.rb +5 -0
  32. data/test/rails_root/app/helpers/application_helper.rb +5 -0
  33. data/test/rails_root/app/helpers/confirmations_helper.rb +2 -0
  34. data/test/rails_root/app/helpers/passwords_helper.rb +2 -0
  35. data/test/rails_root/app/models/user.rb +3 -0
  36. data/test/rails_root/config/boot.rb +110 -0
  37. data/test/rails_root/config/environment.rb +17 -0
  38. data/test/rails_root/config/environments/development.rb +19 -0
  39. data/test/rails_root/config/environments/production.rb +1 -0
  40. data/test/rails_root/config/environments/test.rb +36 -0
  41. data/test/rails_root/config/initializers/clearance.rb +3 -0
  42. data/test/rails_root/config/initializers/clearance_loader.rb +8 -0
  43. data/test/rails_root/config/initializers/inflections.rb +10 -0
  44. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  45. data/test/rails_root/config/initializers/requires.rb +13 -0
  46. data/test/rails_root/config/initializers/time_formats.rb +4 -0
  47. data/test/rails_root/config/routes.rb +6 -0
  48. data/test/rails_root/db/migrate/20100120045223_clearance_create_users.rb +21 -0
  49. data/test/rails_root/features/step_definitions/clearance_steps.rb +122 -0
  50. data/test/rails_root/features/step_definitions/factory_girl_steps.rb +5 -0
  51. data/test/rails_root/features/step_definitions/web_steps.rb +259 -0
  52. data/test/rails_root/features/support/env.rb +47 -0
  53. data/test/rails_root/features/support/paths.rb +23 -0
  54. data/test/rails_root/public/dispatch.rb +10 -0
  55. data/test/rails_root/script/create_project.rb +52 -0
  56. data/test/rails_root/test/factories/clearance.rb +13 -0
  57. data/test/rails_root/test/functional/accounts_controller_test.rb +23 -0
  58. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +21 -0
  59. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/lib/formtastic.rb +1236 -0
  60. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/lib/justin_french/formtastic.rb +10 -0
  61. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/rails/init.rb +3 -0
  62. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/spec/formtastic_spec.rb +2900 -0
  63. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/spec/test_helper.rb +14 -0
  64. data/test/test_helper.rb +19 -0
  65. metadata +60 -18
  66. data/TODO.textile +0 -6
  67. data/config/clearance_routes.rb +0 -30
  68. data/lib/clearance/extensions/routes.rb +0 -14
@@ -12,7 +12,7 @@
12
12
 
13
13
  <ul>
14
14
  <li>
15
- <%= link_to "Sign up", new_user_path %>
15
+ <%= link_to "Sign up", sign_up_path %>
16
16
  </li>
17
17
  <li>
18
18
  <%= link_to "Forgot password?", new_password_path %>
@@ -1,6 +1,7 @@
1
1
  require 'clearance/extensions/errors'
2
2
  require 'clearance/extensions/rescue'
3
- require 'clearance/extensions/routes'
4
3
 
4
+ require 'clearance/configuration'
5
+ require 'clearance/routes'
5
6
  require 'clearance/authentication'
6
7
  require 'clearance/user'
@@ -87,7 +87,7 @@ module Clearance
87
87
  def deny_access(flash_message = nil)
88
88
  store_location
89
89
  flash[:failure] = flash_message if flash_message
90
- redirect_to(new_session_url)
90
+ redirect_to(sign_in_url)
91
91
  end
92
92
 
93
93
  protected
@@ -123,7 +123,7 @@ module Clearance
123
123
  end
124
124
 
125
125
  def redirect_to_root
126
- redirect_to(root_url)
126
+ redirect_to('/')
127
127
  end
128
128
  end
129
129
 
@@ -0,0 +1,25 @@
1
+ module Clearance
2
+ class Configuration
3
+ attr_accessor :mailer_sender
4
+
5
+ def initialize
6
+ @mailer_sender = 'donotreply@example.com'
7
+ end
8
+ end
9
+
10
+ class << self
11
+ attr_accessor :configuration
12
+ end
13
+
14
+ # Configure Clearance someplace sensible,
15
+ # like config/initializers/clearance.rb
16
+ #
17
+ # @example
18
+ # Clearance.configure do |config|
19
+ # config.mailer_sender = 'donotreply@example.com'
20
+ # end
21
+ def self.configure
22
+ self.configuration ||= Configuration.new
23
+ yield(configuration)
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ module Clearance
2
+ class Routes
3
+
4
+ # In your application's config/routes.rb, draw Clearance's routes:
5
+ #
6
+ # @example
7
+ # map.resources :posts
8
+ # Clearance::Routes.draw(map)
9
+ #
10
+ # If you need to override a Clearance route, invoke your app route
11
+ # earlier in the file so Rails' router short-circuits when it finds
12
+ # your route:
13
+ #
14
+ # @example
15
+ # map.resources :users, :only => [:new, :create]
16
+ # Clearance::Routes.draw(map)
17
+ def self.draw(map)
18
+ map.resources :passwords,
19
+ :controller => 'clearance/passwords',
20
+ :only => [:new, :create]
21
+
22
+ map.resource :session,
23
+ :controller => 'clearance/sessions',
24
+ :only => [:new, :create, :destroy]
25
+
26
+ map.resources :users, :controller => 'clearance/users' do |users|
27
+ users.resource :password,
28
+ :controller => 'clearance/passwords',
29
+ :only => [:create, :edit, :update]
30
+
31
+ users.resource :confirmation,
32
+ :controller => 'clearance/confirmations',
33
+ :only => [:new, :create]
34
+ end
35
+
36
+ map.sign_up 'sign_up',
37
+ :controller => 'clearance/users',
38
+ :action => 'new'
39
+ map.sign_in 'sign_in',
40
+ :controller => 'clearance/sessions',
41
+ :action => 'new'
42
+ map.sign_out 'sign_out',
43
+ :controller => 'clearance/sessions',
44
+ :action => 'destroy',
45
+ :method => :delete
46
+ end
47
+
48
+ end
49
+ end
@@ -24,29 +24,11 @@ module Clearance
24
24
  model.extend(ClassMethods)
25
25
 
26
26
  model.send(:include, InstanceMethods)
27
- model.send(:include, AttrAccessible)
28
27
  model.send(:include, AttrAccessor)
29
28
  model.send(:include, Validations)
30
29
  model.send(:include, Callbacks)
31
30
  end
32
31
 
33
- module AttrAccessible
34
- # Hook for attr_accessible white list.
35
- #
36
- # :email, :password, :password_confirmation
37
- #
38
- # Append other attributes that must be mass-assigned in your model.
39
- #
40
- # @example
41
- # include Clearance::User
42
- # attr_accessible :location, :gender
43
- def self.included(model)
44
- model.class_eval do
45
- attr_accessible :email, :password, :password_confirmation
46
- end
47
- end
48
- end
49
-
50
32
  module AttrAccessor
51
33
  # Hook for attr_accessor virtual attributes.
52
34
  #
@@ -54,7 +54,7 @@ module Clearance
54
54
  should_not_set_the_flash
55
55
  end
56
56
 
57
- should_redirect_to('new_session_url') { new_session_url }
57
+ should_redirect_to('sign in page') { sign_in_url }
58
58
  end
59
59
 
60
60
  # HTTP FLUENCY
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ class ConfirmationsControllerTest < ActionController::TestCase
4
+
5
+ tests Clearance::ConfirmationsController
6
+
7
+ should_filter_params :token
8
+
9
+ context "a user whose email has not been confirmed" do
10
+ setup { @user = Factory(:user) }
11
+
12
+ should "have a token" do
13
+ assert_not_nil @user.confirmation_token
14
+ assert_not_equal "", @user.confirmation_token
15
+ end
16
+
17
+ context "on GET to #new with correct id and token" do
18
+ setup do
19
+ get :new, :user_id => @user.to_param,
20
+ :token => @user.confirmation_token
21
+ end
22
+
23
+ should_set_the_flash_to /confirmed email/i
24
+ should_set_the_flash_to /signed in/i
25
+ should_redirect_to_url_after_create
26
+ end
27
+
28
+ context "with an incorrect token" do
29
+ setup do
30
+ @bad_token = "bad token"
31
+ assert_not_equal @bad_token, @user.confirmation_token
32
+ end
33
+
34
+ should_forbid "on GET to #new with incorrect token" do
35
+ get :new, :user_id => @user.to_param,
36
+ :token => @bad_token
37
+ end
38
+ end
39
+
40
+ should_forbid "on GET to #new with blank token" do
41
+ get :new, :user_id => @user.to_param, :token => ""
42
+ end
43
+
44
+ should_forbid "on GET to #new with no token" do
45
+ get :new, :user_id => @user.to_param
46
+ end
47
+ end
48
+
49
+ context "a signed in confirmed user on GET to #new with token" do
50
+ setup do
51
+ @user = Factory(:user)
52
+ @token = @user.confirmation_token
53
+ @user.confirm_email!
54
+ sign_in_as @user
55
+
56
+ get :new, :user_id => @user.to_param, :token => @token
57
+ end
58
+
59
+ should_set_the_flash_to /confirmed email/i
60
+ should_redirect_to_url_after_create
61
+ end
62
+
63
+ context "a bad user" do
64
+ setup do
65
+ @user = Factory(:user)
66
+ @token = @user.confirmation_token
67
+ @user.confirm_email!
68
+
69
+ @bad_user = Factory(:email_confirmed_user)
70
+ sign_in_as @bad_user
71
+ end
72
+
73
+ should_forbid "on GET to #new with token for another user" do
74
+ get :new, :user_id => @user.to_param, :token => @token
75
+ end
76
+ end
77
+
78
+ context "a signed out confirmed user on GET to #new with token" do
79
+ setup do
80
+ @user = Factory(:user)
81
+ @token = @user.confirmation_token
82
+ @user.confirm_email!
83
+ get :new, :user_id => @user.to_param, :token => @token
84
+ end
85
+
86
+ should_set_the_flash_to /already confirmed/i
87
+ should_set_the_flash_to /sign in/i
88
+ should_not_be_signed_in
89
+ should_redirect_to_url_already_confirmed
90
+ end
91
+
92
+ context "no users" do
93
+ setup { assert_equal 0, ::User.count }
94
+
95
+ should_forbid "on GET to #new with nonexistent id and token" do
96
+ get :new, :user_id => '123', :token => '123'
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1,183 @@
1
+ require 'test_helper'
2
+
3
+ class PasswordsControllerTest < ActionController::TestCase
4
+
5
+ tests Clearance::PasswordsController
6
+
7
+ should_route :get, '/users/1/password/edit',
8
+ :controller => 'clearance/passwords', :action => 'edit', :user_id => '1'
9
+
10
+ context "a signed up user" do
11
+ setup do
12
+ @user = Factory(:user)
13
+ end
14
+
15
+ context "on GET to #new" do
16
+ setup { get :new, :user_id => @user.to_param }
17
+
18
+ should_respond_with :success
19
+ should_render_template "new"
20
+ end
21
+
22
+ context "on POST to #create" do
23
+ context "with correct email address" do
24
+ setup do
25
+ ActionMailer::Base.deliveries.clear
26
+ post :create, :password => { :email => @user.email }
27
+ end
28
+
29
+ should "generate a token for the change your password email" do
30
+ assert_not_nil @user.reload.confirmation_token
31
+ end
32
+
33
+ should "send the change your password email" do
34
+ assert_sent_email do |email|
35
+ email.subject =~ /change your password/i
36
+ end
37
+ end
38
+
39
+ should_set_the_flash_to /password/i
40
+ should_redirect_to_url_after_create
41
+ end
42
+
43
+ context "with incorrect email address" do
44
+ setup do
45
+ email = "user1@example.com"
46
+ assert ! ::User.exists?(['email = ?', email])
47
+ ActionMailer::Base.deliveries.clear
48
+ assert_equal @user.confirmation_token,
49
+ @user.reload.confirmation_token
50
+
51
+ post :create, :password => { :email => email }
52
+ end
53
+
54
+ should "not generate a token for the change your password email" do
55
+ assert_equal @user.confirmation_token,
56
+ @user.reload.confirmation_token
57
+ end
58
+
59
+ should "not send a password reminder email" do
60
+ assert ActionMailer::Base.deliveries.empty?
61
+ end
62
+
63
+ should "set the failure flash to Unknown email" do
64
+ assert_match /unknown email/i, flash.now[:failure]
65
+ end
66
+
67
+ should_render_template :new
68
+ end
69
+ end
70
+ end
71
+
72
+ context "a signed up user and forgotten password" do
73
+ setup do
74
+ @user = Factory(:user)
75
+ @user.forgot_password!
76
+ end
77
+
78
+ context "on GET to #edit with correct id and token" do
79
+ setup do
80
+ get :edit, :user_id => @user.to_param,
81
+ :token => @user.confirmation_token
82
+ end
83
+
84
+ should "find the user" do
85
+ assert_equal @user, assigns(:user)
86
+ end
87
+
88
+ should_respond_with :success
89
+ should_render_template "edit"
90
+ should_display_a_password_update_form
91
+ end
92
+
93
+ should_forbid "on GET to #edit with correct id but blank token" do
94
+ get :edit, :user_id => @user.to_param, :token => ""
95
+ end
96
+
97
+ should_forbid "on GET to #edit with correct id but no token" do
98
+ get :edit, :user_id => @user.to_param
99
+ end
100
+
101
+ context "on PUT to #update with matching password and password confirmation" do
102
+ setup do
103
+ new_password = "new_password"
104
+ @encrypted_new_password = @user.send(:encrypt, new_password)
105
+ assert_not_equal @encrypted_new_password, @user.encrypted_password
106
+
107
+ put(:update,
108
+ :user_id => @user,
109
+ :token => @user.confirmation_token,
110
+ :user => {
111
+ :password => new_password,
112
+ :password_confirmation => new_password
113
+ })
114
+ @user.reload
115
+ end
116
+
117
+ should "update password" do
118
+ assert_equal @encrypted_new_password,
119
+ @user.encrypted_password
120
+ end
121
+
122
+ should "clear confirmation token" do
123
+ assert_nil @user.confirmation_token
124
+ end
125
+
126
+ should "set remember token" do
127
+ assert_not_nil @user.remember_token
128
+ end
129
+
130
+ should_set_the_flash_to(/signed in/i)
131
+ should_redirect_to_url_after_update
132
+ end
133
+
134
+ context "on PUT to #update with password but blank password confirmation" do
135
+ setup do
136
+ new_password = "new_password"
137
+ @encrypted_new_password = @user.send(:encrypt, new_password)
138
+
139
+ put(:update,
140
+ :user_id => @user.to_param,
141
+ :token => @user.confirmation_token,
142
+ :user => {
143
+ :password => new_password,
144
+ :password_confirmation => ''
145
+ })
146
+ @user.reload
147
+ end
148
+
149
+ should "not update password" do
150
+ assert_not_equal @encrypted_new_password,
151
+ @user.encrypted_password
152
+ end
153
+
154
+ should "not clear token" do
155
+ assert_not_nil @user.confirmation_token
156
+ end
157
+
158
+ should_not_be_signed_in
159
+ should_not_set_the_flash
160
+ should_respond_with :success
161
+ should_render_template :edit
162
+
163
+ should_display_a_password_update_form
164
+ end
165
+
166
+ should_forbid "on PUT to #update with id but no token" do
167
+ put :update, :user_id => @user.to_param, :token => ""
168
+ end
169
+ end
170
+
171
+ context "given two users and user one signs in" do
172
+ setup do
173
+ @user_one = Factory(:user)
174
+ @user_two = Factory(:user)
175
+ sign_in_as @user_one
176
+ end
177
+
178
+ should_forbid "when user one tries to change user two's password on GET with no token" do
179
+ get :edit, :user_id => @user_two.to_param
180
+ end
181
+ end
182
+
183
+ end
@@ -0,0 +1,141 @@
1
+ require 'test_helper'
2
+
3
+ class SessionsControllerTest < ActionController::TestCase
4
+
5
+ tests Clearance::SessionsController
6
+
7
+ should_filter_params :password
8
+
9
+ context "on GET to /sessions/new" do
10
+ setup { get :new }
11
+
12
+ should_respond_with :success
13
+ should_render_template :new
14
+ should_not_set_the_flash
15
+ should_display_a_sign_in_form
16
+ end
17
+
18
+ context "on POST to #create with unconfirmed credentials" do
19
+ setup do
20
+ @user = Factory(:user)
21
+ ActionMailer::Base.deliveries.clear
22
+ post :create, :session => {
23
+ :email => @user.email,
24
+ :password => @user.password }
25
+ end
26
+
27
+ should_deny_access(:flash => /User has not confirmed email. Confirmation email will be resent./i)
28
+
29
+ should "send the confirmation email" do
30
+ assert_not_nil email = ActionMailer::Base.deliveries[0]
31
+ assert_match /account confirmation/i, email.subject
32
+ end
33
+ end
34
+
35
+ context "on POST to #create with good credentials" do
36
+ setup do
37
+ @user = Factory(:email_confirmed_user)
38
+ post :create, :session => {
39
+ :email => @user.email,
40
+ :password => @user.password }
41
+ end
42
+
43
+ should_set_the_flash_to /signed in/i
44
+ should_redirect_to_url_after_create
45
+
46
+ should 'set the cookie' do
47
+ assert ! cookies['remember_token'].empty?
48
+ end
49
+
50
+ should 'set the token in users table' do
51
+ assert_not_nil @user.reload.remember_token
52
+ end
53
+ end
54
+
55
+ context "on POST to #create with good credentials and a session return url" do
56
+ setup do
57
+ @user = Factory(:email_confirmed_user)
58
+ @return_url = '/url_in_the_session'
59
+ @request.session[:return_to] = @return_url
60
+ post :create, :session => {
61
+ :email => @user.email,
62
+ :password => @user.password }
63
+ end
64
+
65
+ should_redirect_to("the return URL") { @return_url }
66
+ end
67
+
68
+ context "on POST to #create with good credentials and a request return url" do
69
+ setup do
70
+ @user = Factory(:email_confirmed_user)
71
+ @return_url = '/url_in_the_request'
72
+ post :create, :session => {
73
+ :email => @user.email,
74
+ :password => @user.password },
75
+ :return_to => @return_url
76
+ end
77
+
78
+ should_redirect_to("the return URL") { @return_url }
79
+ end
80
+
81
+ context "on POST to #create with good credentials and a session return url and request return url" do
82
+ setup do
83
+ @user = Factory(:email_confirmed_user)
84
+ @return_url = '/url_in_the_session'
85
+ @request.session[:return_to] = @return_url
86
+ post :create, :session => {
87
+ :email => @user.email,
88
+ :password => @user.password },
89
+ :return_to => '/url_in_the_request'
90
+ end
91
+
92
+ should_redirect_to("the return URL") { @return_url }
93
+ end
94
+
95
+ context "on POST to #create with bad credentials" do
96
+ setup do
97
+ post :create, :session => {
98
+ :email => 'bad.email@example.com',
99
+ :password => "bad value" }
100
+ end
101
+
102
+ should_set_the_flash_to /bad/i
103
+ should_respond_with :unauthorized
104
+ should_render_template :new
105
+ should_not_be_signed_in
106
+
107
+ should 'not create the cookie' do
108
+ assert_nil cookies['remember_token']
109
+ end
110
+ end
111
+
112
+ context "on DELETE to #destroy given a signed out user" do
113
+ setup do
114
+ sign_out
115
+ delete :destroy
116
+ end
117
+ should_set_the_flash_to(/signed out/i)
118
+ should_redirect_to_url_after_destroy
119
+ end
120
+
121
+ context "on DELETE to #destroy with a cookie" do
122
+ setup do
123
+ @user = Factory(:email_confirmed_user)
124
+ cookies['remember_token'] = CGI::Cookie.new('token', 'value')
125
+ sign_in_as @user
126
+ delete :destroy
127
+ end
128
+
129
+ should_set_the_flash_to(/signed out/i)
130
+ should_redirect_to_url_after_destroy
131
+
132
+ should "delete the cookie token" do
133
+ assert_nil cookies['remember_token']
134
+ end
135
+
136
+ should "delete the database token" do
137
+ assert_nil @user.reload.remember_token
138
+ end
139
+ end
140
+
141
+ end