deviseOne 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +38 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG.md +1117 -0
  6. data/CONTRIBUTING.md +14 -0
  7. data/Gemfile +29 -0
  8. data/Gemfile.lock +199 -0
  9. data/MIT-LICENSE +20 -0
  10. data/README.md +529 -0
  11. data/Rakefile +35 -0
  12. data/app/controllers/devise/confirmations_controller.rb +47 -0
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +30 -0
  14. data/app/controllers/devise/passwords_controller.rb +71 -0
  15. data/app/controllers/devise/registrations_controller.rb +143 -0
  16. data/app/controllers/devise/sessions_controller.rb +166 -0
  17. data/app/controllers/devise/unlocks_controller.rb +46 -0
  18. data/app/controllers/devise_controller.rb +193 -0
  19. data/app/helpers/devise_helper.rb +25 -0
  20. data/app/mailers/devise/mailer.rb +20 -0
  21. data/app/views/devise/confirmations/new.html.erb +16 -0
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  23. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  24. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  25. data/app/views/devise/passwords/edit.html.erb +25 -0
  26. data/app/views/devise/passwords/new.html.erb +16 -0
  27. data/app/views/devise/registrations/edit.html.erb +39 -0
  28. data/app/views/devise/registrations/new.html.erb +29 -0
  29. data/app/views/devise/sessions/new.html.erb +27 -0
  30. data/app/views/devise/shared/_links.html.erb +21 -0
  31. data/app/views/devise/unlocks/new.html.erb +16 -0
  32. data/config/locales/en.yml +70 -0
  33. data/devise.gemspec +33 -0
  34. data/devise.png +0 -0
  35. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  36. data/gemfiles/Gemfile.rails-3.2-stable.lock +169 -0
  37. data/gemfiles/Gemfile.rails-4.0-stable +29 -0
  38. data/gemfiles/Gemfile.rails-4.0-stable.lock +165 -0
  39. data/gemfiles/Gemfile.rails-4.1-stable +29 -0
  40. data/gemfiles/Gemfile.rails-4.1-stable.lock +170 -0
  41. data/lib/devise.rb +499 -0
  42. data/lib/devise/controllers/helpers.rb +284 -0
  43. data/lib/devise/controllers/rememberable.rb +47 -0
  44. data/lib/devise/controllers/scoped_views.rb +17 -0
  45. data/lib/devise/controllers/sign_in_out.rb +102 -0
  46. data/lib/devise/controllers/store_location.rb +58 -0
  47. data/lib/devise/controllers/url_helpers.rb +69 -0
  48. data/lib/devise/delegator.rb +16 -0
  49. data/lib/devise/failure_app.rb +212 -0
  50. data/lib/devise/hooks/activatable.rb +10 -0
  51. data/lib/devise/hooks/csrf_cleaner.rb +7 -0
  52. data/lib/devise/hooks/forgetable.rb +9 -0
  53. data/lib/devise/hooks/lockable.rb +7 -0
  54. data/lib/devise/hooks/proxy.rb +21 -0
  55. data/lib/devise/hooks/rememberable.rb +7 -0
  56. data/lib/devise/hooks/timeoutable.rb +35 -0
  57. data/lib/devise/hooks/trackable.rb +9 -0
  58. data/lib/devise/mailers/helpers.rb +90 -0
  59. data/lib/devise/mapping.rb +175 -0
  60. data/lib/devise/models.rb +119 -0
  61. data/lib/devise/models/authenticatable.rb +290 -0
  62. data/lib/devise/models/confirmable.rb +305 -0
  63. data/lib/devise/models/database_authenticatable.rb +164 -0
  64. data/lib/devise/models/lockable.rb +196 -0
  65. data/lib/devise/models/omniauthable.rb +27 -0
  66. data/lib/devise/models/recoverable.rb +157 -0
  67. data/lib/devise/models/registerable.rb +25 -0
  68. data/lib/devise/models/rememberable.rb +142 -0
  69. data/lib/devise/models/timeoutable.rb +49 -0
  70. data/lib/devise/models/trackable.rb +38 -0
  71. data/lib/devise/models/validatable.rb +66 -0
  72. data/lib/devise/modules.rb +28 -0
  73. data/lib/devise/omniauth.rb +28 -0
  74. data/lib/devise/omniauth/config.rb +45 -0
  75. data/lib/devise/omniauth/url_helpers.rb +18 -0
  76. data/lib/devise/orm/active_record.rb +3 -0
  77. data/lib/devise/orm/mongoid.rb +3 -0
  78. data/lib/devise/parameter_filter.rb +40 -0
  79. data/lib/devise/parameter_sanitizer.rb +99 -0
  80. data/lib/devise/rails.rb +56 -0
  81. data/lib/devise/rails/routes.rb +495 -0
  82. data/lib/devise/rails/warden_compat.rb +22 -0
  83. data/lib/devise/strategies/authenticatable.rb +173 -0
  84. data/lib/devise/strategies/base.rb +20 -0
  85. data/lib/devise/strategies/database_authenticatable.rb +24 -0
  86. data/lib/devise/strategies/rememberable.rb +59 -0
  87. data/lib/devise/test_helpers.rb +132 -0
  88. data/lib/devise/time_inflector.rb +14 -0
  89. data/lib/devise/token_generator.rb +70 -0
  90. data/lib/devise/version.rb +3 -0
  91. data/lib/generators/active_record/devise_generator.rb +91 -0
  92. data/lib/generators/active_record/templates/migration.rb +18 -0
  93. data/lib/generators/active_record/templates/migration_existing.rb +25 -0
  94. data/lib/generators/devise/controllers_generator.rb +44 -0
  95. data/lib/generators/devise/devise_generator.rb +26 -0
  96. data/lib/generators/devise/install_generator.rb +29 -0
  97. data/lib/generators/devise/orm_helpers.rb +51 -0
  98. data/lib/generators/devise/views_generator.rb +135 -0
  99. data/lib/generators/mongoid/devise_generator.rb +55 -0
  100. data/lib/generators/templates/README +35 -0
  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 +263 -0
  109. data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
  110. data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
  111. data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
  112. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +16 -0
  113. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
  114. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
  115. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +27 -0
  116. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
  117. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
  118. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +16 -0
  119. data/script/cached-bundle +49 -0
  120. data/script/s3-put +71 -0
  121. data/test/controllers/custom_registrations_controller_test.rb +35 -0
  122. data/test/controllers/custom_strategy_test.rb +62 -0
  123. data/test/controllers/helpers_test.rb +316 -0
  124. data/test/controllers/internal_helpers_test.rb +129 -0
  125. data/test/controllers/load_hooks_controller_test.rb +19 -0
  126. data/test/controllers/passwords_controller_test.rb +31 -0
  127. data/test/controllers/sessions_controller_test.rb +102 -0
  128. data/test/controllers/url_helpers_test.rb +65 -0
  129. data/test/delegator_test.rb +19 -0
  130. data/test/devise_test.rb +107 -0
  131. data/test/failure_app_test.rb +275 -0
  132. data/test/generators/active_record_generator_test.rb +109 -0
  133. data/test/generators/controllers_generator_test.rb +48 -0
  134. data/test/generators/devise_generator_test.rb +39 -0
  135. data/test/generators/install_generator_test.rb +13 -0
  136. data/test/generators/mongoid_generator_test.rb +23 -0
  137. data/test/generators/views_generator_test.rb +96 -0
  138. data/test/helpers/devise_helper_test.rb +49 -0
  139. data/test/integration/authenticatable_test.rb +731 -0
  140. data/test/integration/confirmable_test.rb +324 -0
  141. data/test/integration/database_authenticatable_test.rb +94 -0
  142. data/test/integration/http_authenticatable_test.rb +105 -0
  143. data/test/integration/lockable_test.rb +239 -0
  144. data/test/integration/omniauthable_test.rb +133 -0
  145. data/test/integration/recoverable_test.rb +334 -0
  146. data/test/integration/registerable_test.rb +361 -0
  147. data/test/integration/rememberable_test.rb +176 -0
  148. data/test/integration/timeoutable_test.rb +189 -0
  149. data/test/integration/trackable_test.rb +92 -0
  150. data/test/mailers/confirmation_instructions_test.rb +115 -0
  151. data/test/mailers/reset_password_instructions_test.rb +96 -0
  152. data/test/mailers/unlock_instructions_test.rb +91 -0
  153. data/test/mapping_test.rb +128 -0
  154. data/test/models/authenticatable_test.rb +23 -0
  155. data/test/models/confirmable_test.rb +461 -0
  156. data/test/models/database_authenticatable_test.rb +249 -0
  157. data/test/models/lockable_test.rb +328 -0
  158. data/test/models/omniauthable_test.rb +7 -0
  159. data/test/models/recoverable_test.rb +205 -0
  160. data/test/models/registerable_test.rb +7 -0
  161. data/test/models/rememberable_test.rb +198 -0
  162. data/test/models/serializable_test.rb +49 -0
  163. data/test/models/timeoutable_test.rb +51 -0
  164. data/test/models/trackable_test.rb +41 -0
  165. data/test/models/validatable_test.rb +127 -0
  166. data/test/models_test.rb +144 -0
  167. data/test/omniauth/config_test.rb +57 -0
  168. data/test/omniauth/url_helpers_test.rb +54 -0
  169. data/test/orm/active_record.rb +10 -0
  170. data/test/orm/mongoid.rb +13 -0
  171. data/test/parameter_sanitizer_test.rb +81 -0
  172. data/test/rails_app/Rakefile +6 -0
  173. data/test/rails_app/app/active_record/admin.rb +6 -0
  174. data/test/rails_app/app/active_record/shim.rb +2 -0
  175. data/test/rails_app/app/active_record/user.rb +6 -0
  176. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  177. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  178. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  179. data/test/rails_app/app/controllers/admins_controller.rb +11 -0
  180. data/test/rails_app/app/controllers/application_controller.rb +12 -0
  181. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  182. data/test/rails_app/app/controllers/custom/registrations_controller.rb +21 -0
  183. data/test/rails_app/app/controllers/home_controller.rb +25 -0
  184. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  185. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  186. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
  187. data/test/rails_app/app/controllers/users_controller.rb +31 -0
  188. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  189. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  190. data/test/rails_app/app/mailers/users/mailer.rb +3 -0
  191. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  192. data/test/rails_app/app/mongoid/admin.rb +29 -0
  193. data/test/rails_app/app/mongoid/shim.rb +23 -0
  194. data/test/rails_app/app/mongoid/user.rb +39 -0
  195. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  196. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  197. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  198. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  199. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  200. data/test/rails_app/app/views/home/index.html.erb +1 -0
  201. data/test/rails_app/app/views/home/join.html.erb +1 -0
  202. data/test/rails_app/app/views/home/private.html.erb +1 -0
  203. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  204. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  205. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  206. data/test/rails_app/app/views/users/index.html.erb +1 -0
  207. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  208. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  209. data/test/rails_app/bin/bundle +3 -0
  210. data/test/rails_app/bin/rails +4 -0
  211. data/test/rails_app/bin/rake +4 -0
  212. data/test/rails_app/config.ru +4 -0
  213. data/test/rails_app/config/application.rb +40 -0
  214. data/test/rails_app/config/boot.rb +14 -0
  215. data/test/rails_app/config/database.yml +18 -0
  216. data/test/rails_app/config/environment.rb +5 -0
  217. data/test/rails_app/config/environments/development.rb +30 -0
  218. data/test/rails_app/config/environments/production.rb +80 -0
  219. data/test/rails_app/config/environments/test.rb +36 -0
  220. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  221. data/test/rails_app/config/initializers/devise.rb +180 -0
  222. data/test/rails_app/config/initializers/inflections.rb +2 -0
  223. data/test/rails_app/config/initializers/secret_token.rb +8 -0
  224. data/test/rails_app/config/initializers/session_store.rb +1 -0
  225. data/test/rails_app/config/routes.rb +122 -0
  226. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +71 -0
  227. data/test/rails_app/db/schema.rb +55 -0
  228. data/test/rails_app/lib/shared_admin.rb +17 -0
  229. data/test/rails_app/lib/shared_user.rb +29 -0
  230. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  231. data/test/rails_app/public/404.html +26 -0
  232. data/test/rails_app/public/422.html +26 -0
  233. data/test/rails_app/public/500.html +26 -0
  234. data/test/rails_app/public/favicon.ico +0 -0
  235. data/test/routes_test.rb +264 -0
  236. data/test/support/action_controller/record_identifier.rb +10 -0
  237. data/test/support/assertions.rb +39 -0
  238. data/test/support/helpers.rb +73 -0
  239. data/test/support/integration.rb +92 -0
  240. data/test/support/locale/en.yml +8 -0
  241. data/test/support/mongoid.yml +6 -0
  242. data/test/support/webrat/integrations/rails.rb +24 -0
  243. data/test/test_helper.rb +34 -0
  244. data/test/test_helpers_test.rb +163 -0
  245. data/test/test_models.rb +33 -0
  246. metadata +531 -0
@@ -0,0 +1,275 @@
1
+ require 'test_helper'
2
+ require 'ostruct'
3
+
4
+ class FailureTest < ActiveSupport::TestCase
5
+ class RootFailureApp < Devise::FailureApp
6
+ def fake_app
7
+ Object.new
8
+ end
9
+ end
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
+ def self.context(name, &block)
30
+ instance_eval(&block)
31
+ end
32
+
33
+ def call_failure(env_params={})
34
+ env = {
35
+ 'REQUEST_URI' => 'http://test.host/',
36
+ 'HTTP_HOST' => 'test.host',
37
+ 'REQUEST_METHOD' => 'GET',
38
+ 'warden.options' => { scope: :user },
39
+ 'rack.session' => {},
40
+ 'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
41
+ 'rack.input' => "",
42
+ 'warden' => OpenStruct.new(message: nil)
43
+ }.merge!(env_params)
44
+
45
+ @response = (env.delete(:app) || Devise::FailureApp).call(env).to_a
46
+ @request = ActionDispatch::Request.new(env)
47
+ end
48
+
49
+ context 'When redirecting' do
50
+ test 'returns to the default redirect location' do
51
+ call_failure
52
+ assert_equal 302, @response.first
53
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
54
+ assert_equal 'http://test.host/users/sign_in', @response.second['Location']
55
+ end
56
+
57
+ test 'returns to the default redirect location considering subdomain' do
58
+ call_failure('warden.options' => { scope: :subdomain_user })
59
+ assert_equal 302, @response.first
60
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
61
+ assert_equal 'http://sub.test.host/subdomain_users/sign_in', @response.second['Location']
62
+ end
63
+
64
+ test 'returns to the default redirect location for wildcard requests' do
65
+ call_failure 'action_dispatch.request.formats' => nil, 'HTTP_ACCEPT' => '*/*'
66
+ assert_equal 302, @response.first
67
+ assert_equal 'http://test.host/users/sign_in', @response.second['Location']
68
+ end
69
+
70
+ test 'returns to the root path if no session path is available' do
71
+ swap Devise, router_name: :fake_app do
72
+ call_failure app: RootFailureApp
73
+ assert_equal 302, @response.first
74
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
75
+ assert_equal 'http://test.host/', @response.second['Location']
76
+ end
77
+ end
78
+
79
+ test 'returns to the root path considering subdomain if no session path is available' do
80
+ swap Devise, router_name: :fake_app do
81
+ call_failure app: FailureWithSubdomain
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/', @response.second['Location']
85
+ end
86
+ end
87
+
88
+ if Rails.application.config.respond_to?(:relative_url_root)
89
+ test 'returns to the default redirect location considering the relative url root' do
90
+ swap Rails.application.config, relative_url_root: "/sample" do
91
+ call_failure
92
+ assert_equal 302, @response.first
93
+ assert_equal 'http://test.host/sample/users/sign_in', @response.second['Location']
94
+ end
95
+ end
96
+
97
+ test 'returns to the default redirect location considering the relative url root and subdomain' do
98
+ swap Rails.application.config, relative_url_root: "/sample" do
99
+ call_failure('warden.options' => { scope: :subdomain_user })
100
+ assert_equal 302, @response.first
101
+ assert_equal 'http://sub.test.host/sample/subdomain_users/sign_in', @response.second['Location']
102
+ end
103
+ end
104
+ end
105
+
106
+ test 'uses the proxy failure message as symbol' do
107
+ call_failure('warden' => OpenStruct.new(message: :invalid))
108
+ assert_equal 'Invalid email or password.', @request.flash[:alert]
109
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
110
+ end
111
+
112
+ test 'supports authentication_keys as a Hash for the flash message' do
113
+ swap Devise, authentication_keys: { email: true, login: true } do
114
+ call_failure('warden' => OpenStruct.new(message: :invalid))
115
+ assert_equal 'Invalid email, login or password.', @request.flash[:alert]
116
+ end
117
+ end
118
+
119
+ test 'uses custom i18n options' do
120
+ call_failure('warden' => OpenStruct.new(message: :does_not_exist), app: FailureWithI18nOptions)
121
+ assert_equal 'User Steve does not exist', @request.flash[:alert]
122
+ end
123
+
124
+ test 'uses the proxy failure message as string' do
125
+ call_failure('warden' => OpenStruct.new(message: 'Hello world'))
126
+ assert_equal 'Hello world', @request.flash[:alert]
127
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
128
+ end
129
+
130
+ test 'set content type to default text/html' do
131
+ call_failure
132
+ assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
133
+ end
134
+
135
+ test 'setup a default message' do
136
+ call_failure
137
+ assert_match(/You are being/, @response.last.body)
138
+ assert_match(/redirected/, @response.last.body)
139
+ assert_match(/users\/sign_in/, @response.last.body)
140
+ end
141
+
142
+ test 'works for any navigational format' do
143
+ swap Devise, navigational_formats: [:xml] do
144
+ call_failure('formats' => Mime::XML)
145
+ assert_equal 302, @response.first
146
+ end
147
+ end
148
+
149
+ test 'redirects the correct format if it is a non-html format request' do
150
+ swap Devise, navigational_formats: [:js] do
151
+ call_failure('formats' => Mime::JS)
152
+ assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
153
+ end
154
+ end
155
+ end
156
+
157
+ context 'For HTTP request' do
158
+ test 'return 401 status' do
159
+ call_failure('formats' => Mime::XML)
160
+ assert_equal 401, @response.first
161
+ end
162
+
163
+ test 'return appropriate body for xml' do
164
+ call_failure('formats' => Mime::XML)
165
+ 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)
166
+ assert_equal result, @response.last.body
167
+ end
168
+
169
+ test 'return appropriate body for json' do
170
+ call_failure('formats' => Mime::JSON)
171
+ result = %({"error":"You need to sign in or sign up before continuing."})
172
+ assert_equal result, @response.last.body
173
+ end
174
+
175
+ test 'return 401 status for unknown formats' do
176
+ call_failure 'formats' => []
177
+ assert_equal 401, @response.first
178
+ end
179
+
180
+ test 'return WWW-authenticate headers if model allows' do
181
+ call_failure('formats' => Mime::XML)
182
+ assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
183
+ end
184
+
185
+ test 'does not return WWW-authenticate headers if model does not allow' do
186
+ swap Devise, http_authenticatable: false do
187
+ call_failure('formats' => Mime::XML)
188
+ assert_nil @response.second["WWW-Authenticate"]
189
+ end
190
+ end
191
+
192
+ test 'works for any non navigational format' do
193
+ swap Devise, navigational_formats: [] do
194
+ call_failure('formats' => Mime::HTML)
195
+ assert_equal 401, @response.first
196
+ end
197
+ end
198
+
199
+ test 'uses the failure message as response body' do
200
+ call_failure('formats' => Mime::XML, 'warden' => OpenStruct.new(message: :invalid))
201
+ assert_match '<error>Invalid email or password.</error>', @response.third.body
202
+ end
203
+
204
+ context 'on ajax call' do
205
+ context 'when http_authenticatable_on_xhr is false' do
206
+ test 'dont return 401 with navigational formats' do
207
+ swap Devise, http_authenticatable_on_xhr: false do
208
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
209
+ assert_equal 302, @response.first
210
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
211
+ end
212
+ end
213
+
214
+ test 'dont return 401 with non navigational formats' do
215
+ swap Devise, http_authenticatable_on_xhr: false do
216
+ call_failure('formats' => Mime::JSON, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
217
+ assert_equal 302, @response.first
218
+ assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
219
+ end
220
+ end
221
+ end
222
+
223
+ context 'when http_authenticatable_on_xhr is true' do
224
+ test 'return 401' do
225
+ swap Devise, http_authenticatable_on_xhr: true do
226
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
227
+ assert_equal 401, @response.first
228
+ end
229
+ end
230
+
231
+ test 'skip WWW-Authenticate header' do
232
+ swap Devise, http_authenticatable_on_xhr: true do
233
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
234
+ assert_nil @response.second['WWW-Authenticate']
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ context 'With recall' do
242
+ test 'calls the original controller if invalid email or password' do
243
+ env = {
244
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in" },
245
+ "devise.mapping" => Devise.mappings[:user],
246
+ "warden" => stub_everything
247
+ }
248
+ call_failure(env)
249
+ assert @response.third.body.include?('<h2>Log in</h2>')
250
+ assert @response.third.body.include?('Invalid email or password.')
251
+ end
252
+
253
+ test 'calls the original controller if not confirmed email' do
254
+ env = {
255
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :unconfirmed },
256
+ "devise.mapping" => Devise.mappings[:user],
257
+ "warden" => stub_everything
258
+ }
259
+ call_failure(env)
260
+ assert @response.third.body.include?('<h2>Log in</h2>')
261
+ assert @response.third.body.include?('You have to confirm your email address before continuing.')
262
+ end
263
+
264
+ test 'calls the original controller if inactive account' do
265
+ env = {
266
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :inactive },
267
+ "devise.mapping" => Devise.mappings[:user],
268
+ "warden" => stub_everything
269
+ }
270
+ call_failure(env)
271
+ assert @response.third.body.include?('<h2>Log in</h2>')
272
+ assert @response.third.body.include?('Your account is not activated yet.')
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,109 @@
1
+ require "test_helper"
2
+
3
+ if DEVISE_ORM == :active_record
4
+ require "generators/active_record/devise_generator"
5
+
6
+ class ActiveRecordGeneratorTest < Rails::Generators::TestCase
7
+ tests ActiveRecord::Generators::DeviseGenerator
8
+ destination File.expand_path("../../tmp", __FILE__)
9
+ setup :prepare_destination
10
+
11
+ test "all files are properly created with rails31 migration syntax" do
12
+ run_generator %w(monster)
13
+ assert_migration "db/migrate/devise_create_monsters.rb", /def change/
14
+ end
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
+
21
+ test "update model migration when model exists" do
22
+ run_generator %w(monster)
23
+ assert_file "app/models/monster.rb"
24
+ run_generator %w(monster)
25
+ assert_migration "db/migrate/add_devise_to_monsters.rb"
26
+ end
27
+
28
+ test "all files are properly deleted" do
29
+ run_generator %w(monster)
30
+ run_generator %w(monster)
31
+ assert_migration "db/migrate/devise_create_monsters.rb"
32
+ assert_migration "db/migrate/add_devise_to_monsters.rb"
33
+ run_generator %w(monster), behavior: :revoke
34
+ assert_no_migration "db/migrate/add_devise_to_monsters.rb"
35
+ assert_migration "db/migrate/devise_create_monsters.rb"
36
+ run_generator %w(monster), behavior: :revoke
37
+ assert_no_file "app/models/monster.rb"
38
+ assert_no_migration "db/migrate/devise_create_monsters.rb"
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
46
+ end
47
+
48
+ module RailsEngine
49
+ class Engine < Rails::Engine
50
+ isolate_namespace RailsEngine
51
+ end
52
+ end
53
+
54
+ def simulate_inside_engine(engine, namespace)
55
+ if Rails::Generators.respond_to?(:namespace=)
56
+ swap Rails::Generators, namespace: namespace do
57
+ yield
58
+ end
59
+ else
60
+ swap Rails, application: engine.instance do
61
+ yield
62
+ end
63
+ end
64
+ end
65
+
66
+ class ActiveRecordEngineGeneratorTest < Rails::Generators::TestCase
67
+ tests ActiveRecord::Generators::DeviseGenerator
68
+ destination File.expand_path("../../tmp", __FILE__)
69
+ setup :prepare_destination
70
+
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)
99
+ simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
100
+ run_generator ["monster"]
101
+
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
106
+ end
107
+ end
108
+ 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
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ require "generators/devise/devise_generator"
4
+
5
+ class DeviseGeneratorTest < Rails::Generators::TestCase
6
+ tests Devise::Generators::DeviseGenerator
7
+ destination File.expand_path("../../tmp", __FILE__)
8
+
9
+ setup do
10
+ prepare_destination
11
+ copy_routes
12
+ end
13
+
14
+ test "route generation for simple model names" do
15
+ run_generator %w(monster name:string)
16
+ assert_file "config/routes.rb", /devise_for :monsters/
17
+ end
18
+
19
+ test "route generation for namespaced model names" do
20
+ run_generator %w(monster/goblin name:string)
21
+ match = /devise_for :goblins, class_name: "Monster::Goblin"/
22
+ assert_file "config/routes.rb", match
23
+ end
24
+
25
+ test "route generation with skip routes" do
26
+ run_generator %w(monster name:string --skip-routes)
27
+ match = /devise_for :monsters, skip: :all/
28
+ assert_file "config/routes.rb", match
29
+ end
30
+
31
+ def copy_routes
32
+ routes = File.expand_path("../../rails_app/config/routes.rb", __FILE__)
33
+ destination = File.join(destination_root, "config")
34
+
35
+ FileUtils.mkdir_p(destination)
36
+ FileUtils.cp routes, destination
37
+ end
38
+
39
+ end