devise 3.2.1 → 4.4.3

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 (254) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +58 -10
  3. data/CHANGELOG.md +199 -979
  4. data/CODE_OF_CONDUCT.md +22 -0
  5. data/CONTRIBUTING.md +73 -8
  6. data/Gemfile +19 -11
  7. data/Gemfile.lock +152 -119
  8. data/ISSUE_TEMPLATE.md +19 -0
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +347 -93
  11. data/Rakefile +4 -2
  12. data/app/controllers/devise/confirmations_controller.rb +11 -5
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +12 -6
  14. data/app/controllers/devise/passwords_controller.rb +20 -8
  15. data/app/controllers/devise/registrations_controller.rb +34 -19
  16. data/app/controllers/devise/sessions_controller.rb +47 -17
  17. data/app/controllers/devise/unlocks_controller.rb +9 -4
  18. data/app/controllers/devise_controller.rb +67 -31
  19. data/app/helpers/devise_helper.rb +4 -2
  20. data/app/mailers/devise/mailer.rb +10 -0
  21. data/app/views/devise/confirmations/new.html.erb +8 -4
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  23. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  24. data/app/views/devise/mailer/password_change.html.erb +3 -0
  25. data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
  26. data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
  27. data/app/views/devise/passwords/edit.html.erb +15 -6
  28. data/app/views/devise/passwords/new.html.erb +8 -4
  29. data/app/views/devise/registrations/edit.html.erb +28 -14
  30. data/app/views/devise/registrations/new.html.erb +19 -8
  31. data/app/views/devise/sessions/new.html.erb +17 -8
  32. data/app/views/devise/shared/{_links.erb → _links.html.erb} +2 -2
  33. data/app/views/devise/unlocks/new.html.erb +8 -4
  34. data/bin/test +13 -0
  35. data/config/locales/en.yml +22 -17
  36. data/devise.gemspec +7 -6
  37. data/gemfiles/Gemfile.rails-4.1-stable +32 -0
  38. data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
  39. data/gemfiles/Gemfile.rails-4.2-stable +32 -0
  40. data/gemfiles/Gemfile.rails-4.2-stable.lock +192 -0
  41. data/gemfiles/Gemfile.rails-5.0-stable +33 -0
  42. data/gemfiles/Gemfile.rails-5.0-stable.lock +192 -0
  43. data/gemfiles/Gemfile.rails-5.2-rc1 +26 -0
  44. data/gemfiles/Gemfile.rails-5.2-rc1.lock +201 -0
  45. data/guides/bug_report_templates/integration_test.rb +106 -0
  46. data/lib/devise.rb +107 -84
  47. data/lib/devise/controllers/helpers.rb +111 -31
  48. data/lib/devise/controllers/rememberable.rb +15 -6
  49. data/lib/devise/controllers/scoped_views.rb +3 -1
  50. data/lib/devise/controllers/sign_in_out.rb +39 -26
  51. data/lib/devise/controllers/store_location.rb +31 -2
  52. data/lib/devise/controllers/url_helpers.rb +9 -7
  53. data/lib/devise/delegator.rb +2 -0
  54. data/lib/devise/encryptor.rb +24 -0
  55. data/lib/devise/failure_app.rb +98 -39
  56. data/lib/devise/hooks/activatable.rb +7 -6
  57. data/lib/devise/hooks/csrf_cleaner.rb +5 -1
  58. data/lib/devise/hooks/forgetable.rb +2 -0
  59. data/lib/devise/hooks/lockable.rb +7 -2
  60. data/lib/devise/hooks/proxy.rb +4 -2
  61. data/lib/devise/hooks/rememberable.rb +4 -2
  62. data/lib/devise/hooks/timeoutable.rb +16 -9
  63. data/lib/devise/hooks/trackable.rb +3 -1
  64. data/lib/devise/mailers/helpers.rb +15 -12
  65. data/lib/devise/mapping.rb +8 -2
  66. data/lib/devise/models.rb +3 -1
  67. data/lib/devise/models/authenticatable.rb +63 -36
  68. data/lib/devise/models/confirmable.rb +121 -41
  69. data/lib/devise/models/database_authenticatable.rb +66 -23
  70. data/lib/devise/models/lockable.rb +30 -17
  71. data/lib/devise/models/omniauthable.rb +3 -1
  72. data/lib/devise/models/recoverable.rb +62 -26
  73. data/lib/devise/models/registerable.rb +2 -0
  74. data/lib/devise/models/rememberable.rb +62 -33
  75. data/lib/devise/models/timeoutable.rb +4 -8
  76. data/lib/devise/models/trackable.rb +12 -3
  77. data/lib/devise/models/validatable.rb +16 -9
  78. data/lib/devise/modules.rb +12 -10
  79. data/lib/devise/omniauth.rb +2 -0
  80. data/lib/devise/omniauth/config.rb +2 -0
  81. data/lib/devise/omniauth/url_helpers.rb +14 -5
  82. data/lib/devise/orm/active_record.rb +5 -1
  83. data/lib/devise/orm/mongoid.rb +6 -2
  84. data/lib/devise/parameter_filter.rb +2 -0
  85. data/lib/devise/parameter_sanitizer.rb +131 -69
  86. data/lib/devise/rails.rb +10 -13
  87. data/lib/devise/rails/routes.rb +147 -116
  88. data/lib/devise/rails/warden_compat.rb +3 -10
  89. data/lib/devise/secret_key_finder.rb +25 -0
  90. data/lib/devise/strategies/authenticatable.rb +20 -9
  91. data/lib/devise/strategies/base.rb +3 -1
  92. data/lib/devise/strategies/database_authenticatable.rb +8 -5
  93. data/lib/devise/strategies/rememberable.rb +15 -3
  94. data/lib/devise/test/controller_helpers.rb +165 -0
  95. data/lib/devise/test/integration_helpers.rb +63 -0
  96. data/lib/devise/test_helpers.rb +7 -124
  97. data/lib/devise/time_inflector.rb +4 -2
  98. data/lib/devise/token_generator.rb +3 -41
  99. data/lib/devise/version.rb +3 -1
  100. data/lib/generators/active_record/devise_generator.rb +47 -10
  101. data/lib/generators/active_record/templates/migration.rb +9 -7
  102. data/lib/generators/active_record/templates/migration_existing.rb +9 -7
  103. data/lib/generators/devise/controllers_generator.rb +46 -0
  104. data/lib/generators/devise/devise_generator.rb +9 -5
  105. data/lib/generators/devise/install_generator.rb +22 -0
  106. data/lib/generators/devise/orm_helpers.rb +8 -19
  107. data/lib/generators/devise/views_generator.rb +51 -28
  108. data/lib/generators/mongoid/devise_generator.rb +22 -19
  109. data/lib/generators/templates/README +5 -12
  110. data/lib/generators/templates/controllers/README +14 -0
  111. data/lib/generators/templates/controllers/confirmations_controller.rb +30 -0
  112. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +30 -0
  113. data/lib/generators/templates/controllers/passwords_controller.rb +34 -0
  114. data/lib/generators/templates/controllers/registrations_controller.rb +62 -0
  115. data/lib/generators/templates/controllers/sessions_controller.rb +27 -0
  116. data/lib/generators/templates/controllers/unlocks_controller.rb +30 -0
  117. data/lib/generators/templates/devise.rb +64 -35
  118. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  119. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  120. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  121. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  122. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  123. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +2 -2
  124. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +4 -4
  125. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +2 -2
  126. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +6 -6
  127. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +4 -4
  128. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +6 -6
  129. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +2 -2
  130. data/test/controllers/custom_registrations_controller_test.rb +42 -0
  131. data/test/controllers/custom_strategy_test.rb +10 -6
  132. data/test/controllers/helper_methods_test.rb +24 -0
  133. data/test/controllers/helpers_test.rb +88 -40
  134. data/test/controllers/inherited_controller_i18n_messages_test.rb +53 -0
  135. data/test/controllers/internal_helpers_test.rb +31 -22
  136. data/test/controllers/load_hooks_controller_test.rb +21 -0
  137. data/test/controllers/passwords_controller_test.rb +8 -5
  138. data/test/controllers/sessions_controller_test.rb +42 -33
  139. data/test/controllers/url_helpers_test.rb +13 -5
  140. data/test/delegator_test.rb +3 -1
  141. data/test/devise_test.rb +34 -19
  142. data/test/failure_app_test.rb +150 -42
  143. data/test/generators/active_record_generator_test.rb +58 -31
  144. data/test/generators/controllers_generator_test.rb +50 -0
  145. data/test/generators/devise_generator_test.rb +4 -2
  146. data/test/generators/install_generator_test.rb +16 -3
  147. data/test/generators/mongoid_generator_test.rb +5 -3
  148. data/test/generators/views_generator_test.rb +40 -2
  149. data/test/helpers/devise_helper_test.rb +20 -20
  150. data/test/integration/authenticatable_test.rb +134 -141
  151. data/test/integration/confirmable_test.rb +109 -67
  152. data/test/integration/database_authenticatable_test.rb +36 -23
  153. data/test/integration/http_authenticatable_test.rb +29 -20
  154. data/test/integration/lockable_test.rb +52 -49
  155. data/test/integration/mounted_engine_test.rb +38 -0
  156. data/test/integration/omniauthable_test.rb +30 -15
  157. data/test/integration/recoverable_test.rb +76 -61
  158. data/test/integration/registerable_test.rb +107 -91
  159. data/test/integration/rememberable_test.rb +82 -30
  160. data/test/integration/timeoutable_test.rb +48 -40
  161. data/test/integration/trackable_test.rb +15 -8
  162. data/test/mailers/confirmation_instructions_test.rb +16 -14
  163. data/test/mailers/email_changed_test.rb +132 -0
  164. data/test/mailers/mailer_test.rb +20 -0
  165. data/test/mailers/reset_password_instructions_test.rb +13 -11
  166. data/test/mailers/unlock_instructions_test.rb +12 -10
  167. data/test/mapping_test.rb +15 -6
  168. data/test/models/authenticatable_test.rb +15 -3
  169. data/test/models/confirmable_test.rb +190 -95
  170. data/test/models/database_authenticatable_test.rb +75 -41
  171. data/test/models/lockable_test.rb +115 -61
  172. data/test/models/omniauthable_test.rb +3 -1
  173. data/test/models/recoverable_test.rb +116 -37
  174. data/test/models/registerable_test.rb +3 -1
  175. data/test/models/rememberable_test.rb +95 -94
  176. data/test/models/serializable_test.rb +19 -8
  177. data/test/models/timeoutable_test.rb +10 -8
  178. data/test/models/trackable_test.rb +50 -1
  179. data/test/models/validatable_test.rb +24 -30
  180. data/test/models_test.rb +19 -8
  181. data/test/omniauth/config_test.rb +15 -11
  182. data/test/omniauth/url_helpers_test.rb +8 -9
  183. data/test/orm/active_record.rb +16 -2
  184. data/test/orm/mongoid.rb +4 -2
  185. data/test/parameter_sanitizer_test.rb +53 -57
  186. data/test/rails_app/app/active_record/admin.rb +2 -0
  187. data/test/rails_app/app/active_record/shim.rb +3 -1
  188. data/test/rails_app/app/active_record/user.rb +14 -0
  189. data/test/rails_app/app/active_record/user_on_engine.rb +9 -0
  190. data/test/rails_app/app/active_record/user_on_main_app.rb +9 -0
  191. data/test/rails_app/app/active_record/user_with_validations.rb +12 -0
  192. data/test/rails_app/app/active_record/user_without_email.rb +10 -0
  193. data/test/rails_app/app/controllers/admins/sessions_controller.rb +3 -1
  194. data/test/rails_app/app/controllers/admins_controller.rb +3 -6
  195. data/test/rails_app/app/controllers/application_controller.rb +7 -3
  196. data/test/rails_app/app/controllers/application_with_fake_engine.rb +32 -0
  197. data/test/rails_app/app/controllers/custom/registrations_controller.rb +33 -0
  198. data/test/rails_app/app/controllers/home_controller.rb +7 -1
  199. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +3 -1
  200. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +3 -1
  201. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +7 -5
  202. data/test/rails_app/app/controllers/users_controller.rb +8 -6
  203. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  204. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +5 -0
  205. data/test/rails_app/app/mailers/users/mailer.rb +3 -10
  206. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +6 -0
  207. data/test/rails_app/app/mongoid/admin.rb +13 -11
  208. data/test/rails_app/app/mongoid/shim.rb +4 -2
  209. data/test/rails_app/app/mongoid/user.rb +30 -19
  210. data/test/rails_app/app/mongoid/user_on_engine.rb +41 -0
  211. data/test/rails_app/app/mongoid/user_on_main_app.rb +41 -0
  212. data/test/rails_app/app/mongoid/user_with_validations.rb +37 -0
  213. data/test/rails_app/app/mongoid/user_without_email.rb +35 -0
  214. data/test/rails_app/app/views/admins/sessions/new.html.erb +1 -1
  215. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -1
  216. data/test/rails_app/app/views/home/index.html.erb +1 -1
  217. data/test/rails_app/app/views/home/join.html.erb +1 -1
  218. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -1
  219. data/test/rails_app/app/views/layouts/application.html.erb +1 -1
  220. data/test/rails_app/config/application.rb +13 -5
  221. data/test/rails_app/config/boot.rb +17 -4
  222. data/test/rails_app/config/environment.rb +2 -0
  223. data/test/rails_app/config/environments/development.rb +2 -0
  224. data/test/rails_app/config/environments/production.rb +10 -2
  225. data/test/rails_app/config/environments/test.rb +14 -3
  226. data/test/rails_app/config/initializers/backtrace_silencers.rb +2 -0
  227. data/test/rails_app/config/initializers/devise.rb +22 -21
  228. data/test/rails_app/config/initializers/inflections.rb +2 -0
  229. data/test/rails_app/config/initializers/secret_token.rb +3 -6
  230. data/test/rails_app/config/initializers/session_store.rb +2 -0
  231. data/test/rails_app/config/routes.rb +67 -43
  232. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +16 -10
  233. data/test/rails_app/db/schema.rb +2 -0
  234. data/test/rails_app/lib/shared_admin.rb +10 -4
  235. data/test/rails_app/lib/shared_user.rb +4 -1
  236. data/test/rails_app/lib/shared_user_without_email.rb +28 -0
  237. data/test/rails_app/lib/shared_user_without_omniauth.rb +15 -0
  238. data/test/rails_test.rb +11 -0
  239. data/test/routes_test.rb +92 -61
  240. data/test/secret_key_finder_test.rb +97 -0
  241. data/test/support/action_controller/record_identifier.rb +12 -0
  242. data/test/support/assertions.rb +4 -14
  243. data/test/support/helpers.rb +23 -10
  244. data/test/support/http_method_compatibility.rb +53 -0
  245. data/test/support/integration.rb +19 -16
  246. data/test/support/mongoid.yml +6 -0
  247. data/test/support/webrat/integrations/rails.rb +11 -0
  248. data/test/{test_helpers_test.rb → test/controller_helpers_test.rb} +60 -40
  249. data/test/test/integration_helpers_test.rb +34 -0
  250. data/test/test_helper.rb +9 -0
  251. data/test/test_models.rb +8 -6
  252. metadata +123 -53
  253. data/gemfiles/Gemfile.rails-3.2.x +0 -31
  254. data/gemfiles/Gemfile.rails-3.2.x.lock +0 -159
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'ostruct'
3
5
 
@@ -8,9 +10,37 @@ class FailureTest < ActiveSupport::TestCase
8
10
  end
9
11
  end
10
12
 
13
+ class FailureWithSubdomain < RootFailureApp
14
+ routes = ActionDispatch::Routing::RouteSet.new
15
+
16
+ routes.draw do
17
+ scope subdomain: 'sub' do
18
+ root to: 'foo#bar'
19
+ end
20
+ end
21
+
22
+ include routes.url_helpers
23
+ end
24
+
11
25
  class FailureWithI18nOptions < Devise::FailureApp
12
26
  def i18n_options(options)
13
- options.merge(:name => 'Steve')
27
+ options.merge(name: 'Steve')
28
+ end
29
+ end
30
+
31
+ class FakeEngineApp < Devise::FailureApp
32
+ class FakeEngine
33
+ def new_user_on_engine_session_url _
34
+ '/user_on_engines/sign_in'
35
+ end
36
+ end
37
+
38
+ def main_app
39
+ raise 'main_app router called instead of fake_engine'
40
+ end
41
+
42
+ def fake_engine
43
+ @fake_engine ||= FakeEngine.new
14
44
  end
15
45
  end
16
46
 
@@ -23,13 +53,18 @@ class FailureTest < ActiveSupport::TestCase
23
53
  'REQUEST_URI' => 'http://test.host/',
24
54
  'HTTP_HOST' => 'test.host',
25
55
  'REQUEST_METHOD' => 'GET',
26
- 'warden.options' => { :scope => :user },
56
+ 'warden.options' => { scope: :user },
27
57
  'rack.session' => {},
28
- 'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
58
+ 'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime[:html]),
29
59
  'rack.input' => "",
30
- 'warden' => OpenStruct.new(:message => nil)
60
+ 'warden' => OpenStruct.new(message: nil)
31
61
  }.merge!(env_params)
32
62
 
63
+ # Passing nil for action_dispatch.request.formats prevents the default from being used in Rails 5, need to remove it
64
+ if env.has_key?('action_dispatch.request.formats') && env['action_dispatch.request.formats'].nil?
65
+ env.delete 'action_dispatch.request.formats' unless env['action_dispatch.request.formats']
66
+ end
67
+
33
68
  @response = (env.delete(:app) || Devise::FailureApp).call(env).to_a
34
69
  @request = ActionDispatch::Request.new(env)
35
70
  end
@@ -42,6 +77,13 @@ class FailureTest < ActiveSupport::TestCase
42
77
  assert_equal 'http://test.host/users/sign_in', @response.second['Location']
43
78
  end
44
79
 
80
+ test 'returns to the default redirect location considering subdomain' do
81
+ call_failure('warden.options' => { scope: :subdomain_user })
82
+ assert_equal 302, @response.first
83
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
84
+ assert_equal 'http://sub.test.host/subdomain_users/sign_in', @response.second['Location']
85
+ end
86
+
45
87
  test 'returns to the default redirect location for wildcard requests' do
46
88
  call_failure 'action_dispatch.request.formats' => nil, 'HTTP_ACCEPT' => '*/*'
47
89
  assert_equal 302, @response.first
@@ -49,37 +91,86 @@ class FailureTest < ActiveSupport::TestCase
49
91
  end
50
92
 
51
93
  test 'returns to the root path if no session path is available' do
52
- swap Devise, :router_name => :fake_app do
53
- call_failure :app => RootFailureApp
94
+ swap Devise, router_name: :fake_app do
95
+ call_failure app: RootFailureApp
54
96
  assert_equal 302, @response.first
55
97
  assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
56
98
  assert_equal 'http://test.host/', @response.second['Location']
57
99
  end
58
100
  end
59
101
 
102
+ test 'returns to the root path considering subdomain if no session path is available' do
103
+ swap Devise, router_name: :fake_app do
104
+ call_failure app: FailureWithSubdomain
105
+ assert_equal 302, @response.first
106
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
107
+ assert_equal 'http://sub.test.host/', @response.second['Location']
108
+ end
109
+ end
110
+
111
+ test 'returns to the default redirect location considering the router for supplied scope' do
112
+ call_failure app: FakeEngineApp, 'warden.options' => { scope: :user_on_engine }
113
+ assert_equal 302, @response.first
114
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
115
+ assert_equal 'http://test.host/user_on_engines/sign_in', @response.second['Location']
116
+ end
117
+
60
118
  if Rails.application.config.respond_to?(:relative_url_root)
61
119
  test 'returns to the default redirect location considering the relative url root' do
62
- swap Rails.application.config, :relative_url_root => "/sample" do
120
+ swap Rails.application.config, relative_url_root: "/sample" do
121
+ call_failure
122
+ assert_equal 302, @response.first
123
+ assert_equal 'http://test.host/sample/users/sign_in', @response.second['Location']
124
+ end
125
+ end
126
+
127
+ test 'returns to the default redirect location considering the relative url root and subdomain' do
128
+ swap Rails.application.config, relative_url_root: "/sample" do
129
+ call_failure('warden.options' => { scope: :subdomain_user })
130
+ assert_equal 302, @response.first
131
+ assert_equal 'http://sub.test.host/sample/subdomain_users/sign_in', @response.second['Location']
132
+ end
133
+ end
134
+ end
135
+
136
+ if Rails.application.config.action_controller.respond_to?(:relative_url_root)
137
+ test "returns to the default redirect location considering action_controller's relative url root" do
138
+ swap Rails.application.config.action_controller, relative_url_root: "/sample" do
63
139
  call_failure
64
140
  assert_equal 302, @response.first
65
141
  assert_equal 'http://test.host/sample/users/sign_in', @response.second['Location']
66
142
  end
67
143
  end
144
+
145
+ test "returns to the default redirect location considering action_controller's relative url root and subdomain" do
146
+ swap Rails.application.config.action_controller, relative_url_root: "/sample" do
147
+ call_failure('warden.options' => { scope: :subdomain_user })
148
+ assert_equal 302, @response.first
149
+ assert_equal 'http://sub.test.host/sample/subdomain_users/sign_in', @response.second['Location']
150
+ end
151
+ end
68
152
  end
69
153
 
70
154
  test 'uses the proxy failure message as symbol' do
71
- call_failure('warden' => OpenStruct.new(:message => :invalid))
72
- assert_equal 'Invalid email or password.', @request.flash[:alert]
155
+ call_failure('warden' => OpenStruct.new(message: :invalid))
156
+ assert_equal 'Invalid Email or password.', @request.flash[:alert]
73
157
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
74
158
  end
75
159
 
160
+ test 'supports authentication_keys as a Hash for the flash message' do
161
+ swap Devise, authentication_keys: { email: true, login: true } do
162
+ call_failure('warden' => OpenStruct.new(message: :invalid))
163
+ assert_equal 'Invalid Email, Login or password.', @request.flash[:alert]
164
+ end
165
+ end
166
+
76
167
  test 'uses custom i18n options' do
77
- call_failure('warden' => OpenStruct.new(:message => :does_not_exist), :app => FailureWithI18nOptions)
168
+ call_failure('warden' => OpenStruct.new(message: :does_not_exist), app: FailureWithI18nOptions)
78
169
  assert_equal 'User Steve does not exist', @request.flash[:alert]
79
170
  end
80
171
 
81
172
  test 'uses the proxy failure message as string' do
82
- call_failure('warden' => OpenStruct.new(:message => 'Hello world'))
173
+ call_failure('warden' => OpenStruct.new(message: 'Hello world'))
83
174
  assert_equal 'Hello world', @request.flash[:alert]
84
175
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
85
176
  end
@@ -89,7 +180,7 @@ class FailureTest < ActiveSupport::TestCase
89
180
  assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
90
181
  end
91
182
 
92
- test 'setup a default message' do
183
+ test 'set up a default message' do
93
184
  call_failure
94
185
  assert_match(/You are being/, @response.last.body)
95
186
  assert_match(/redirected/, @response.last.body)
@@ -97,15 +188,15 @@ class FailureTest < ActiveSupport::TestCase
97
188
  end
98
189
 
99
190
  test 'works for any navigational format' do
100
- swap Devise, :navigational_formats => [:xml] do
101
- call_failure('formats' => Mime::XML)
191
+ swap Devise, navigational_formats: [:xml] do
192
+ call_failure('formats' => Mime[:xml])
102
193
  assert_equal 302, @response.first
103
194
  end
104
195
  end
105
196
 
106
197
  test 'redirects the correct format if it is a non-html format request' do
107
- swap Devise, :navigational_formats => [:js] do
108
- call_failure('formats' => Mime::JS)
198
+ swap Devise, navigational_formats: [:js] do
199
+ call_failure('formats' => Mime[:js])
109
200
  assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
110
201
  end
111
202
  end
@@ -113,18 +204,18 @@ class FailureTest < ActiveSupport::TestCase
113
204
 
114
205
  context 'For HTTP request' do
115
206
  test 'return 401 status' do
116
- call_failure('formats' => Mime::XML)
207
+ call_failure('formats' => Mime[:xml])
117
208
  assert_equal 401, @response.first
118
209
  end
119
210
 
120
211
  test 'return appropriate body for xml' do
121
- call_failure('formats' => Mime::XML)
212
+ call_failure('formats' => Mime[:xml])
122
213
  result = %(<?xml version="1.0" encoding="UTF-8"?>\n<errors>\n <error>You need to sign in or sign up before continuing.</error>\n</errors>\n)
123
214
  assert_equal result, @response.last.body
124
215
  end
125
216
 
126
217
  test 'return appropriate body for json' do
127
- call_failure('formats' => Mime::JSON)
218
+ call_failure('formats' => Mime[:json])
128
219
  result = %({"error":"You need to sign in or sign up before continuing."})
129
220
  assert_equal result, @response.last.body
130
221
  end
@@ -135,42 +226,42 @@ class FailureTest < ActiveSupport::TestCase
135
226
  end
136
227
 
137
228
  test 'return WWW-authenticate headers if model allows' do
138
- call_failure('formats' => Mime::XML)
229
+ call_failure('formats' => Mime[:xml])
139
230
  assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
140
231
  end
141
232
 
142
233
  test 'does not return WWW-authenticate headers if model does not allow' do
143
- swap Devise, :http_authenticatable => false do
144
- call_failure('formats' => Mime::XML)
234
+ swap Devise, http_authenticatable: false do
235
+ call_failure('formats' => Mime[:xml])
145
236
  assert_nil @response.second["WWW-Authenticate"]
146
237
  end
147
238
  end
148
239
 
149
240
  test 'works for any non navigational format' do
150
- swap Devise, :navigational_formats => [] do
151
- call_failure('formats' => Mime::HTML)
241
+ swap Devise, navigational_formats: [] do
242
+ call_failure('formats' => Mime[:html])
152
243
  assert_equal 401, @response.first
153
244
  end
154
245
  end
155
246
 
156
247
  test 'uses the failure message as response body' do
157
- call_failure('formats' => Mime::XML, 'warden' => OpenStruct.new(:message => :invalid))
158
- assert_match '<error>Invalid email or password.</error>', @response.third.body
248
+ call_failure('formats' => Mime[:xml], 'warden' => OpenStruct.new(message: :invalid))
249
+ assert_match '<error>Invalid Email or password.</error>', @response.third.body
159
250
  end
160
251
 
161
252
  context 'on ajax call' do
162
253
  context 'when http_authenticatable_on_xhr is false' do
163
254
  test 'dont return 401 with navigational formats' do
164
- swap Devise, :http_authenticatable_on_xhr => false do
165
- call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
255
+ swap Devise, http_authenticatable_on_xhr: false do
256
+ call_failure('formats' => Mime[:html], 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
166
257
  assert_equal 302, @response.first
167
258
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
168
259
  end
169
260
  end
170
261
 
171
262
  test 'dont return 401 with non navigational formats' do
172
- swap Devise, :http_authenticatable_on_xhr => false do
173
- call_failure('formats' => Mime::JSON, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
263
+ swap Devise, http_authenticatable_on_xhr: false do
264
+ call_failure('formats' => Mime[:json], 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
174
265
  assert_equal 302, @response.first
175
266
  assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
176
267
  end
@@ -179,15 +270,15 @@ class FailureTest < ActiveSupport::TestCase
179
270
 
180
271
  context 'when http_authenticatable_on_xhr is true' do
181
272
  test 'return 401' do
182
- swap Devise, :http_authenticatable_on_xhr => true do
183
- call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
273
+ swap Devise, http_authenticatable_on_xhr: true do
274
+ call_failure('formats' => Mime[:html], 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
184
275
  assert_equal 401, @response.first
185
276
  end
186
277
  end
187
278
 
188
279
  test 'skip WWW-Authenticate header' do
189
- swap Devise, :http_authenticatable_on_xhr => true do
190
- call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
280
+ swap Devise, http_authenticatable_on_xhr: true do
281
+ call_failure('formats' => Mime[:html], 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
191
282
  assert_nil @response.second['WWW-Authenticate']
192
283
  end
193
284
  end
@@ -198,35 +289,52 @@ class FailureTest < ActiveSupport::TestCase
198
289
  context 'With recall' do
199
290
  test 'calls the original controller if invalid email or password' do
200
291
  env = {
201
- "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in" },
292
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in" },
202
293
  "devise.mapping" => Devise.mappings[:user],
203
294
  "warden" => stub_everything
204
295
  }
205
296
  call_failure(env)
206
- assert @response.third.body.include?('<h2>Sign in</h2>')
207
- assert @response.third.body.include?('Invalid email or password.')
297
+ assert @response.third.body.include?('<h2>Log in</h2>')
298
+ assert @response.third.body.include?('Invalid Email or password.')
208
299
  end
209
300
 
210
301
  test 'calls the original controller if not confirmed email' do
211
302
  env = {
212
- "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in", :message => :unconfirmed },
303
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :unconfirmed },
213
304
  "devise.mapping" => Devise.mappings[:user],
214
305
  "warden" => stub_everything
215
306
  }
216
307
  call_failure(env)
217
- assert @response.third.body.include?('<h2>Sign in</h2>')
218
- assert @response.third.body.include?('You have to confirm your account before continuing.')
308
+ assert @response.third.body.include?('<h2>Log in</h2>')
309
+ assert @response.third.body.include?('You have to confirm your email address before continuing.')
219
310
  end
220
311
 
221
312
  test 'calls the original controller if inactive account' do
222
313
  env = {
223
- "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in", :message => :inactive },
314
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :inactive },
224
315
  "devise.mapping" => Devise.mappings[:user],
225
316
  "warden" => stub_everything
226
317
  }
227
318
  call_failure(env)
228
- assert @response.third.body.include?('<h2>Sign in</h2>')
319
+ assert @response.third.body.include?('<h2>Log in</h2>')
229
320
  assert @response.third.body.include?('Your account is not activated yet.')
230
321
  end
322
+
323
+ if Rails.application.config.respond_to?(:relative_url_root)
324
+ test 'calls the original controller with the proper environment considering the relative url root' do
325
+ swap Rails.application.config, relative_url_root: "/sample" do
326
+ env = {
327
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/sample/users/sign_in"},
328
+ "devise.mapping" => Devise.mappings[:user],
329
+ "warden" => stub_everything
330
+ }
331
+ call_failure(env)
332
+ assert @response.third.body.include?('<h2>Log in</h2>')
333
+ assert @response.third.body.include?('Invalid Email or password.')
334
+ assert_equal @request.env["SCRIPT_NAME"], '/sample'
335
+ assert_equal @request.env["PATH_INFO"], '/users/sign_in'
336
+ end
337
+ end
338
+ end
231
339
  end
232
340
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "test_helper"
2
4
 
3
5
  if DEVISE_ORM == :active_record
@@ -13,6 +15,20 @@ if DEVISE_ORM == :active_record
13
15
  assert_migration "db/migrate/devise_create_monsters.rb", /def change/
14
16
  end
15
17
 
18
+ test "all files are properly created with changed db/migrate path in application configuration" do
19
+ old_paths = Rails.application.config.paths["db/migrate"]
20
+ Rails.application.config.paths.add "db/migrate", with: "db2/migrate"
21
+
22
+ run_generator %w(monster)
23
+ if Rails.version >= '5.0.3'
24
+ assert_migration "db2/migrate/devise_create_monsters.rb", /def change/
25
+ else
26
+ assert_migration "db/migrate/devise_create_monsters.rb", /def change/
27
+ end
28
+
29
+ Rails.application.config.paths["db/migrate"] = old_paths
30
+ end
31
+
16
32
  test "all files for namespaced model are properly created" do
17
33
  run_generator %w(admin/monster)
18
34
  assert_migration "db/migrate/devise_create_admin_monsters.rb", /def change/
@@ -25,18 +41,55 @@ if DEVISE_ORM == :active_record
25
41
  assert_migration "db/migrate/add_devise_to_monsters.rb"
26
42
  end
27
43
 
44
+ test "update model migration when model exists with changed db/migrate path in application configuration" do
45
+ old_paths = Rails.application.config.paths["db/migrate"]
46
+ Rails.application.config.paths.add "db/migrate", with: "db2/migrate"
47
+
48
+ run_generator %w(monster)
49
+ assert_file "app/models/monster.rb"
50
+ run_generator %w(monster)
51
+
52
+ if Rails.version >= '5.0.3'
53
+ assert_migration "db2/migrate/add_devise_to_monsters.rb"
54
+ else
55
+ assert_migration "db/migrate/add_devise_to_monsters.rb"
56
+ end
57
+
58
+ Rails.application.config.paths["db/migrate"] = old_paths
59
+ end
60
+
28
61
  test "all files are properly deleted" do
29
62
  run_generator %w(monster)
30
63
  run_generator %w(monster)
31
64
  assert_migration "db/migrate/devise_create_monsters.rb"
32
65
  assert_migration "db/migrate/add_devise_to_monsters.rb"
33
- run_generator %w(monster), :behavior => :revoke
66
+ run_generator %w(monster), behavior: :revoke
34
67
  assert_no_migration "db/migrate/add_devise_to_monsters.rb"
35
68
  assert_migration "db/migrate/devise_create_monsters.rb"
36
- run_generator %w(monster), :behavior => :revoke
69
+ run_generator %w(monster), behavior: :revoke
37
70
  assert_no_file "app/models/monster.rb"
38
71
  assert_no_migration "db/migrate/devise_create_monsters.rb"
39
72
  end
73
+
74
+ test "use string column type for ip addresses" do
75
+ run_generator %w(monster)
76
+ assert_migration "db/migrate/devise_create_monsters.rb", /t.string :current_sign_in_ip/
77
+ assert_migration "db/migrate/devise_create_monsters.rb", /t.string :last_sign_in_ip/
78
+ end
79
+
80
+ test "do NOT add primary key type when NOT specified in rails generator" do
81
+ run_generator %w(monster)
82
+ assert_migration "db/migrate/devise_create_monsters.rb", /create_table :monsters do/
83
+ end
84
+
85
+ test "add primary key type with rails 5 when specified in rails generator" do
86
+ run_generator ["monster", "--primary_key_type=uuid"]
87
+ if Rails.version.start_with? '5'
88
+ assert_migration "db/migrate/devise_create_monsters.rb", /create_table :monsters, id: :uuid do/
89
+ else
90
+ assert_migration "db/migrate/devise_create_monsters.rb", /create_table :monsters do/
91
+ end
92
+ end
40
93
  end
41
94
 
42
95
  module RailsEngine
@@ -47,11 +100,11 @@ if DEVISE_ORM == :active_record
47
100
 
48
101
  def simulate_inside_engine(engine, namespace)
49
102
  if Rails::Generators.respond_to?(:namespace=)
50
- swap Rails::Generators, :namespace => namespace do
103
+ swap Rails::Generators, namespace: namespace do
51
104
  yield
52
105
  end
53
106
  else
54
- swap Rails, :application => engine.instance do
107
+ swap Rails, application: engine.instance do
55
108
  yield
56
109
  end
57
110
  end
@@ -63,41 +116,15 @@ if DEVISE_ORM == :active_record
63
116
  setup :prepare_destination
64
117
 
65
118
  test "all files are properly created in rails 4.0" do
66
- ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(false)
67
119
  simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
68
120
  run_generator ["monster"]
69
121
 
70
122
  assert_file "app/models/rails_engine/monster.rb", /devise/
71
123
  assert_file "app/models/rails_engine/monster.rb" do |content|
72
- assert_no_match /attr_accessible :email/, content
124
+ assert_no_match %r{attr_accessible :email}, content
73
125
  end
74
126
  end
75
127
  end
76
128
 
77
- test "all files are properly created in rails 3.2 when strong_parameters gem is not installed" do
78
- ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
79
- ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(false)
80
- simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
81
- run_generator ["monster"]
82
-
83
- assert_file "app/models/rails_engine/monster.rb", /devise/
84
- assert_file "app/models/rails_engine/monster.rb" do |content|
85
- assert_match /attr_accessible :email/, content
86
- end
87
- end
88
- end
89
-
90
- test "all files are properly created in rails 3.2 when strong_parameters gem is installed" do
91
- ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
92
- ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(true)
93
- simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
94
- run_generator ["monster"]
95
-
96
- assert_file "app/models/rails_engine/monster.rb", /devise/
97
- assert_file "app/models/rails_engine/monster.rb" do |content|
98
- assert_no_match /attr_accessible :email/, content
99
- end
100
- end
101
- end
102
129
  end
103
130
  end