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
@@ -8,6 +8,40 @@ class FailureTest < ActiveSupport::TestCase
8
8
  end
9
9
  end
10
10
 
11
+ class FailureWithSubdomain < RootFailureApp
12
+ routes = ActionDispatch::Routing::RouteSet.new
13
+
14
+ routes.draw do
15
+ scope subdomain: 'sub' do
16
+ root to: 'foo#bar'
17
+ end
18
+ end
19
+
20
+ include routes.url_helpers
21
+ end
22
+
23
+ class FailureWithI18nOptions < Devise::FailureApp
24
+ def i18n_options(options)
25
+ options.merge(name: 'Steve')
26
+ end
27
+ end
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
+
11
45
  def self.context(name, &block)
12
46
  instance_eval(&block)
13
47
  end
@@ -17,11 +51,11 @@ class FailureTest < ActiveSupport::TestCase
17
51
  'REQUEST_URI' => 'http://test.host/',
18
52
  'HTTP_HOST' => 'test.host',
19
53
  'REQUEST_METHOD' => 'GET',
20
- 'warden.options' => { :scope => :user },
54
+ 'warden.options' => { scope: :user },
21
55
  'rack.session' => {},
22
56
  'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
23
57
  'rack.input' => "",
24
- 'warden' => OpenStruct.new(:message => nil)
58
+ 'warden' => OpenStruct.new(message: nil)
25
59
  }.merge!(env_params)
26
60
 
27
61
  @response = (env.delete(:app) || Devise::FailureApp).call(env).to_a
@@ -36,6 +70,13 @@ class FailureTest < ActiveSupport::TestCase
36
70
  assert_equal 'http://test.host/users/sign_in', @response.second['Location']
37
71
  end
38
72
 
73
+ test 'returns to the default redirect location considering subdomain' do
74
+ call_failure('warden.options' => { scope: :subdomain_user })
75
+ assert_equal 302, @response.first
76
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
77
+ assert_equal 'http://sub.test.host/subdomain_users/sign_in', @response.second['Location']
78
+ end
79
+
39
80
  test 'returns to the default redirect location for wildcard requests' do
40
81
  call_failure 'action_dispatch.request.formats' => nil, 'HTTP_ACCEPT' => '*/*'
41
82
  assert_equal 302, @response.first
@@ -43,32 +84,68 @@ class FailureTest < ActiveSupport::TestCase
43
84
  end
44
85
 
45
86
  test 'returns to the root path if no session path is available' do
46
- swap Devise, :router_name => :fake_app do
47
- call_failure :app => RootFailureApp
87
+ swap Devise, router_name: :fake_app do
88
+ call_failure app: RootFailureApp
48
89
  assert_equal 302, @response.first
49
90
  assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
50
91
  assert_equal 'http://test.host/', @response.second['Location']
51
92
  end
52
93
  end
53
94
 
95
+ test 'returns to the root path considering subdomain if no session path is available' do
96
+ swap Devise, router_name: :fake_app do
97
+ call_failure app: FailureWithSubdomain
98
+ assert_equal 302, @response.first
99
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
100
+ assert_equal 'http://sub.test.host/', @response.second['Location']
101
+ end
102
+ end
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
+
54
111
  if Rails.application.config.respond_to?(:relative_url_root)
55
112
  test 'returns to the default redirect location considering the relative url root' do
56
- swap Rails.application.config, :relative_url_root => "/sample" do
113
+ swap Rails.application.config, relative_url_root: "/sample" do
57
114
  call_failure
58
115
  assert_equal 302, @response.first
59
116
  assert_equal 'http://test.host/sample/users/sign_in', @response.second['Location']
60
117
  end
61
118
  end
119
+
120
+ test 'returns to the default redirect location considering the relative url root and subdomain' do
121
+ swap Rails.application.config, relative_url_root: "/sample" do
122
+ call_failure('warden.options' => { scope: :subdomain_user })
123
+ assert_equal 302, @response.first
124
+ assert_equal 'http://sub.test.host/sample/subdomain_users/sign_in', @response.second['Location']
125
+ end
126
+ end
62
127
  end
63
128
 
64
129
  test 'uses the proxy failure message as symbol' do
65
- call_failure('warden' => OpenStruct.new(:message => :invalid))
130
+ call_failure('warden' => OpenStruct.new(message: :invalid))
66
131
  assert_equal 'Invalid email or password.', @request.flash[:alert]
67
132
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
68
133
  end
69
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
+
142
+ test 'uses custom i18n options' do
143
+ call_failure('warden' => OpenStruct.new(message: :does_not_exist), app: FailureWithI18nOptions)
144
+ assert_equal 'User Steve does not exist', @request.flash[:alert]
145
+ end
146
+
70
147
  test 'uses the proxy failure message as string' do
71
- call_failure('warden' => OpenStruct.new(:message => 'Hello world'))
148
+ call_failure('warden' => OpenStruct.new(message: 'Hello world'))
72
149
  assert_equal 'Hello world', @request.flash[:alert]
73
150
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
74
151
  end
@@ -80,20 +157,20 @@ class FailureTest < ActiveSupport::TestCase
80
157
 
81
158
  test 'setup a default message' do
82
159
  call_failure
83
- assert_match /You are being/, @response.last.body
84
- assert_match /redirected/, @response.last.body
85
- assert_match /users\/sign_in/, @response.last.body
160
+ assert_match(/You are being/, @response.last.body)
161
+ assert_match(/redirected/, @response.last.body)
162
+ assert_match(/users\/sign_in/, @response.last.body)
86
163
  end
87
164
 
88
165
  test 'works for any navigational format' do
89
- swap Devise, :navigational_formats => [:xml] do
166
+ swap Devise, navigational_formats: [:xml] do
90
167
  call_failure('formats' => Mime::XML)
91
168
  assert_equal 302, @response.first
92
169
  end
93
170
  end
94
171
 
95
172
  test 'redirects the correct format if it is a non-html format request' do
96
- swap Devise, :navigational_formats => [:js] do
173
+ swap Devise, navigational_formats: [:js] do
97
174
  call_failure('formats' => Mime::JS)
98
175
  assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
99
176
  end
@@ -129,28 +206,28 @@ class FailureTest < ActiveSupport::TestCase
129
206
  end
130
207
 
131
208
  test 'does not return WWW-authenticate headers if model does not allow' do
132
- swap Devise, :http_authenticatable => false do
209
+ swap Devise, http_authenticatable: false do
133
210
  call_failure('formats' => Mime::XML)
134
211
  assert_nil @response.second["WWW-Authenticate"]
135
212
  end
136
213
  end
137
214
 
138
215
  test 'works for any non navigational format' do
139
- swap Devise, :navigational_formats => [] do
216
+ swap Devise, navigational_formats: [] do
140
217
  call_failure('formats' => Mime::HTML)
141
218
  assert_equal 401, @response.first
142
219
  end
143
220
  end
144
221
 
145
222
  test 'uses the failure message as response body' do
146
- call_failure('formats' => Mime::XML, 'warden' => OpenStruct.new(:message => :invalid))
223
+ call_failure('formats' => Mime::XML, 'warden' => OpenStruct.new(message: :invalid))
147
224
  assert_match '<error>Invalid email or password.</error>', @response.third.body
148
225
  end
149
226
 
150
227
  context 'on ajax call' do
151
228
  context 'when http_authenticatable_on_xhr is false' do
152
229
  test 'dont return 401 with navigational formats' do
153
- swap Devise, :http_authenticatable_on_xhr => false do
230
+ swap Devise, http_authenticatable_on_xhr: false do
154
231
  call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
155
232
  assert_equal 302, @response.first
156
233
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
@@ -158,7 +235,7 @@ class FailureTest < ActiveSupport::TestCase
158
235
  end
159
236
 
160
237
  test 'dont return 401 with non navigational formats' do
161
- swap Devise, :http_authenticatable_on_xhr => false do
238
+ swap Devise, http_authenticatable_on_xhr: false do
162
239
  call_failure('formats' => Mime::JSON, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
163
240
  assert_equal 302, @response.first
164
241
  assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
@@ -168,14 +245,14 @@ class FailureTest < ActiveSupport::TestCase
168
245
 
169
246
  context 'when http_authenticatable_on_xhr is true' do
170
247
  test 'return 401' do
171
- swap Devise, :http_authenticatable_on_xhr => true do
248
+ swap Devise, http_authenticatable_on_xhr: true do
172
249
  call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
173
250
  assert_equal 401, @response.first
174
251
  end
175
252
  end
176
253
 
177
254
  test 'skip WWW-Authenticate header' do
178
- swap Devise, :http_authenticatable_on_xhr => true do
255
+ swap Devise, http_authenticatable_on_xhr: true do
179
256
  call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
180
257
  assert_nil @response.second['WWW-Authenticate']
181
258
  end
@@ -187,35 +264,52 @@ class FailureTest < ActiveSupport::TestCase
187
264
  context 'With recall' do
188
265
  test 'calls the original controller if invalid email or password' do
189
266
  env = {
190
- "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in" },
267
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in" },
191
268
  "devise.mapping" => Devise.mappings[:user],
192
269
  "warden" => stub_everything
193
270
  }
194
271
  call_failure(env)
195
- assert @response.third.body.include?('<h2>Sign in</h2>')
272
+ assert @response.third.body.include?('<h2>Log in</h2>')
196
273
  assert @response.third.body.include?('Invalid email or password.')
197
274
  end
198
275
 
199
276
  test 'calls the original controller if not confirmed email' do
200
277
  env = {
201
- "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in", :message => :unconfirmed },
278
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :unconfirmed },
202
279
  "devise.mapping" => Devise.mappings[:user],
203
280
  "warden" => stub_everything
204
281
  }
205
282
  call_failure(env)
206
- assert @response.third.body.include?('<h2>Sign in</h2>')
207
- assert @response.third.body.include?('You have to confirm your account before continuing.')
283
+ assert @response.third.body.include?('<h2>Log in</h2>')
284
+ assert @response.third.body.include?('You have to confirm your email address before continuing.')
208
285
  end
209
286
 
210
287
  test 'calls the original controller if inactive account' do
211
288
  env = {
212
- "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in", :message => :inactive },
289
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :inactive },
213
290
  "devise.mapping" => Devise.mappings[:user],
214
291
  "warden" => stub_everything
215
292
  }
216
293
  call_failure(env)
217
- assert @response.third.body.include?('<h2>Sign in</h2>')
218
- assert @response.third.body.include?('Your account was not activated yet.')
294
+ assert @response.third.body.include?('<h2>Log in</h2>')
295
+ assert @response.third.body.include?('Your account is not activated yet.')
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
219
313
  end
220
314
  end
221
315
  end
@@ -10,10 +10,14 @@ if DEVISE_ORM == :active_record
10
10
 
11
11
  test "all files are properly created with rails31 migration syntax" do
12
12
  run_generator %w(monster)
13
- assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
14
13
  assert_migration "db/migrate/devise_create_monsters.rb", /def change/
15
14
  end
16
15
 
16
+ test "all files for namespaced model are properly created" do
17
+ run_generator %w(admin/monster)
18
+ assert_migration "db/migrate/devise_create_admin_monsters.rb", /def change/
19
+ end
20
+
17
21
  test "update model migration when model exists" do
18
22
  run_generator %w(monster)
19
23
  assert_file "app/models/monster.rb"
@@ -26,13 +30,19 @@ if DEVISE_ORM == :active_record
26
30
  run_generator %w(monster)
27
31
  assert_migration "db/migrate/devise_create_monsters.rb"
28
32
  assert_migration "db/migrate/add_devise_to_monsters.rb"
29
- run_generator %w(monster), :behavior => :revoke
33
+ run_generator %w(monster), behavior: :revoke
30
34
  assert_no_migration "db/migrate/add_devise_to_monsters.rb"
31
35
  assert_migration "db/migrate/devise_create_monsters.rb"
32
- run_generator %w(monster), :behavior => :revoke
36
+ run_generator %w(monster), behavior: :revoke
33
37
  assert_no_file "app/models/monster.rb"
34
38
  assert_no_migration "db/migrate/devise_create_monsters.rb"
35
39
  end
40
+
41
+ test "use string column type for ip addresses" do
42
+ run_generator %w(monster)
43
+ assert_migration "db/migrate/devise_create_monsters.rb", /t.string :current_sign_in_ip/
44
+ assert_migration "db/migrate/devise_create_monsters.rb", /t.string :last_sign_in_ip/
45
+ end
36
46
  end
37
47
 
38
48
  module RailsEngine
@@ -43,11 +53,11 @@ if DEVISE_ORM == :active_record
43
53
 
44
54
  def simulate_inside_engine(engine, namespace)
45
55
  if Rails::Generators.respond_to?(:namespace=)
46
- swap Rails::Generators, :namespace => namespace do
56
+ swap Rails::Generators, namespace: namespace do
47
57
  yield
48
58
  end
49
59
  else
50
- swap Rails, :application => engine.instance do
60
+ swap Rails, application: engine.instance do
51
61
  yield
52
62
  end
53
63
  end
@@ -58,12 +68,42 @@ if DEVISE_ORM == :active_record
58
68
  destination File.expand_path("../../tmp", __FILE__)
59
69
  setup :prepare_destination
60
70
 
61
- test "all files are properly created" do
71
+ test "all files are properly created in rails 4.0" do
72
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(false)
73
+ simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
74
+ run_generator ["monster"]
75
+
76
+ assert_file "app/models/rails_engine/monster.rb", /devise/
77
+ assert_file "app/models/rails_engine/monster.rb" do |content|
78
+ assert_no_match /attr_accessible :email/, content
79
+ end
80
+ end
81
+ end
82
+
83
+ test "all files are properly created in rails 3.2 when strong_parameters gem is not installed" do
84
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
85
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(false)
86
+ simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
87
+ run_generator ["monster"]
88
+
89
+ assert_file "app/models/rails_engine/monster.rb", /devise/
90
+ assert_file "app/models/rails_engine/monster.rb" do |content|
91
+ assert_match /attr_accessible :email/, content
92
+ end
93
+ end
94
+ end
95
+
96
+ test "all files are properly created in rails 3.2 when strong_parameters gem is installed" do
97
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
98
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(true)
62
99
  simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
63
100
  run_generator ["monster"]
64
101
 
65
- assert_file "app/models/rails_engine/monster.rb", /devise/,/attr_accessible (:[a-z_]+(, )?)+/
102
+ assert_file "app/models/rails_engine/monster.rb", /devise/
103
+ assert_file "app/models/rails_engine/monster.rb" do |content|
104
+ assert_no_match /attr_accessible :email/, content
105
+ end
66
106
  end
67
107
  end
68
108
  end
69
- end
109
+ 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
@@ -18,13 +18,13 @@ class DeviseGeneratorTest < Rails::Generators::TestCase
18
18
 
19
19
  test "route generation for namespaced model names" do
20
20
  run_generator %w(monster/goblin name:string)
21
- match = /devise_for :goblins, :class_name => "Monster::Goblin"/
21
+ match = /devise_for :goblins, class_name: "Monster::Goblin"/
22
22
  assert_file "config/routes.rb", match
23
23
  end
24
24
 
25
25
  test "route generation with skip routes" do
26
26
  run_generator %w(monster name:string --skip-routes)
27
- match = /devise_for :monsters, :skip => :all/
27
+ match = /devise_for :monsters, skip: :all/
28
28
  assert_file "config/routes.rb", match
29
29
  end
30
30
 
@@ -7,15 +7,15 @@ if DEVISE_ORM == :mongoid
7
7
  tests Mongoid::Generators::DeviseGenerator
8
8
  destination File.expand_path("../../tmp", __FILE__)
9
9
  setup :prepare_destination
10
-
10
+
11
11
  test "all files are properly created" do
12
12
  run_generator %w(monster)
13
13
  assert_file "app/models/monster.rb", /devise/
14
14
  end
15
-
15
+
16
16
  test "all files are properly deleted" do
17
17
  run_generator %w(monster)
18
- run_generator %w(monster), :behavior => :revoke
18
+ run_generator %w(monster), behavior: :revoke
19
19
  assert_no_file "app/models/monster.rb"
20
20
  end
21
21
  end