devise 3.3.0 → 3.5.10

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +29 -20
  3. data/CHANGELOG.md +219 -102
  4. data/CODE_OF_CONDUCT.md +22 -0
  5. data/CONTRIBUTING.md +2 -0
  6. data/Gemfile +3 -2
  7. data/Gemfile.lock +101 -80
  8. data/MIT-LICENSE +1 -1
  9. data/README.md +87 -43
  10. data/Rakefile +2 -1
  11. data/app/controllers/devise/confirmations_controller.rb +5 -1
  12. data/app/controllers/devise/omniauth_callbacks_controller.rb +4 -0
  13. data/app/controllers/devise/passwords_controller.rb +14 -4
  14. data/app/controllers/devise/registrations_controller.rb +10 -11
  15. data/app/controllers/devise/sessions_controller.rb +7 -2
  16. data/app/controllers/devise/unlocks_controller.rb +3 -0
  17. data/app/controllers/devise_controller.rb +44 -21
  18. data/app/mailers/devise/mailer.rb +4 -0
  19. data/app/views/devise/confirmations/new.html.erb +7 -3
  20. data/app/views/devise/mailer/password_change.html.erb +3 -0
  21. data/app/views/devise/passwords/edit.html.erb +14 -5
  22. data/app/views/devise/passwords/new.html.erb +7 -3
  23. data/app/views/devise/registrations/edit.html.erb +19 -9
  24. data/app/views/devise/registrations/new.html.erb +18 -7
  25. data/app/views/devise/sessions/new.html.erb +15 -6
  26. data/app/views/devise/shared/{_links.erb → _links.html.erb} +1 -1
  27. data/app/views/devise/unlocks/new.html.erb +7 -3
  28. data/config/locales/en.yml +4 -2
  29. data/devise.gemspec +2 -2
  30. data/gemfiles/Gemfile.rails-3.2-stable.lock +54 -48
  31. data/gemfiles/Gemfile.rails-4.0-stable +1 -0
  32. data/gemfiles/Gemfile.rails-4.0-stable.lock +63 -59
  33. data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.1-stable} +3 -5
  34. data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
  35. data/gemfiles/Gemfile.rails-4.2-stable +30 -0
  36. data/gemfiles/Gemfile.rails-4.2-stable.lock +193 -0
  37. data/lib/devise/controllers/helpers.rb +12 -6
  38. data/lib/devise/controllers/rememberable.rb +9 -2
  39. data/lib/devise/controllers/sign_in_out.rb +2 -8
  40. data/lib/devise/controllers/store_location.rb +3 -1
  41. data/lib/devise/controllers/url_helpers.rb +7 -9
  42. data/lib/devise/encryptor.rb +22 -0
  43. data/lib/devise/failure_app.rb +56 -14
  44. data/lib/devise/hooks/timeoutable.rb +5 -7
  45. data/lib/devise/mapping.rb +2 -1
  46. data/lib/devise/models/authenticatable.rb +28 -28
  47. data/lib/devise/models/confirmable.rb +51 -17
  48. data/lib/devise/models/database_authenticatable.rb +17 -11
  49. data/lib/devise/models/lockable.rb +7 -3
  50. data/lib/devise/models/recoverable.rb +23 -15
  51. data/lib/devise/models/rememberable.rb +56 -22
  52. data/lib/devise/models/timeoutable.rb +0 -6
  53. data/lib/devise/models/trackable.rb +1 -2
  54. data/lib/devise/models/validatable.rb +3 -3
  55. data/lib/devise/models.rb +1 -1
  56. data/lib/devise/rails/routes.rb +33 -27
  57. data/lib/devise/rails.rb +1 -1
  58. data/lib/devise/strategies/authenticatable.rb +8 -6
  59. data/lib/devise/strategies/database_authenticatable.rb +2 -1
  60. data/lib/devise/strategies/rememberable.rb +13 -3
  61. data/lib/devise/test_helpers.rb +2 -2
  62. data/lib/devise/version.rb +1 -1
  63. data/lib/devise.rb +39 -37
  64. data/lib/generators/active_record/devise_generator.rb +2 -1
  65. data/lib/generators/active_record/templates/migration.rb +1 -1
  66. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  67. data/lib/generators/devise/controllers_generator.rb +44 -0
  68. data/lib/generators/devise/views_generator.rb +14 -3
  69. data/lib/generators/templates/controllers/README +14 -0
  70. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  71. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  72. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  73. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  74. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  75. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  76. data/lib/generators/templates/devise.rb +19 -13
  77. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  78. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  79. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  80. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  81. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  82. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  83. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +2 -2
  84. data/test/controllers/custom_registrations_controller_test.rb +6 -1
  85. data/test/controllers/helper_methods_test.rb +21 -0
  86. data/test/controllers/helpers_test.rb +5 -0
  87. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  88. data/test/controllers/internal_helpers_test.rb +10 -4
  89. data/test/controllers/load_hooks_controller_test.rb +19 -0
  90. data/test/controllers/passwords_controller_test.rb +1 -1
  91. data/test/controllers/sessions_controller_test.rb +3 -3
  92. data/test/controllers/url_helpers_test.rb +6 -0
  93. data/test/devise_test.rb +3 -3
  94. data/test/failure_app_test.rb +47 -0
  95. data/test/generators/controllers_generator_test.rb +48 -0
  96. data/test/generators/views_generator_test.rb +8 -1
  97. data/test/helpers/devise_helper_test.rb +9 -12
  98. data/test/integration/authenticatable_test.rb +1 -1
  99. data/test/integration/database_authenticatable_test.rb +11 -0
  100. data/test/integration/http_authenticatable_test.rb +1 -1
  101. data/test/integration/omniauthable_test.rb +12 -10
  102. data/test/integration/recoverable_test.rb +13 -0
  103. data/test/integration/rememberable_test.rb +50 -3
  104. data/test/integration/timeoutable_test.rb +13 -18
  105. data/test/mailers/confirmation_instructions_test.rb +1 -1
  106. data/test/mapping_test.rb +7 -0
  107. data/test/models/authenticatable_test.rb +10 -0
  108. data/test/models/confirmable_test.rb +99 -42
  109. data/test/models/database_authenticatable_test.rb +20 -0
  110. data/test/models/lockable_test.rb +45 -17
  111. data/test/models/recoverable_test.rb +62 -7
  112. data/test/models/rememberable_test.rb +68 -97
  113. data/test/models/validatable_test.rb +5 -5
  114. data/test/models_test.rb +15 -6
  115. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  116. data/test/rails_app/app/controllers/admins_controller.rb +0 -5
  117. data/test/rails_app/app/controllers/custom/registrations_controller.rb +10 -0
  118. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  119. data/test/rails_app/app/mailers/users/mailer.rb +0 -9
  120. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  121. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  122. data/test/rails_app/config/application.rb +1 -1
  123. data/test/rails_app/config/environments/production.rb +6 -2
  124. data/test/rails_app/config/environments/test.rb +7 -2
  125. data/test/rails_app/config/initializers/devise.rb +12 -15
  126. data/test/rails_app/config/routes.rb +6 -3
  127. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -2
  128. data/test/rails_app/lib/shared_user.rb +1 -1
  129. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  130. data/test/rails_test.rb +9 -0
  131. data/test/support/helpers.rb +13 -6
  132. data/test/support/integration.rb +2 -2
  133. data/test/test_helper.rb +5 -0
  134. data/test/test_helpers_test.rb +22 -7
  135. data/test/test_models.rb +2 -2
  136. data/test/time_helpers.rb +137 -0
  137. metadata +58 -8
  138. data/gemfiles/Gemfile.rails-head.lock +0 -190
@@ -4,6 +4,8 @@ Devise.setup do |config|
4
4
  # The secret key used by Devise. Devise uses this key to generate
5
5
  # random tokens. Changing this key will render invalid all existing
6
6
  # confirmation, reset password and unlock tokens in the database.
7
+ # Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key`
8
+ # by default. You can change it below and use your own secret key.
7
9
  <% if rails_4? -%>
8
10
  # config.secret_key = '<%= SecureRandom.hex(64) %>'
9
11
  <% else -%>
@@ -33,7 +35,7 @@ Devise.setup do |config|
33
35
  # session. If you need permissions, you should implement that in a before filter.
34
36
  # You can also supply a hash where the value is a boolean determining whether
35
37
  # or not authentication should be aborted when the value is not present.
36
- # config.authentication_keys = [ :email ]
38
+ # config.authentication_keys = [:email]
37
39
 
38
40
  # Configure parameters from the request object used for authentication. Each entry
39
41
  # given should be a request method and it will automatically be passed to the
@@ -45,12 +47,12 @@ Devise.setup do |config|
45
47
  # Configure which authentication keys should be case-insensitive.
46
48
  # These keys will be downcased upon creating or modifying a user and when used
47
49
  # to authenticate or find a user. Default is :email.
48
- config.case_insensitive_keys = [ :email ]
50
+ config.case_insensitive_keys = [:email]
49
51
 
50
52
  # Configure which authentication keys should have whitespace stripped.
51
53
  # These keys will have whitespace before and after removed upon creating or
52
54
  # modifying a user and when used to authenticate or find a user. Default is :email.
53
- config.strip_whitespace_keys = [ :email ]
55
+ config.strip_whitespace_keys = [:email]
54
56
 
55
57
  # Tell if authentication through request.params is enabled. True by default.
56
58
  # It can be set to an array that will enable params authentication only for the
@@ -65,7 +67,7 @@ Devise.setup do |config|
65
67
  # :database = Support basic authentication with authentication key + password
66
68
  # config.http_authenticatable = false
67
69
 
68
- # If http headers should be returned for AJAX requests. True by default.
70
+ # If 401 status code should be returned for AJAX requests. True by default.
69
71
  # config.http_authenticatable_on_xhr = true
70
72
 
71
73
  # The realm used in Http Basic Authentication. 'Application' by default.
@@ -103,6 +105,9 @@ Devise.setup do |config|
103
105
  # Setup a pepper to generate the encrypted password.
104
106
  # config.pepper = '<%= SecureRandom.hex(64) %>'
105
107
 
108
+ # Send a notification email when the user's password is changed
109
+ # config.send_password_change_notification = false
110
+
106
111
  # ==> Configuration for :confirmable
107
112
  # A period that the user is allowed to access the website even without
108
113
  # confirming their account. For instance, if set to 2.days, the user will be
@@ -126,7 +131,7 @@ Devise.setup do |config|
126
131
  config.reconfirmable = true
127
132
 
128
133
  # Defines which key will be used when confirming an account
129
- # config.confirmation_keys = [ :email ]
134
+ # config.confirmation_keys = [:email]
130
135
 
131
136
  # ==> Configuration for :rememberable
132
137
  # The time the user will be remembered without asking for credentials again.
@@ -144,7 +149,7 @@ Devise.setup do |config|
144
149
 
145
150
  # ==> Configuration for :validatable
146
151
  # Range for password length.
147
- config.password_length = 8..128
152
+ config.password_length = 8..72
148
153
 
149
154
  # Email regex used to validate email formats. It simply asserts that
150
155
  # one (and only one) @ exists in the given string. This is mainly
@@ -156,9 +161,6 @@ Devise.setup do |config|
156
161
  # time the user will be asked for credentials again. Default is 30 minutes.
157
162
  # config.timeout_in = 30.minutes
158
163
 
159
- # If true, expires auth token on session timeout.
160
- # config.expire_auth_token_on_timeout = false
161
-
162
164
  # ==> Configuration for :lockable
163
165
  # Defines which strategy will be used to lock an account.
164
166
  # :failed_attempts = Locks an account after a number of failed attempts to sign in.
@@ -166,7 +168,7 @@ Devise.setup do |config|
166
168
  # config.lock_strategy = :failed_attempts
167
169
 
168
170
  # Defines which key will be used when locking and unlocking an account
169
- # config.unlock_keys = [ :email ]
171
+ # config.unlock_keys = [:email]
170
172
 
171
173
  # Defines which strategy will be used to unlock an account.
172
174
  # :email = Sends an unlock link to the user email
@@ -183,18 +185,22 @@ Devise.setup do |config|
183
185
  # config.unlock_in = 1.hour
184
186
 
185
187
  # Warn on the last attempt before the account is locked.
186
- # config.last_attempt_warning = false
188
+ # config.last_attempt_warning = true
187
189
 
188
190
  # ==> Configuration for :recoverable
189
191
  #
190
192
  # Defines which key will be used when recovering the password for an account
191
- # config.reset_password_keys = [ :email ]
193
+ # config.reset_password_keys = [:email]
192
194
 
193
195
  # Time interval you can reset your password with a reset password key.
194
196
  # Don't put a too small interval or your users won't have the time to
195
197
  # change their passwords.
196
198
  config.reset_password_within = 6.hours
197
199
 
200
+ # When set to false, does not sign a user in automatically after their password is
201
+ # reset. Defaults to true, so a user is signed in automatically after a reset.
202
+ # config.sign_in_after_reset_password = true
203
+
198
204
  # ==> Configuration for :encryptable
199
205
  # Allow you to use another encryption algorithm besides bcrypt (default). You can use
200
206
  # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
@@ -257,7 +263,7 @@ Devise.setup do |config|
257
263
  # The router that invoked `devise_for`, in the example above, would be:
258
264
  # config.router_name = :my_engine
259
265
  #
260
- # When using omniauth, Devise cannot automatically set Omniauth path,
266
+ # When using OmniAuth, Devise cannot automatically set OmniAuth path,
261
267
  # so you need to do it manually. For the users scope, it would be:
262
268
  # config.omniauth_path_prefix = '/my_engine/users/auth'
263
269
  end
@@ -2,4 +2,4 @@ Welcome <%= @email %>!
2
2
 
3
3
  You can confirm your account through the link below:
4
4
 
5
- <%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
5
+ [Confirm my account](<%= confirmation_url(@resource, confirmation_token: @token) %>)
@@ -0,0 +1,3 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>We're contacting you to notify you that your password has been changed.</p>
@@ -2,7 +2,7 @@ Hello <%= @resource.email %>!
2
2
 
3
3
  Someone has requested a link to change your password, and you can do this through the link below.
4
4
 
5
- <%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
5
+ [Change my password](<%= edit_password_url(@resource, reset_password_token: @token) %>)
6
6
 
7
7
  If you didn't request this, please ignore this email.
8
8
  Your password won't change until you access the link above and create a new one.
@@ -4,4 +4,4 @@ Your account has been locked due to an excessive number of unsuccessful sign in
4
4
 
5
5
  Click the link below to unlock your account:
6
6
 
7
- <%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
7
+ [Unlock my account](<%= unlock_url(@resource, unlock_token: @token) %>)
@@ -7,7 +7,7 @@
7
7
  <%= f.full_error :reset_password_token %>
8
8
 
9
9
  <div class="form-inputs">
10
- <%= f.input :password, label: "New password", required: true, autofocus: true %>
10
+ <%= f.input :password, label: "New password", required: true, autofocus: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
11
11
  <%= f.input :password_confirmation, label: "Confirm your new password", required: true %>
12
12
  </div>
13
13
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  <div class="form-inputs">
7
7
  <%= f.input :email, required: true, autofocus: true %>
8
- <%= f.input :password, required: true %>
8
+ <%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
9
9
  <%= f.input :password_confirmation, required: true %>
10
10
  </div>
11
11
 
@@ -1,4 +1,4 @@
1
- <h2>Sign in</h2>
1
+ <h2>Log in</h2>
2
2
 
3
3
  <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4
4
  <div class="form-inputs">
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
 
10
10
  <div class="form-actions">
11
- <%= f.button :submit, "Sign in" %>
11
+ <%= f.button :submit, "Log in" %>
12
12
  </div>
13
13
  <% end %>
14
14
 
@@ -8,7 +8,7 @@ class CustomRegistrationsControllerTest < ActionController::TestCase
8
8
  setup do
9
9
  request.env["devise.mapping"] = Devise.mappings[:user]
10
10
  @password = 'password'
11
- @user = create_user(password: @password, password_confirmation: @password).tap(&:confirm!)
11
+ @user = create_user(password: @password, password_confirmation: @password).tap(&:confirm)
12
12
  end
13
13
 
14
14
  test "yield resource to block on create success" do
@@ -32,4 +32,9 @@ class CustomRegistrationsControllerTest < ActionController::TestCase
32
32
  put :update, { user: { } }
33
33
  assert @controller.update_block_called?, "update failed to yield resource to provided block"
34
34
  end
35
+
36
+ test "yield resource to block on new" do
37
+ get :new
38
+ assert @controller.new_block_called?, "new failed to yield resource to provided block"
39
+ end
35
40
  end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class ApiController < ActionController::Metal
4
+ include Devise::Controllers::Helpers
5
+ end
6
+
7
+ class HelperMethodsTest < ActionController::TestCase
8
+ tests ApiController
9
+
10
+ test 'includes Devise::Controllers::Helpers' do
11
+ assert_includes @controller.class.ancestors, Devise::Controllers::Helpers
12
+ end
13
+
14
+ test 'does not respond_to helper_method' do
15
+ refute_respond_to @controller.class, :helper_method
16
+ end
17
+
18
+ test 'defines methods like current_user' do
19
+ assert_respond_to @controller, :current_user
20
+ end
21
+ end
@@ -245,6 +245,11 @@ class ControllerAuthenticatableTest < ActionController::TestCase
245
245
  assert_equal "/foo?bar=baz", @controller.stored_location_for(:user)
246
246
  end
247
247
 
248
+ test 'store location for stores fragments' do
249
+ @controller.store_location_for(:user, "/foo#bar")
250
+ assert_equal "/foo#bar", @controller.stored_location_for(:user)
251
+ end
252
+
248
253
  test 'after sign in path defaults to root path if none by was specified for the given scope' do
249
254
  assert_equal root_path, @controller.after_sign_in_path_for(:user)
250
255
  end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class SessionsInheritedController < Devise::SessionsController
4
+ def test_i18n_scope
5
+ set_flash_message(:notice, :signed_in)
6
+ end
7
+ end
8
+
9
+ class AnotherInheritedController < SessionsInheritedController
10
+ protected
11
+
12
+ def translation_scope
13
+ 'another'
14
+ end
15
+ end
16
+
17
+ class InheritedControllerTest < ActionController::TestCase
18
+ tests SessionsInheritedController
19
+
20
+ def setup
21
+ @mock_warden = OpenStruct.new
22
+ @controller.request.env['warden'] = @mock_warden
23
+ @controller.request.env['devise.mapping'] = Devise.mappings[:user]
24
+ end
25
+
26
+ test 'I18n scope is inherited from Devise::Sessions' do
27
+ I18n.expects(:t).with do |message, options|
28
+ message == 'user.signed_in' &&
29
+ options[:scope] == 'devise.sessions'
30
+ end
31
+ @controller.test_i18n_scope
32
+ end
33
+ end
34
+
35
+ class AnotherInheritedControllerTest < ActionController::TestCase
36
+ tests AnotherInheritedController
37
+
38
+ def setup
39
+ @mock_warden = OpenStruct.new
40
+ @controller.request.env['warden'] = @mock_warden
41
+ @controller.request.env['devise.mapping'] = Devise.mappings[:user]
42
+ end
43
+
44
+ test 'I18n scope is overridden' do
45
+ I18n.expects(:t).with do |message, options|
46
+ message == 'user.signed_in' &&
47
+ options[:scope] == 'another'
48
+ end
49
+ @controller.test_i18n_scope
50
+ end
51
+ end
@@ -13,16 +13,16 @@ class HelpersTest < ActionController::TestCase
13
13
  end
14
14
 
15
15
  test 'get resource name from env' do
16
- assert_equal :user, @controller.resource_name
16
+ assert_equal :user, @controller.send(:resource_name)
17
17
  end
18
18
 
19
19
  test 'get resource class from env' do
20
- assert_equal User, @controller.resource_class
20
+ assert_equal User, @controller.send(:resource_class)
21
21
  end
22
22
 
23
23
  test 'get resource instance variable from env' do
24
24
  @controller.instance_variable_set(:@user, user = User.new)
25
- assert_equal user, @controller.resource
25
+ assert_equal user, @controller.send(:resource)
26
26
  end
27
27
 
28
28
  test 'set resource instance variable from env' do
@@ -80,7 +80,7 @@ class HelpersTest < ActionController::TestCase
80
80
 
81
81
  test 'signed in resource returns signed in resource for current scope' do
82
82
  @mock_warden.expects(:authenticate).with(scope: :user).returns(User.new)
83
- assert_kind_of User, @controller.signed_in_resource
83
+ assert_kind_of User, @controller.send(:signed_in_resource)
84
84
  end
85
85
 
86
86
  test 'is a devise controller' do
@@ -99,6 +99,12 @@ class HelpersTest < ActionController::TestCase
99
99
  assert_equal 'non-blank', flash[:notice]
100
100
  end
101
101
 
102
+ test 'issues non-blank flash.now messages normally' do
103
+ I18n.stubs(:t).returns('non-blank')
104
+ @controller.send :set_flash_message, :notice, :send_instructions, { now: true }
105
+ assert_equal 'non-blank', flash.now[:notice]
106
+ end
107
+
102
108
  test 'uses custom i18n options' do
103
109
  @controller.stubs(:devise_i18n_options).returns(default: "devise custom options")
104
110
  @controller.send :set_flash_message, :notice, :invalid_i18n_messagesend_instructions
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class LoadHooksControllerTest < ActionController::TestCase
4
+ setup do
5
+ ActiveSupport.on_load(:devise_controller) do
6
+ define_method :defined_by_load_hook do
7
+ puts 'I am defined dynamically by activesupport load hook'
8
+ end
9
+ end
10
+ end
11
+
12
+ teardown do
13
+ DeviseController.class_eval { undef :defined_by_load_hook }
14
+ end
15
+
16
+ test 'load hook called when controller is loaded' do
17
+ assert DeviseController.instance_methods.include? :defined_by_load_hook
18
+ end
19
+ end
@@ -6,7 +6,7 @@ class PasswordsControllerTest < ActionController::TestCase
6
6
 
7
7
  setup do
8
8
  request.env["devise.mapping"] = Devise.mappings[:user]
9
- @user = create_user.tap(&:confirm!)
9
+ @user = create_user.tap(&:confirm)
10
10
  @raw = @user.send_reset_password_instructions
11
11
  end
12
12
 
@@ -36,7 +36,7 @@ class SessionsControllerTest < ActionController::TestCase
36
36
  request.session["user_return_to"] = 'foo.bar'
37
37
 
38
38
  user = create_user
39
- user.confirm!
39
+ user.confirm
40
40
  post :create, user: {
41
41
  email: user.email,
42
42
  password: user.password
@@ -50,7 +50,7 @@ class SessionsControllerTest < ActionController::TestCase
50
50
  request.session["user_return_to"] = 'foo.bar'
51
51
 
52
52
  user = create_user
53
- user.confirm!
53
+ user.confirm
54
54
  post :create, format: 'json', user: {
55
55
  email: user.email,
56
56
  password: user.password
@@ -72,7 +72,7 @@ class SessionsControllerTest < ActionController::TestCase
72
72
  test "#destroy doesn't set the flash if the requested format is not navigational" do
73
73
  request.env["devise.mapping"] = Devise.mappings[:user]
74
74
  user = create_user
75
- user.confirm!
75
+ user.confirm
76
76
  post :create, format: 'json', user: {
77
77
  email: user.email,
78
78
  password: user.password
@@ -13,6 +13,12 @@ class RoutesTest < ActionController::TestCase
13
13
  assert_equal @controller.send(:"#{prepend_path}#{name}_url", :user),
14
14
  send(:"#{prepend_path}user_#{name}_url")
15
15
 
16
+ # With string
17
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", "user"),
18
+ send(:"#{prepend_path}user_#{name}_path")
19
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", "user"),
20
+ send(:"#{prepend_path}user_#{name}_url")
21
+
16
22
  # Default url params
17
23
  assert_equal @controller.send(:"#{prepend_path}#{name}_path", :user, param: 123),
18
24
  send(:"#{prepend_path}user_#{name}_path", param: 123)
data/test/devise_test.rb CHANGED
@@ -14,11 +14,11 @@ class DeviseTest < ActiveSupport::TestCase
14
14
  test 'bcrypt on the class' do
15
15
  password = "super secret"
16
16
  klass = Struct.new(:pepper, :stretches).new("blahblah", 2)
17
- hash = Devise.bcrypt(klass, password)
17
+ hash = Devise::Encryptor.digest(klass, password)
18
18
  assert_equal ::BCrypt::Password.create(hash), hash
19
19
 
20
20
  klass = Struct.new(:pepper, :stretches).new("bla", 2)
21
- hash = Devise.bcrypt(klass, password)
21
+ hash = Devise::Encryptor.digest(klass, password)
22
22
  assert_not_equal ::BCrypt::Password.new(hash), hash
23
23
  end
24
24
 
@@ -95,7 +95,7 @@ class DeviseTest < ActiveSupport::TestCase
95
95
 
96
96
  test 'Devise.email_regexp should match valid email addresses' do
97
97
  valid_emails = ["test@example.com", "jo@jo.co", "f4$_m@you.com", "testing.example@example.com.ua"]
98
- non_valid_emails = ["rex", "test@go,com", "test user@example.com", "test_user@example server.com"]
98
+ non_valid_emails = ["rex", "test@go,com", "test user@example.com", "test_user@example server.com", "test_user@example.com."]
99
99
 
100
100
  valid_emails.each do |email|
101
101
  assert_match Devise.email_regexp, email
@@ -26,6 +26,22 @@ class FailureTest < ActiveSupport::TestCase
26
26
  end
27
27
  end
28
28
 
29
+ class FakeEngineApp < Devise::FailureApp
30
+ class FakeEngine
31
+ def new_user_on_engine_session_url _
32
+ '/user_on_engines/sign_in'
33
+ end
34
+ end
35
+
36
+ def main_app
37
+ raise 'main_app router called instead of fake_engine'
38
+ end
39
+
40
+ def fake_engine
41
+ @fake_engine ||= FakeEngine.new
42
+ end
43
+ end
44
+
29
45
  def self.context(name, &block)
30
46
  instance_eval(&block)
31
47
  end
@@ -85,6 +101,13 @@ class FailureTest < ActiveSupport::TestCase
85
101
  end
86
102
  end
87
103
 
104
+ test 'returns to the default redirect location considering the router for supplied scope' do
105
+ call_failure app: FakeEngineApp, 'warden.options' => { scope: :user_on_engine }
106
+ assert_equal 302, @response.first
107
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
108
+ assert_equal 'http://test.host/user_on_engines/sign_in', @response.second['Location']
109
+ end
110
+
88
111
  if Rails.application.config.respond_to?(:relative_url_root)
89
112
  test 'returns to the default redirect location considering the relative url root' do
90
113
  swap Rails.application.config, relative_url_root: "/sample" do
@@ -109,6 +132,13 @@ class FailureTest < ActiveSupport::TestCase
109
132
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
110
133
  end
111
134
 
135
+ test 'supports authentication_keys as a Hash for the flash message' do
136
+ swap Devise, authentication_keys: { email: true, login: true } do
137
+ call_failure('warden' => OpenStruct.new(message: :invalid))
138
+ assert_equal 'Invalid email, login or password.', @request.flash[:alert]
139
+ end
140
+ end
141
+
112
142
  test 'uses custom i18n options' do
113
143
  call_failure('warden' => OpenStruct.new(message: :does_not_exist), app: FailureWithI18nOptions)
114
144
  assert_equal 'User Steve does not exist', @request.flash[:alert]
@@ -264,5 +294,22 @@ class FailureTest < ActiveSupport::TestCase
264
294
  assert @response.third.body.include?('<h2>Log in</h2>')
265
295
  assert @response.third.body.include?('Your account is not activated yet.')
266
296
  end
297
+
298
+ if Rails.application.config.respond_to?(:relative_url_root)
299
+ test 'calls the original controller with the proper environment considering the relative url root' do
300
+ swap Rails.application.config, relative_url_root: "/sample" do
301
+ env = {
302
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/sample/users/sign_in"},
303
+ "devise.mapping" => Devise.mappings[:user],
304
+ "warden" => stub_everything
305
+ }
306
+ call_failure(env)
307
+ assert @response.third.body.include?('<h2>Log in</h2>')
308
+ assert @response.third.body.include?('Invalid email or password.')
309
+ assert_equal @request.env["SCRIPT_NAME"], '/sample'
310
+ assert_equal @request.env["PATH_INFO"], '/users/sign_in'
311
+ end
312
+ end
313
+ end
267
314
  end
268
315
  end
@@ -0,0 +1,48 @@
1
+ require "test_helper"
2
+
3
+ class ControllersGeneratorTest < Rails::Generators::TestCase
4
+ tests Devise::Generators::ControllersGenerator
5
+ destination File.expand_path("../../tmp", __FILE__)
6
+ setup :prepare_destination
7
+
8
+ test "Assert no controllers are created with no params" do
9
+ capture(:stderr) { run_generator }
10
+ assert_no_file "app/controllers/sessions_controller.rb"
11
+ assert_no_file "app/controllers/registrations_controller.rb"
12
+ assert_no_file "app/controllers/confirmations_controller.rb"
13
+ assert_no_file "app/controllers/passwords_controller.rb"
14
+ assert_no_file "app/controllers/unlocks_controller.rb"
15
+ assert_no_file "app/controllers/omniauth_callbacks_controller.rb"
16
+ end
17
+
18
+ test "Assert all controllers are properly created with scope param" do
19
+ run_generator %w(users)
20
+ assert_class_names 'users'
21
+
22
+ run_generator %w(admins)
23
+ assert_class_names 'admins'
24
+ end
25
+
26
+ test "Assert specified controllers with scope" do
27
+ run_generator %w(users -c sessions)
28
+ assert_file "app/controllers/users/sessions_controller.rb"
29
+ assert_no_file "app/controllers/users/registrations_controller.rb"
30
+ assert_no_file "app/controllers/users/confirmations_controller.rb"
31
+ assert_no_file "app/controllers/users/passwords_controller.rb"
32
+ assert_no_file "app/controllers/users/unlocks_controller.rb"
33
+ assert_no_file "app/controllers/users/omniauth_callbacks_controller.rb"
34
+ end
35
+
36
+ private
37
+
38
+ def assert_class_names(scope, options = {})
39
+ base_dir = "app/controllers#{scope.blank? ? '' : ('/' + scope)}"
40
+ scope_prefix = scope.blank? ? '' : (scope.camelize + '::')
41
+ controllers = options[:controllers] ||
42
+ %w(confirmations passwords registrations sessions unlocks omniauth_callbacks)
43
+
44
+ controllers.each do |c|
45
+ assert_file "#{base_dir}/#{c}_controller.rb", /#{scope_prefix + c.camelize}/
46
+ end
47
+ end
48
+ end
@@ -46,6 +46,13 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
46
46
  assert_no_file "app/views/devise/mailer/confirmation_instructions.html.erb"
47
47
  end
48
48
 
49
+ test "Assert mailer specific directory with simple form" do
50
+ run_generator %w(-v mailer -b simple_form_for)
51
+ assert_file "app/views/devise/mailer/confirmation_instructions.html.erb"
52
+ assert_file "app/views/devise/mailer/reset_password_instructions.html.erb"
53
+ assert_file "app/views/devise/mailer/unlock_instructions.html.erb"
54
+ end
55
+
49
56
  test "Assert specified directories with scope" do
50
57
  run_generator %w(users -v sessions)
51
58
  assert_file "app/views/users/sessions/new.html.erb"
@@ -78,7 +85,7 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
78
85
  assert_file "app/views/#{scope}/registrations/new.html.erb"
79
86
  assert_file "app/views/#{scope}/registrations/edit.html.erb"
80
87
  assert_file "app/views/#{scope}/sessions/new.html.erb"
81
- assert_file "app/views/#{scope}/shared/_links.erb"
88
+ assert_file "app/views/#{scope}/shared/_links.html.erb"
82
89
  assert_file "app/views/#{scope}/unlocks/new.html.erb"
83
90
  end
84
91
 
@@ -2,25 +2,22 @@ require 'test_helper'
2
2
 
3
3
  class DeviseHelperTest < ActionDispatch::IntegrationTest
4
4
  setup do
5
- model_labels = { models: { user: "utilisateur" } }
6
- # TODO: Remove this hack that fixes the I18n performance safeguards that
7
- # breaks the custom locale.
8
- I18n.available_locales += [:fr]
9
- I18n.backend.store_translations :fr,
10
- {
5
+ model_labels = { models: { user: "the user" } }
6
+ translations = {
11
7
  errors: { messages: { not_saved: {
12
- one: "Erreur lors de l'enregistrement de '%{resource}': 1 erreur.",
13
- other: "Erreur lors de l'enregistrement de '%{resource}': %{count} erreurs."
8
+ one: "Can't save %{resource} because of 1 error",
9
+ other: "Can't save %{resource} because of %{count} errors",
14
10
  } } },
15
11
  activerecord: model_labels,
16
12
  mongoid: model_labels
17
13
  }
18
14
 
19
- I18n.locale = 'fr'
15
+ I18n.available_locales
16
+ I18n.backend.store_translations(:en, translations)
20
17
  end
21
18
 
22
19
  teardown do
23
- I18n.locale = 'en'
20
+ I18n.reload!
24
21
  end
25
22
 
26
23
  test 'test errors.messages.not_saved with single error from i18n' do
@@ -31,7 +28,7 @@ class DeviseHelperTest < ActionDispatch::IntegrationTest
31
28
  click_button 'Sign up'
32
29
 
33
30
  assert_have_selector '#error_explanation'
34
- assert_contain "Erreur lors de l'enregistrement de 'utilisateur': 1 erreur"
31
+ assert_contain "Can't save the user because of 1 error"
35
32
  end
36
33
 
37
34
  test 'test errors.messages.not_saved with multiple errors from i18n' do
@@ -47,6 +44,6 @@ class DeviseHelperTest < ActionDispatch::IntegrationTest
47
44
  click_button 'Sign up'
48
45
 
49
46
  assert_have_selector '#error_explanation'
50
- assert_contain "Erreur lors de l'enregistrement de 'utilisateur': 2 erreurs"
47
+ assert_contain "Can't save the user because of 2 errors"
51
48
  end
52
49
  end
@@ -580,7 +580,7 @@ class AuthenticationKeysTest < ActionDispatch::IntegrationTest
580
580
  test 'missing authentication keys cause authentication to abort' do
581
581
  swap Devise, authentication_keys: [:subdomain] do
582
582
  sign_in_as_user
583
- assert_contain "Invalid email or password."
583
+ assert_contain "Invalid subdomain or password."
584
584
  assert_not warden.authenticated?(:user)
585
585
  end
586
586
  end
@@ -81,4 +81,15 @@ class DatabaseAuthenticationTest < ActionDispatch::IntegrationTest
81
81
  assert_contain 'Invalid credentials'
82
82
  end
83
83
  end
84
+
85
+ test 'valid sign in calls after_database_authentication callback' do
86
+ user = create_user(email: ' foo@bar.com ')
87
+
88
+ User.expects(:find_for_database_authentication).returns user
89
+ user.expects :after_database_authentication
90
+
91
+ sign_in_as_user do
92
+ fill_in 'email', with: 'foo@bar.com'
93
+ end
94
+ end
84
95
  end