devise 2.1.2 → 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 (242) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +39 -10
  3. data/.yardopts +9 -0
  4. data/{CHANGELOG.rdoc → CHANGELOG.md} +445 -112
  5. data/CODE_OF_CONDUCT.md +22 -0
  6. data/CONTRIBUTING.md +16 -0
  7. data/Gemfile +10 -15
  8. data/Gemfile.lock +151 -129
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +256 -96
  11. data/Rakefile +4 -2
  12. data/app/controllers/devise/confirmations_controller.rb +15 -7
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +6 -2
  14. data/app/controllers/devise/passwords_controller.rb +33 -9
  15. data/app/controllers/devise/registrations_controller.rb +66 -26
  16. data/app/controllers/devise/sessions_controller.rb +52 -21
  17. data/app/controllers/devise/unlocks_controller.rb +11 -6
  18. data/app/controllers/devise_controller.rb +65 -58
  19. data/app/helpers/devise_helper.rb +2 -2
  20. data/app/mailers/devise/mailer.rb +19 -10
  21. data/app/views/devise/confirmations/new.html.erb +8 -4
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +2 -2
  23. data/app/views/devise/mailer/password_change.html.erb +3 -0
  24. data/app/views/devise/mailer/reset_password_instructions.html.erb +2 -2
  25. data/app/views/devise/mailer/unlock_instructions.html.erb +2 -2
  26. data/app/views/devise/passwords/edit.html.erb +15 -6
  27. data/app/views/devise/passwords/new.html.erb +8 -4
  28. data/app/views/devise/registrations/edit.html.erb +29 -15
  29. data/app/views/devise/registrations/new.html.erb +19 -8
  30. data/app/views/devise/sessions/new.html.erb +17 -8
  31. data/app/views/devise/shared/{_links.erb → _links.html.erb} +4 -4
  32. data/app/views/devise/unlocks/new.html.erb +8 -4
  33. data/config/locales/en.yml +51 -47
  34. data/devise.gemspec +8 -6
  35. data/devise.png +0 -0
  36. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  37. data/gemfiles/Gemfile.rails-3.2-stable.lock +172 -0
  38. data/gemfiles/Gemfile.rails-4.0-stable +30 -0
  39. data/gemfiles/Gemfile.rails-4.0-stable.lock +166 -0
  40. data/gemfiles/Gemfile.rails-4.1-stable +30 -0
  41. data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
  42. data/gemfiles/Gemfile.rails-4.2-stable +30 -0
  43. data/gemfiles/Gemfile.rails-4.2-stable.lock +193 -0
  44. data/lib/devise/controllers/helpers.rb +126 -108
  45. data/lib/devise/controllers/rememberable.rb +19 -17
  46. data/lib/devise/controllers/scoped_views.rb +1 -1
  47. data/lib/devise/controllers/sign_in_out.rb +96 -0
  48. data/lib/devise/controllers/store_location.rb +58 -0
  49. data/lib/devise/controllers/url_helpers.rb +7 -7
  50. data/lib/devise/encryptor.rb +22 -0
  51. data/lib/devise/failure_app.rb +85 -25
  52. data/lib/devise/hooks/activatable.rb +5 -6
  53. data/lib/devise/hooks/csrf_cleaner.rb +7 -0
  54. data/lib/devise/hooks/forgetable.rb +1 -1
  55. data/lib/devise/hooks/lockable.rb +2 -2
  56. data/lib/devise/hooks/proxy.rb +21 -0
  57. data/lib/devise/hooks/rememberable.rb +5 -4
  58. data/lib/devise/hooks/timeoutable.rb +16 -8
  59. data/lib/devise/hooks/trackable.rb +1 -1
  60. data/lib/devise/mailers/helpers.rb +27 -23
  61. data/lib/devise/mapping.rb +11 -7
  62. data/lib/devise/models/authenticatable.rb +82 -66
  63. data/lib/devise/models/confirmable.rb +142 -55
  64. data/lib/devise/models/database_authenticatable.rb +59 -15
  65. data/lib/devise/models/lockable.rb +41 -30
  66. data/lib/devise/models/omniauthable.rb +3 -3
  67. data/lib/devise/models/recoverable.rb +56 -41
  68. data/lib/devise/models/rememberable.rb +65 -27
  69. data/lib/devise/models/timeoutable.rb +2 -8
  70. data/lib/devise/models/trackable.rb +6 -4
  71. data/lib/devise/models/validatable.rb +9 -9
  72. data/lib/devise/models.rb +4 -13
  73. data/lib/devise/modules.rb +10 -11
  74. data/lib/devise/omniauth/url_helpers.rb +2 -2
  75. data/lib/devise/orm/active_record.rb +1 -1
  76. data/lib/devise/orm/mongoid.rb +1 -1
  77. data/lib/devise/{param_filter.rb → parameter_filter.rb} +10 -11
  78. data/lib/devise/parameter_sanitizer.rb +99 -0
  79. data/lib/devise/rails/routes.rb +173 -115
  80. data/lib/devise/rails/warden_compat.rb +10 -31
  81. data/lib/devise/rails.rb +14 -12
  82. data/lib/devise/strategies/authenticatable.rb +26 -26
  83. data/lib/devise/strategies/base.rb +1 -1
  84. data/lib/devise/strategies/database_authenticatable.rb +8 -4
  85. data/lib/devise/strategies/rememberable.rb +15 -5
  86. data/lib/devise/test_helpers.rb +7 -5
  87. data/lib/devise/time_inflector.rb +14 -0
  88. data/lib/devise/token_generator.rb +70 -0
  89. data/lib/devise/version.rb +1 -1
  90. data/lib/devise.rb +110 -52
  91. data/lib/generators/active_record/devise_generator.rb +34 -18
  92. data/lib/generators/active_record/templates/migration.rb +5 -6
  93. data/lib/generators/active_record/templates/migration_existing.rb +5 -6
  94. data/lib/generators/devise/controllers_generator.rb +44 -0
  95. data/lib/generators/devise/devise_generator.rb +5 -3
  96. data/lib/generators/devise/install_generator.rb +5 -0
  97. data/lib/generators/devise/orm_helpers.rb +25 -6
  98. data/lib/generators/devise/views_generator.rb +52 -22
  99. data/lib/generators/mongoid/devise_generator.rb +21 -26
  100. data/lib/generators/templates/README +9 -5
  101. data/lib/generators/templates/controllers/README +14 -0
  102. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  103. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  104. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  105. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  106. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  107. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  108. data/lib/generators/templates/devise.rb +80 -43
  109. data/lib/generators/templates/markerb/confirmation_instructions.markerb +2 -2
  110. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  111. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  112. data/lib/generators/templates/markerb/unlock_instructions.markerb +2 -2
  113. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +3 -2
  114. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +4 -4
  115. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +2 -2
  116. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -6
  117. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +4 -4
  118. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +6 -6
  119. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +3 -2
  120. data/script/cached-bundle +49 -0
  121. data/script/s3-put +71 -0
  122. data/test/controllers/custom_registrations_controller_test.rb +40 -0
  123. data/test/controllers/helper_methods_test.rb +21 -0
  124. data/test/controllers/helpers_test.rb +95 -32
  125. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  126. data/test/controllers/internal_helpers_test.rb +39 -14
  127. data/test/controllers/load_hooks_controller_test.rb +19 -0
  128. data/test/controllers/passwords_controller_test.rb +31 -0
  129. data/test/controllers/sessions_controller_test.rb +66 -6
  130. data/test/controllers/url_helpers_test.rb +10 -4
  131. data/test/delegator_test.rb +1 -1
  132. data/test/devise_test.rb +45 -10
  133. data/test/failure_app_test.rb +121 -27
  134. data/test/generators/active_record_generator_test.rb +48 -8
  135. data/test/generators/controllers_generator_test.rb +48 -0
  136. data/test/generators/devise_generator_test.rb +2 -2
  137. data/test/generators/mongoid_generator_test.rb +3 -3
  138. data/test/generators/views_generator_test.rb +54 -3
  139. data/test/helpers/devise_helper_test.rb +18 -20
  140. data/test/integration/authenticatable_test.rb +161 -65
  141. data/test/integration/confirmable_test.rb +146 -77
  142. data/test/integration/database_authenticatable_test.rb +43 -30
  143. data/test/integration/http_authenticatable_test.rb +30 -22
  144. data/test/integration/lockable_test.rb +64 -49
  145. data/test/integration/omniauthable_test.rb +17 -15
  146. data/test/integration/recoverable_test.rb +111 -70
  147. data/test/integration/registerable_test.rb +114 -79
  148. data/test/integration/rememberable_test.rb +87 -31
  149. data/test/integration/timeoutable_test.rb +77 -33
  150. data/test/integration/trackable_test.rb +5 -5
  151. data/test/mailers/confirmation_instructions_test.rb +28 -8
  152. data/test/mailers/reset_password_instructions_test.rb +21 -8
  153. data/test/mailers/unlock_instructions_test.rb +20 -6
  154. data/test/mapping_test.rb +12 -5
  155. data/test/models/authenticatable_test.rb +17 -1
  156. data/test/models/confirmable_test.rb +216 -62
  157. data/test/models/database_authenticatable_test.rb +129 -49
  158. data/test/models/lockable_test.rb +132 -45
  159. data/test/models/recoverable_test.rb +100 -54
  160. data/test/models/rememberable_test.rb +89 -94
  161. data/test/models/serializable_test.rb +12 -11
  162. data/test/models/timeoutable_test.rb +6 -1
  163. data/test/models/trackable_test.rb +28 -0
  164. data/test/models/validatable_test.rb +31 -21
  165. data/test/models_test.rb +22 -48
  166. data/test/omniauth/config_test.rb +4 -4
  167. data/test/omniauth/url_helpers_test.rb +7 -4
  168. data/test/orm/active_record.rb +1 -0
  169. data/test/orm/mongoid.rb +2 -3
  170. data/test/parameter_sanitizer_test.rb +81 -0
  171. data/test/rails_app/Rakefile +0 -4
  172. data/test/rails_app/app/active_record/shim.rb +1 -1
  173. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  174. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  175. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  176. data/test/rails_app/app/controllers/admins/sessions_controller.rb +1 -1
  177. data/test/rails_app/app/controllers/admins_controller.rb +0 -5
  178. data/test/rails_app/app/controllers/application_controller.rb +6 -2
  179. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  180. data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
  181. data/test/rails_app/app/controllers/home_controller.rb +1 -1
  182. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +1 -1
  183. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +1 -1
  184. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +4 -4
  185. data/test/rails_app/app/controllers/users_controller.rb +12 -4
  186. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  187. data/test/rails_app/app/mailers/users/mailer.rb +1 -1
  188. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  189. data/test/rails_app/app/mongoid/admin.rb +12 -10
  190. data/test/rails_app/app/mongoid/shim.rb +4 -5
  191. data/test/rails_app/app/mongoid/user.rb +19 -22
  192. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  193. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  194. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  195. data/test/rails_app/app/views/admins/sessions/new.html.erb +1 -1
  196. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -1
  197. data/test/rails_app/app/views/home/index.html.erb +1 -1
  198. data/test/rails_app/app/views/home/join.html.erb +1 -1
  199. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -1
  200. data/test/rails_app/app/views/layouts/application.html.erb +1 -1
  201. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  202. data/test/rails_app/bin/bundle +3 -0
  203. data/test/rails_app/bin/rails +4 -0
  204. data/test/rails_app/bin/rake +4 -0
  205. data/test/rails_app/config/application.rb +4 -5
  206. data/test/rails_app/config/boot.rb +9 -3
  207. data/test/rails_app/config/environment.rb +2 -2
  208. data/test/rails_app/config/environments/development.rb +19 -7
  209. data/test/rails_app/config/environments/production.rb +68 -17
  210. data/test/rails_app/config/environments/test.rb +24 -16
  211. data/test/rails_app/config/initializers/devise.rb +22 -20
  212. data/test/rails_app/config/initializers/secret_token.rb +8 -2
  213. data/test/rails_app/config/initializers/session_store.rb +1 -0
  214. data/test/rails_app/config/routes.rb +71 -46
  215. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +9 -12
  216. data/test/rails_app/db/schema.rb +21 -18
  217. data/test/rails_app/lib/shared_admin.rb +7 -4
  218. data/test/rails_app/lib/shared_user.rb +6 -3
  219. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  220. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  221. data/test/rails_test.rb +9 -0
  222. data/test/routes_test.rb +94 -78
  223. data/test/support/action_controller/record_identifier.rb +10 -0
  224. data/test/support/assertions.rb +2 -3
  225. data/test/support/helpers.rb +18 -32
  226. data/test/support/integration.rb +17 -16
  227. data/test/support/locale/en.yml +4 -0
  228. data/test/support/mongoid.yml +6 -0
  229. data/test/test_helper.rb +8 -1
  230. data/test/test_helpers_test.rb +64 -20
  231. data/test/test_models.rb +33 -0
  232. data/test/time_helpers.rb +137 -0
  233. metadata +172 -51
  234. data/app/views/devise/_links.erb +0 -3
  235. data/gemfiles/Gemfile.rails-3.1.x +0 -35
  236. data/gemfiles/Gemfile.rails-3.1.x.lock +0 -167
  237. data/lib/devise/models/token_authenticatable.rb +0 -77
  238. data/lib/devise/strategies/token_authenticatable.rb +0 -56
  239. data/test/indifferent_hash.rb +0 -33
  240. data/test/integration/token_authenticatable_test.rb +0 -161
  241. data/test/models/token_authenticatable_test.rb +0 -55
  242. data/test/rails_app/script/rails +0 -10
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ResetPasswordInstructionsTest < ActionMailer::TestCase
4
-
5
4
  def setup
6
5
  setup_mailer
7
6
  Devise.mailer = 'Devise::Mailer'
@@ -49,34 +48,48 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
49
48
  assert_equal ['custom@example.com'], mail.from
50
49
  end
51
50
 
51
+ test 'setup sender from custom mailer defaults with proc' do
52
+ Devise.mailer = 'Users::FromProcMailer'
53
+ assert_equal ['custom@example.com'], mail.from
54
+ end
55
+
56
+ test 'custom mailer renders parent mailer template' do
57
+ Devise.mailer = 'Users::Mailer'
58
+ assert_present mail.body.encoded
59
+ end
60
+
52
61
  test 'setup reply to as copy from sender' do
53
62
  assert_equal ['test@example.com'], mail.reply_to
54
63
  end
55
64
 
56
65
  test 'setup subject from I18n' do
57
- store_translations :en, :devise => { :mailer => { :reset_password_instructions => { :subject => 'Reset instructions' } } } do
66
+ store_translations :en, devise: { mailer: { reset_password_instructions: { subject: 'Reset instructions' } } } do
58
67
  assert_equal 'Reset instructions', mail.subject
59
68
  end
60
69
  end
61
70
 
62
71
  test 'subject namespaced by model' do
63
- store_translations :en, :devise => { :mailer => { :reset_password_instructions => { :user_subject => 'User Reset Instructions' } } } do
72
+ store_translations :en, devise: { mailer: { reset_password_instructions: { user_subject: 'User Reset Instructions' } } } do
64
73
  assert_equal 'User Reset Instructions', mail.subject
65
74
  end
66
75
  end
67
76
 
68
77
  test 'body should have user info' do
69
- assert_match(/#{user.email}/, mail.body.encoded)
78
+ assert_match user.email, mail.body.encoded
70
79
  end
71
80
 
72
81
  test 'body should have link to confirm the account' do
73
- host = ActionMailer::Base.default_url_options[:host]
74
- reset_url_regexp = %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=#{user.reset_password_token}">}
75
- assert_match reset_url_regexp, mail.body.encoded
82
+ host, port = ActionMailer::Base.default_url_options.values_at :host, :port
83
+
84
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/password/edit\?reset_password_token=([^"]+)">}
85
+ assert_equal Devise.token_generator.digest(user.class, :reset_password_token, $1), user.reset_password_token
86
+ else
87
+ flunk "expected reset password url regex to match"
88
+ end
76
89
  end
77
90
 
78
91
  test 'mailer sender accepts a proc' do
79
- swap Devise, :mailer_sender => proc { "another@example.com" } do
92
+ swap Devise, mailer_sender: proc { "another@example.com" } do
80
93
  assert_equal ['another@example.com'], mail.from
81
94
  end
82
95
  end
@@ -49,29 +49,43 @@ class UnlockInstructionsTest < ActionMailer::TestCase
49
49
  assert_equal ['custom@example.com'], mail.from
50
50
  end
51
51
 
52
+ test 'setup sender from custom mailer defaults with proc' do
53
+ Devise.mailer = 'Users::FromProcMailer'
54
+ assert_equal ['custom@example.com'], mail.from
55
+ end
56
+
57
+ test 'custom mailer renders parent mailer template' do
58
+ Devise.mailer = 'Users::Mailer'
59
+ assert_present mail.body.encoded
60
+ end
61
+
52
62
  test 'setup reply to as copy from sender' do
53
63
  assert_equal ['test@example.com'], mail.reply_to
54
64
  end
55
65
 
56
66
  test 'setup subject from I18n' do
57
- store_translations :en, :devise => { :mailer => { :unlock_instructions => { :subject => 'Yo unlock instructions' } } } do
67
+ store_translations :en, devise: { mailer: { unlock_instructions: { subject: 'Yo unlock instructions' } } } do
58
68
  assert_equal 'Yo unlock instructions', mail.subject
59
69
  end
60
70
  end
61
71
 
62
72
  test 'subject namespaced by model' do
63
- store_translations :en, :devise => { :mailer => { :unlock_instructions => { :user_subject => 'User Unlock Instructions' } } } do
73
+ store_translations :en, devise: { mailer: { unlock_instructions: { user_subject: 'User Unlock Instructions' } } } do
64
74
  assert_equal 'User Unlock Instructions', mail.subject
65
75
  end
66
76
  end
67
77
 
68
78
  test 'body should have user info' do
69
- assert_match(/#{user.email}/, mail.body.encoded)
79
+ assert_match user.email, mail.body.encoded
70
80
  end
71
81
 
72
82
  test 'body should have link to unlock the account' do
73
- host = ActionMailer::Base.default_url_options[:host]
74
- unlock_url_regexp = %r{<a href=\"http://#{host}/users/unlock\?unlock_token=#{user.unlock_token}">}
75
- assert_match unlock_url_regexp, mail.body.encoded
83
+ host, port = ActionMailer::Base.default_url_options.values_at :host, :port
84
+
85
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/unlock\?unlock_token=([^"]+)">}
86
+ assert_equal Devise.token_generator.digest(user.class, :unlock_token, $1), user.unlock_token
87
+ else
88
+ flunk "expected unlock url regex to match"
89
+ end
76
90
  end
77
91
  end
data/test/mapping_test.rb CHANGED
@@ -50,18 +50,19 @@ class MappingTest < ActiveSupport::TestCase
50
50
  end
51
51
 
52
52
  test 'has strategies depending on the model declaration' do
53
- assert_equal [:rememberable, :token_authenticatable, :database_authenticatable], Devise.mappings[:user].strategies
53
+ assert_equal [:rememberable, :database_authenticatable], Devise.mappings[:user].strategies
54
54
  assert_equal [:database_authenticatable], Devise.mappings[:admin].strategies
55
55
  end
56
56
 
57
57
  test 'has no input strategies depending on the model declaration' do
58
- assert_equal [:rememberable, :token_authenticatable], Devise.mappings[:user].no_input_strategies
58
+ assert_equal [:rememberable], Devise.mappings[:user].no_input_strategies
59
59
  assert_equal [], Devise.mappings[:admin].no_input_strategies
60
60
  end
61
61
 
62
62
  test 'find scope for a given object' do
63
63
  assert_equal :user, Devise::Mapping.find_scope!(User)
64
64
  assert_equal :user, Devise::Mapping.find_scope!(:user)
65
+ assert_equal :user, Devise::Mapping.find_scope!("user")
65
66
  assert_equal :user, Devise::Mapping.find_scope!(User.new)
66
67
  end
67
68
 
@@ -70,6 +71,12 @@ class MappingTest < ActiveSupport::TestCase
70
71
  assert_equal :user, Devise::Mapping.find_scope!(Class.new(User).new)
71
72
  end
72
73
 
74
+ test 'find scope uses devise_scope' do
75
+ user = User.new
76
+ def user.devise_scope; :special_scope; end
77
+ assert_equal :special_scope, Devise::Mapping.find_scope!(user)
78
+ end
79
+
73
80
  test 'find scope raises an error if cannot be found' do
74
81
  assert_raise RuntimeError do
75
82
  Devise::Mapping.find_scope!(String)
@@ -110,12 +117,12 @@ class MappingTest < ActiveSupport::TestCase
110
117
  assert mapping.lockable?
111
118
  assert_not mapping.omniauthable?
112
119
  end
113
-
120
+
114
121
  test 'find mapping by path' do
115
122
  assert_raise RuntimeError do
116
123
  Devise::Mapping.find_by_path!('/accounts/facebook/callback')
117
124
  end
118
-
125
+
119
126
  assert_nothing_raised do
120
127
  Devise::Mapping.find_by_path!('/:locale/accounts/login')
121
128
  end
@@ -123,5 +130,5 @@ class MappingTest < ActiveSupport::TestCase
123
130
  assert_nothing_raised do
124
131
  Devise::Mapping.find_by_path!('/accounts/facebook/callback', :path)
125
132
  end
126
- end
133
+ end
127
134
  end
@@ -4,4 +4,20 @@ class AuthenticatableTest < ActiveSupport::TestCase
4
4
  test 'required_fields should be an empty array' do
5
5
  assert_equal Devise::Models::Validatable.required_fields(User), []
6
6
  end
7
- end
7
+
8
+ test 'find_first_by_auth_conditions allows custom filtering parameters' do
9
+ user = User.create!(email: "example@example.com", password: "1234567")
10
+ assert_equal User.find_first_by_auth_conditions({ email: "example@example.com" }), user
11
+ assert_nil User.find_first_by_auth_conditions({ email: "example@example.com" }, id: user.id.to_s.next)
12
+ end
13
+
14
+ if defined?(ActionController::Parameters)
15
+ test 'does not passes an ActionController::Parameters to find_first_by_auth_conditions through find_or_initialize_with_errors' do
16
+ user = create_user(email: 'example@example.com')
17
+ attributes = ActionController::Parameters.new(email: 'example@example.com')
18
+
19
+ User.expects(:find_first_by_auth_conditions).with('email' => 'example@example.com').returns(user)
20
+ User.find_or_initialize_with_errors([:email], attributes)
21
+ end
22
+ end
23
+ end
@@ -23,37 +23,31 @@ class ConfirmableTest < ActiveSupport::TestCase
23
23
  test 'should confirm a user by updating confirmed at' do
24
24
  user = create_user
25
25
  assert_nil user.confirmed_at
26
- assert user.confirm!
26
+ assert user.confirm
27
27
  assert_not_nil user.confirmed_at
28
28
  end
29
29
 
30
- test 'should clear confirmation token while confirming a user' do
31
- user = create_user
32
- assert_present user.confirmation_token
33
- user.confirm!
34
- assert_nil user.confirmation_token
35
- end
36
-
37
30
  test 'should verify whether a user is confirmed or not' do
38
31
  assert_not new_user.confirmed?
39
32
  user = create_user
40
33
  assert_not user.confirmed?
41
- user.confirm!
34
+ user.confirm
42
35
  assert user.confirmed?
43
36
  end
44
37
 
45
38
  test 'should not confirm a user already confirmed' do
46
39
  user = create_user
47
- assert user.confirm!
40
+ assert user.confirm
48
41
  assert_blank user.errors[:email]
49
42
 
50
- assert_not user.confirm!
43
+ assert_not user.confirm
51
44
  assert_equal "was already confirmed, please try signing in", user.errors[:email].join
52
45
  end
53
46
 
54
- test 'should find and confirm a user automatically' do
47
+ test 'should find and confirm a user automatically based on the raw token' do
55
48
  user = create_user
56
- confirmed_user = User.confirm_by_token(user.confirmation_token)
49
+ raw = user.raw_confirmation_token
50
+ confirmed_user = User.confirm_by_token(raw)
57
51
  assert_equal confirmed_user, user
58
52
  assert user.reload.confirmed?
59
53
  end
@@ -74,14 +68,24 @@ class ConfirmableTest < ActiveSupport::TestCase
74
68
  user = create_user
75
69
  user.confirmed_at = Time.now
76
70
  user.save
77
- confirmed_user = User.confirm_by_token(user.confirmation_token)
71
+ confirmed_user = User.confirm_by_token(user.raw_confirmation_token)
78
72
  assert confirmed_user.confirmed?
79
73
  assert_equal "was already confirmed, please try signing in", confirmed_user.errors[:email].join
80
74
  end
81
75
 
76
+ test 'should show error when a token has already been used' do
77
+ user = create_user
78
+ raw = user.raw_confirmation_token
79
+ User.confirm_by_token(raw)
80
+ assert user.reload.confirmed?
81
+
82
+ confirmed_user = User.confirm_by_token(raw)
83
+ assert_equal "was already confirmed, please try signing in", confirmed_user.errors[:email].join
84
+ end
85
+
82
86
  test 'should send confirmation instructions by email' do
83
87
  assert_email_sent "mynewuser@example.com" do
84
- create_user :email => "mynewuser@example.com"
88
+ create_user email: "mynewuser@example.com"
85
89
  end
86
90
  end
87
91
 
@@ -104,19 +108,37 @@ class ConfirmableTest < ActiveSupport::TestCase
104
108
  end
105
109
  end
106
110
 
111
+ test 'should skip confirmation e-mail without confirming if skip_confirmation_notification! is invoked' do
112
+ user = new_user
113
+ user.skip_confirmation_notification!
114
+
115
+ assert_email_not_sent do
116
+ user.save!
117
+ assert_not user.confirmed?
118
+ end
119
+ end
120
+
121
+ test 'should not send confirmation when no email is provided' do
122
+ assert_email_not_sent do
123
+ user = new_user
124
+ user.email = ''
125
+ user.save(validate: false)
126
+ end
127
+ end
128
+
107
129
  test 'should find a user to send confirmation instructions' do
108
130
  user = create_user
109
- confirmation_user = User.send_confirmation_instructions(:email => user.email)
131
+ confirmation_user = User.send_confirmation_instructions(email: user.email)
110
132
  assert_equal confirmation_user, user
111
133
  end
112
134
 
113
135
  test 'should return a new user if no email was found' do
114
- confirmation_user = User.send_confirmation_instructions(:email => "invalid@example.com")
136
+ confirmation_user = User.send_confirmation_instructions(email: "invalid@example.com")
115
137
  assert_not confirmation_user.persisted?
116
138
  end
117
139
 
118
140
  test 'should add error to new user email if no email was found' do
119
- confirmation_user = User.send_confirmation_instructions(:email => "invalid@example.com")
141
+ confirmation_user = User.send_confirmation_instructions(email: "invalid@example.com")
120
142
  assert confirmation_user.errors[:email]
121
143
  assert_equal "not found", confirmation_user.errors[:email].join
122
144
  end
@@ -124,7 +146,7 @@ class ConfirmableTest < ActiveSupport::TestCase
124
146
  test 'should send email instructions for the user confirm its email' do
125
147
  user = create_user
126
148
  assert_email_sent user.email do
127
- User.send_confirmation_instructions(:email => user.email)
149
+ User.send_confirmation_instructions(email: user.email)
128
150
  end
129
151
  end
130
152
 
@@ -136,7 +158,7 @@ class ConfirmableTest < ActiveSupport::TestCase
136
158
  assert_not_nil user.reload.confirmation_token
137
159
  end
138
160
 
139
- test 'should not resend email instructions if the user change his email' do
161
+ test 'should not resend email instructions if the user change their email' do
140
162
  user = create_user
141
163
  user.email = 'new_test@example.com'
142
164
  assert_email_not_sent do
@@ -146,25 +168,26 @@ class ConfirmableTest < ActiveSupport::TestCase
146
168
 
147
169
  test 'should not reset confirmation status or token when updating email' do
148
170
  user = create_user
149
- user.confirm!
171
+ original_token = user.confirmation_token
172
+ user.confirm
150
173
  user.email = 'new_test@example.com'
151
174
  user.save!
152
175
 
153
176
  user.reload
154
177
  assert user.confirmed?
155
- assert_nil user.confirmation_token
178
+ assert_equal original_token, user.confirmation_token
156
179
  end
157
180
 
158
181
  test 'should not be able to send instructions if the user is already confirmed' do
159
182
  user = create_user
160
- user.confirm!
161
- assert_not user.resend_confirmation_token
183
+ user.confirm
184
+ assert_not user.resend_confirmation_instructions
162
185
  assert user.confirmed?
163
186
  assert_equal 'was already confirmed, please try signing in', user.errors[:email].join
164
187
  end
165
188
 
166
189
  test 'confirm time should fallback to devise confirm in default configuration' do
167
- swap Devise, :allow_unconfirmed_access_for => 1.day do
190
+ swap Devise, allow_unconfirmed_access_for: 1.day do
168
191
  user = new_user
169
192
  user.confirmation_sent_at = 2.days.ago
170
193
  assert_not user.active_for_authentication?
@@ -175,7 +198,7 @@ class ConfirmableTest < ActiveSupport::TestCase
175
198
  end
176
199
 
177
200
  test 'should be active when confirmation sent at is not overpast' do
178
- swap Devise, :allow_unconfirmed_access_for => 5.days do
201
+ swap Devise, allow_unconfirmed_access_for: 5.days do
179
202
  Devise.allow_unconfirmed_access_for = 5.days
180
203
  user = create_user
181
204
 
@@ -192,7 +215,7 @@ class ConfirmableTest < ActiveSupport::TestCase
192
215
  assert_not user.confirmed?
193
216
  assert_not user.active_for_authentication?
194
217
 
195
- user.confirm!
218
+ user.confirm
196
219
  assert user.confirmed?
197
220
  assert user.active_for_authentication?
198
221
  end
@@ -200,10 +223,18 @@ class ConfirmableTest < ActiveSupport::TestCase
200
223
  test 'should not be active when confirm in is zero' do
201
224
  Devise.allow_unconfirmed_access_for = 0.days
202
225
  user = create_user
203
- user.confirmation_sent_at = Date.today
226
+ user.confirmation_sent_at = Time.zone.today
204
227
  assert_not user.active_for_authentication?
205
228
  end
206
229
 
230
+ test 'should be active when we set allow_unconfirmed_access_for to nil' do
231
+ swap Devise, allow_unconfirmed_access_for: nil do
232
+ user = create_user
233
+ user.confirmation_sent_at = Time.zone.today
234
+ assert user.active_for_authentication?
235
+ end
236
+ end
237
+
207
238
  test 'should not be active without confirmation' do
208
239
  user = create_user
209
240
  user.confirmation_sent_at = nil
@@ -219,113 +250,222 @@ class ConfirmableTest < ActiveSupport::TestCase
219
250
  assert user.reload.active_for_authentication?
220
251
  end
221
252
 
253
+ test 'should not break when a user tries to reset their password in the case where confirmation is not required and confirm_within is set' do
254
+ swap Devise, confirm_within: 3.days do
255
+ user = create_user
256
+ user.instance_eval { def confirmation_required?; false end }
257
+ user.confirmation_sent_at = nil
258
+ user.save
259
+ assert user.reload.confirm!
260
+ end
261
+ end
262
+
222
263
  test 'should find a user to send email instructions for the user confirm its email by authentication_keys' do
223
- swap Devise, :authentication_keys => [:username, :email] do
264
+ swap Devise, authentication_keys: [:username, :email] do
224
265
  user = create_user
225
- confirm_user = User.send_confirmation_instructions(:email => user.email, :username => user.username)
266
+ confirm_user = User.send_confirmation_instructions(email: user.email, username: user.username)
226
267
  assert_equal confirm_user, user
227
268
  end
228
269
  end
229
270
 
230
271
  test 'should require all confirmation_keys' do
231
- swap Devise, :confirmation_keys => [:username, :email] do
272
+ swap Devise, confirmation_keys: [:username, :email] do
232
273
  user = create_user
233
- confirm_user = User.send_confirmation_instructions(:email => user.email)
274
+ confirm_user = User.send_confirmation_instructions(email: user.email)
234
275
  assert_not confirm_user.persisted?
235
276
  assert_equal "can't be blank", confirm_user.errors[:username].join
236
277
  end
237
278
  end
279
+
280
+ def confirm_user_by_token_with_confirmation_sent_at(confirmation_sent_at)
281
+ user = create_user
282
+ user.update_attribute(:confirmation_sent_at, confirmation_sent_at)
283
+ confirmed_user = User.confirm_by_token(user.raw_confirmation_token)
284
+ assert_equal confirmed_user, user
285
+ user.reload.confirmed?
286
+ end
287
+
288
+ test 'should accept confirmation email token even after 5 years when no expiration is set' do
289
+ assert confirm_user_by_token_with_confirmation_sent_at(5.years.ago)
290
+ end
291
+
292
+ test 'should accept confirmation email token after 2 days when expiration is set to 3 days' do
293
+ swap Devise, confirm_within: 3.days do
294
+ assert confirm_user_by_token_with_confirmation_sent_at(2.days.ago)
295
+ end
296
+ end
297
+
298
+ test 'should not accept confirmation email token after 4 days when expiration is set to 3 days' do
299
+ swap Devise, confirm_within: 3.days do
300
+ assert_not confirm_user_by_token_with_confirmation_sent_at(4.days.ago)
301
+ end
302
+ end
303
+
304
+ test 'do not generate a new token on resend' do
305
+ user = create_user
306
+ old = user.confirmation_token
307
+ user = User.find(user.id)
308
+ user.resend_confirmation_instructions
309
+ assert_equal user.confirmation_token, old
310
+ end
311
+
312
+ test 'generate a new token after first has expired' do
313
+ swap Devise, confirm_within: 3.days do
314
+ user = create_user
315
+ old = user.confirmation_token
316
+ user.update_attribute(:confirmation_sent_at, 4.days.ago)
317
+ user = User.find(user.id)
318
+ user.resend_confirmation_instructions
319
+ assert_not_equal user.confirmation_token, old
320
+ end
321
+ end
322
+
323
+ test 'should call after_confirmation if confirmed' do
324
+ user = create_user
325
+ user.define_singleton_method :after_confirmation do
326
+ self.username = self.username.to_s + 'updated'
327
+ end
328
+ old = user.username
329
+ assert user.confirm
330
+ assert_not_equal user.username, old
331
+ end
332
+
333
+ test 'should not call after_confirmation if not confirmed' do
334
+ user = create_user
335
+ assert user.confirm
336
+ user.define_singleton_method :after_confirmation do
337
+ self.username = self.username.to_s + 'updated'
338
+ end
339
+ old = user.username
340
+ assert_not user.confirm
341
+ assert_equal user.username, old
342
+ end
343
+
344
+ test 'should always perform validations upon confirm when ensure valid true' do
345
+ admin = create_admin
346
+ admin.stubs(:valid?).returns(false)
347
+ assert_not admin.confirm(ensure_valid: true)
348
+ end
238
349
  end
239
350
 
240
351
  class ReconfirmableTest < ActiveSupport::TestCase
241
352
  test 'should not worry about validations on confirm even with reconfirmable' do
242
353
  admin = create_admin
243
354
  admin.reset_password_token = "a"
244
- assert admin.confirm!
355
+ assert admin.confirm
245
356
  end
246
357
 
247
358
  test 'should generate confirmation token after changing email' do
248
359
  admin = create_admin
249
- assert admin.confirm!
250
- assert_nil admin.confirmation_token
251
- assert admin.update_attributes(:email => 'new_test@example.com')
252
- assert_not_nil admin.confirmation_token
360
+ assert admin.confirm
361
+ residual_token = admin.confirmation_token
362
+ assert admin.update_attributes(email: 'new_test@example.com')
363
+ assert_not_equal residual_token, admin.confirmation_token
253
364
  end
254
365
 
255
- test 'should not generate confirmation token if skipping reconfirmation after changing email' do
366
+ test 'should not regenerate confirmation token or require reconfirmation if skipping reconfirmation after changing email' do
256
367
  admin = create_admin
257
- assert admin.confirm!
368
+ original_token = admin.confirmation_token
369
+ assert admin.confirm
258
370
  admin.skip_reconfirmation!
259
- assert admin.update_attributes(:email => 'new_test@example.com')
260
- assert_nil admin.confirmation_token
371
+ assert admin.update_attributes(email: 'new_test@example.com')
372
+ assert admin.confirmed?
373
+ assert_not admin.pending_reconfirmation?
374
+ assert_equal original_token, admin.confirmation_token
261
375
  end
262
376
 
377
+ test 'should skip sending reconfirmation email when email is changed and skip_confirmation_notification! is invoked' do
378
+ admin = create_admin
379
+ admin.skip_confirmation_notification!
380
+
381
+ assert_email_not_sent do
382
+ admin.update_attributes(email: 'new_test@example.com')
383
+ end
384
+ end
263
385
 
264
386
  test 'should regenerate confirmation token after changing email' do
265
387
  admin = create_admin
266
- assert admin.confirm!
267
- assert admin.update_attributes(:email => 'old_test@example.com')
388
+ assert admin.confirm
389
+ assert admin.update_attributes(email: 'old_test@example.com')
268
390
  token = admin.confirmation_token
269
- assert admin.update_attributes(:email => 'new_test@example.com')
391
+ assert admin.update_attributes(email: 'new_test@example.com')
270
392
  assert_not_equal token, admin.confirmation_token
271
393
  end
272
394
 
273
395
  test 'should send confirmation instructions by email after changing email' do
274
396
  admin = create_admin
275
- assert admin.confirm!
397
+ assert admin.confirm
398
+ assert_email_sent "new_test@example.com" do
399
+ assert admin.update_attributes(email: 'new_test@example.com')
400
+ end
401
+ assert_match "new_test@example.com", ActionMailer::Base.deliveries.last.body.encoded
402
+ end
403
+
404
+ test 'should send confirmation instructions by email after changing email from nil' do
405
+ admin = create_admin(email: nil)
276
406
  assert_email_sent "new_test@example.com" do
277
- assert admin.update_attributes(:email => 'new_test@example.com')
407
+ assert admin.update_attributes(email: 'new_test@example.com')
278
408
  end
409
+ assert_match "new_test@example.com", ActionMailer::Base.deliveries.last.body.encoded
279
410
  end
280
411
 
281
412
  test 'should not send confirmation by email after changing password' do
282
413
  admin = create_admin
283
- assert admin.confirm!
414
+ assert admin.confirm
415
+ assert_email_not_sent do
416
+ assert admin.update_attributes(password: 'newpass', password_confirmation: 'newpass')
417
+ end
418
+ end
419
+
420
+ test 'should not send confirmation by email after changing to a blank email' do
421
+ admin = create_admin
422
+ assert admin.confirm
284
423
  assert_email_not_sent do
285
- assert admin.update_attributes(:password => 'newpass', :password_confirmation => 'newpass')
424
+ admin.email = ''
425
+ admin.save(validate: false)
286
426
  end
287
427
  end
288
428
 
289
429
  test 'should stay confirmed when email is changed' do
290
430
  admin = create_admin
291
- assert admin.confirm!
292
- assert admin.update_attributes(:email => 'new_test@example.com')
431
+ assert admin.confirm
432
+ assert admin.update_attributes(email: 'new_test@example.com')
293
433
  assert admin.confirmed?
294
434
  end
295
435
 
296
436
  test 'should update email only when it is confirmed' do
297
437
  admin = create_admin
298
- assert admin.confirm!
299
- assert admin.update_attributes(:email => 'new_test@example.com')
438
+ assert admin.confirm
439
+ assert admin.update_attributes(email: 'new_test@example.com')
300
440
  assert_not_equal 'new_test@example.com', admin.email
301
- assert admin.confirm!
441
+ assert admin.confirm
302
442
  assert_equal 'new_test@example.com', admin.email
303
443
  end
304
444
 
305
445
  test 'should not allow admin to get past confirmation email by resubmitting their new address' do
306
446
  admin = create_admin
307
- assert admin.confirm!
308
- assert admin.update_attributes(:email => 'new_test@example.com')
447
+ assert admin.confirm
448
+ assert admin.update_attributes(email: 'new_test@example.com')
309
449
  assert_not_equal 'new_test@example.com', admin.email
310
- assert admin.update_attributes(:email => 'new_test@example.com')
450
+ assert admin.update_attributes(email: 'new_test@example.com')
311
451
  assert_not_equal 'new_test@example.com', admin.email
312
452
  end
313
453
 
314
454
  test 'should find a admin by send confirmation instructions with unconfirmed_email' do
315
455
  admin = create_admin
316
- assert admin.confirm!
317
- assert admin.update_attributes(:email => 'new_test@example.com')
318
- confirmation_admin = Admin.send_confirmation_instructions(:email => admin.unconfirmed_email)
456
+ assert admin.confirm
457
+ assert admin.update_attributes(email: 'new_test@example.com')
458
+ confirmation_admin = Admin.send_confirmation_instructions(email: admin.unconfirmed_email)
319
459
  assert_equal confirmation_admin, admin
320
460
  end
321
461
 
322
462
  test 'should return a new admin if no email or unconfirmed_email was found' do
323
- confirmation_admin = Admin.send_confirmation_instructions(:email => "invalid@email.com")
463
+ confirmation_admin = Admin.send_confirmation_instructions(email: "invalid@email.com")
324
464
  assert_not confirmation_admin.persisted?
325
465
  end
326
466
 
327
467
  test 'should add error to new admin email if no email or unconfirmed_email was found' do
328
- confirmation_admin = Admin.send_confirmation_instructions(:email => "invalid@email.com")
468
+ confirmation_admin = Admin.send_confirmation_instructions(email: "invalid@email.com")
329
469
  assert confirmation_admin.errors[:email]
330
470
  assert_equal "not found", confirmation_admin.errors[:email].join
331
471
  end
@@ -334,7 +474,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
334
474
  admin = create_admin
335
475
  admin.unconfirmed_email = "new_test@email.com"
336
476
  assert admin.save
337
- admin = Admin.find_by_unconfirmed_email_with_errors(:email => "new_test@email.com")
477
+ admin = Admin.find_by_unconfirmed_email_with_errors(email: "new_test@email.com")
338
478
  assert admin.persisted?
339
479
  end
340
480
 
@@ -354,4 +494,18 @@ class ReconfirmableTest < ActiveSupport::TestCase
354
494
  :unconfirmed_email
355
495
  ]
356
496
  end
497
+
498
+ test 'should not require reconfirmation after creating a record' do
499
+ admin = create_admin
500
+ assert !admin.pending_reconfirmation?
501
+ end
502
+
503
+ test 'should not require reconfirmation after creating a record with #save called in callback' do
504
+ class Admin::WithSaveInCallback < Admin
505
+ after_create :save
506
+ end
507
+
508
+ admin = Admin::WithSaveInCallback.create(valid_attributes.except(:username))
509
+ assert !admin.pending_reconfirmation?
510
+ end
357
511
  end