devbootsrap 0.0.1

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 (219) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +31 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/app/controllers/devise/confirmations_controller.rb +47 -0
  8. data/app/controllers/devise/omniauth_callbacks_controller.rb +30 -0
  9. data/app/controllers/devise/passwords_controller.rb +70 -0
  10. data/app/controllers/devise/registrations_controller.rb +137 -0
  11. data/app/controllers/devise/sessions_controller.rb +53 -0
  12. data/app/controllers/devise/unlocks_controller.rb +46 -0
  13. data/app/controllers/devise_controller.rb +176 -0
  14. data/app/helpers/devise_helper.rb +25 -0
  15. data/app/mailers/devise/mailer.rb +20 -0
  16. data/app/views/devise/confirmations/new.html.erb +12 -0
  17. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  18. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  19. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  20. data/app/views/devise/passwords/edit.html.erb +16 -0
  21. data/app/views/devise/passwords/new.html.erb +12 -0
  22. data/app/views/devise/registrations/edit.html.erb +29 -0
  23. data/app/views/devise/registrations/new.html.erb +18 -0
  24. data/app/views/devise/sessions/new.html.erb +17 -0
  25. data/app/views/devise/shared/_links.erb +25 -0
  26. data/app/views/devise/unlocks/new.html.erb +12 -0
  27. data/config/locales/en.yml +59 -0
  28. data/devbootsrap.gemspec +29 -0
  29. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  30. data/gemfiles/Gemfile.rails-4.0-stable +29 -0
  31. data/gemfiles/Gemfile.rails-head +29 -0
  32. data/lib/devbootsrap.rb +5 -0
  33. data/lib/devbootsrap/version.rb +3 -0
  34. data/lib/devise.rb +491 -0
  35. data/lib/devise/controllers/helpers.rb +213 -0
  36. data/lib/devise/controllers/rememberable.rb +47 -0
  37. data/lib/devise/controllers/scoped_views.rb +17 -0
  38. data/lib/devise/controllers/sign_in_out.rb +103 -0
  39. data/lib/devise/controllers/store_location.rb +50 -0
  40. data/lib/devise/controllers/url_helpers.rb +67 -0
  41. data/lib/devise/delegator.rb +16 -0
  42. data/lib/devise/failure_app.rb +205 -0
  43. data/lib/devise/hooks/activatable.rb +11 -0
  44. data/lib/devise/hooks/csrf_cleaner.rb +5 -0
  45. data/lib/devise/hooks/forgetable.rb +9 -0
  46. data/lib/devise/hooks/lockable.rb +7 -0
  47. data/lib/devise/hooks/proxy.rb +21 -0
  48. data/lib/devise/hooks/rememberable.rb +7 -0
  49. data/lib/devise/hooks/timeoutable.rb +28 -0
  50. data/lib/devise/hooks/trackable.rb +9 -0
  51. data/lib/devise/mailers/helpers.rb +90 -0
  52. data/lib/devise/mapping.rb +172 -0
  53. data/lib/devise/models.rb +119 -0
  54. data/lib/devise/models/authenticatable.rb +284 -0
  55. data/lib/devise/models/confirmable.rb +295 -0
  56. data/lib/devise/models/database_authenticatable.rb +164 -0
  57. data/lib/devise/models/lockable.rb +196 -0
  58. data/lib/devise/models/omniauthable.rb +27 -0
  59. data/lib/devise/models/recoverable.rb +131 -0
  60. data/lib/devise/models/registerable.rb +25 -0
  61. data/lib/devise/models/rememberable.rb +129 -0
  62. data/lib/devise/models/timeoutable.rb +49 -0
  63. data/lib/devise/models/trackable.rb +35 -0
  64. data/lib/devise/models/validatable.rb +66 -0
  65. data/lib/devise/modules.rb +28 -0
  66. data/lib/devise/omniauth.rb +28 -0
  67. data/lib/devise/omniauth/config.rb +45 -0
  68. data/lib/devise/omniauth/url_helpers.rb +18 -0
  69. data/lib/devise/orm/active_record.rb +3 -0
  70. data/lib/devise/orm/mongoid.rb +3 -0
  71. data/lib/devise/parameter_filter.rb +40 -0
  72. data/lib/devise/parameter_sanitizer.rb +99 -0
  73. data/lib/devise/rails.rb +56 -0
  74. data/lib/devise/rails/routes.rb +496 -0
  75. data/lib/devise/rails/warden_compat.rb +22 -0
  76. data/lib/devise/strategies/authenticatable.rb +167 -0
  77. data/lib/devise/strategies/base.rb +20 -0
  78. data/lib/devise/strategies/database_authenticatable.rb +23 -0
  79. data/lib/devise/strategies/rememberable.rb +55 -0
  80. data/lib/devise/test_helpers.rb +132 -0
  81. data/lib/devise/time_inflector.rb +14 -0
  82. data/lib/devise/token_generator.rb +70 -0
  83. data/lib/devise/version.rb +3 -0
  84. data/lib/generators/active_record/devise_generator.rb +73 -0
  85. data/lib/generators/active_record/templates/migration.rb +18 -0
  86. data/lib/generators/active_record/templates/migration_existing.rb +25 -0
  87. data/lib/generators/devise/devise_generator.rb +26 -0
  88. data/lib/generators/devise/install_generator.rb +29 -0
  89. data/lib/generators/devise/orm_helpers.rb +51 -0
  90. data/lib/generators/devise/views_generator.rb +135 -0
  91. data/lib/generators/mongoid/devise_generator.rb +55 -0
  92. data/lib/generators/templates/README +35 -0
  93. data/lib/generators/templates/devise.rb +260 -0
  94. data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
  95. data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
  96. data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
  97. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +16 -0
  98. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
  99. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
  100. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +27 -0
  101. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
  102. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
  103. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +16 -0
  104. data/test/controllers/custom_registrations_controller_test.rb +35 -0
  105. data/test/controllers/custom_strategy_test.rb +62 -0
  106. data/test/controllers/helpers_test.rb +276 -0
  107. data/test/controllers/internal_helpers_test.rb +123 -0
  108. data/test/controllers/passwords_controller_test.rb +31 -0
  109. data/test/controllers/sessions_controller_test.rb +103 -0
  110. data/test/controllers/url_helpers_test.rb +59 -0
  111. data/test/delegator_test.rb +19 -0
  112. data/test/devise_test.rb +94 -0
  113. data/test/failure_app_test.rb +232 -0
  114. data/test/generators/active_record_generator_test.rb +103 -0
  115. data/test/generators/devise_generator_test.rb +39 -0
  116. data/test/generators/install_generator_test.rb +13 -0
  117. data/test/generators/mongoid_generator_test.rb +23 -0
  118. data/test/generators/views_generator_test.rb +96 -0
  119. data/test/helpers/devise_helper_test.rb +51 -0
  120. data/test/integration/authenticatable_test.rb +713 -0
  121. data/test/integration/confirmable_test.rb +284 -0
  122. data/test/integration/database_authenticatable_test.rb +84 -0
  123. data/test/integration/http_authenticatable_test.rb +105 -0
  124. data/test/integration/lockable_test.rb +239 -0
  125. data/test/integration/omniauthable_test.rb +133 -0
  126. data/test/integration/recoverable_test.rb +334 -0
  127. data/test/integration/registerable_test.rb +349 -0
  128. data/test/integration/rememberable_test.rb +167 -0
  129. data/test/integration/timeoutable_test.rb +183 -0
  130. data/test/integration/trackable_test.rb +92 -0
  131. data/test/mailers/confirmation_instructions_test.rb +115 -0
  132. data/test/mailers/reset_password_instructions_test.rb +96 -0
  133. data/test/mailers/unlock_instructions_test.rb +91 -0
  134. data/test/mapping_test.rb +127 -0
  135. data/test/models/authenticatable_test.rb +13 -0
  136. data/test/models/confirmable_test.rb +454 -0
  137. data/test/models/database_authenticatable_test.rb +249 -0
  138. data/test/models/lockable_test.rb +316 -0
  139. data/test/models/omniauthable_test.rb +7 -0
  140. data/test/models/recoverable_test.rb +184 -0
  141. data/test/models/registerable_test.rb +7 -0
  142. data/test/models/rememberable_test.rb +183 -0
  143. data/test/models/serializable_test.rb +49 -0
  144. data/test/models/timeoutable_test.rb +51 -0
  145. data/test/models/trackable_test.rb +13 -0
  146. data/test/models/validatable_test.rb +127 -0
  147. data/test/models_test.rb +144 -0
  148. data/test/omniauth/config_test.rb +57 -0
  149. data/test/omniauth/url_helpers_test.rb +54 -0
  150. data/test/orm/active_record.rb +10 -0
  151. data/test/orm/mongoid.rb +13 -0
  152. data/test/parameter_sanitizer_test.rb +81 -0
  153. data/test/rails_app/Rakefile +6 -0
  154. data/test/rails_app/app/active_record/admin.rb +6 -0
  155. data/test/rails_app/app/active_record/shim.rb +2 -0
  156. data/test/rails_app/app/active_record/user.rb +6 -0
  157. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  158. data/test/rails_app/app/controllers/admins_controller.rb +11 -0
  159. data/test/rails_app/app/controllers/application_controller.rb +9 -0
  160. data/test/rails_app/app/controllers/custom/registrations_controller.rb +21 -0
  161. data/test/rails_app/app/controllers/home_controller.rb +25 -0
  162. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  163. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  164. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
  165. data/test/rails_app/app/controllers/users_controller.rb +31 -0
  166. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  167. data/test/rails_app/app/mailers/users/mailer.rb +12 -0
  168. data/test/rails_app/app/mongoid/admin.rb +29 -0
  169. data/test/rails_app/app/mongoid/shim.rb +23 -0
  170. data/test/rails_app/app/mongoid/user.rb +39 -0
  171. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  172. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  173. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  174. data/test/rails_app/app/views/home/index.html.erb +1 -0
  175. data/test/rails_app/app/views/home/join.html.erb +1 -0
  176. data/test/rails_app/app/views/home/private.html.erb +1 -0
  177. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  178. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  179. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  180. data/test/rails_app/app/views/users/index.html.erb +1 -0
  181. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  182. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  183. data/test/rails_app/bin/bundle +3 -0
  184. data/test/rails_app/bin/rails +4 -0
  185. data/test/rails_app/bin/rake +4 -0
  186. data/test/rails_app/config.ru +4 -0
  187. data/test/rails_app/config/application.rb +40 -0
  188. data/test/rails_app/config/boot.rb +14 -0
  189. data/test/rails_app/config/database.yml +18 -0
  190. data/test/rails_app/config/environment.rb +5 -0
  191. data/test/rails_app/config/environments/development.rb +30 -0
  192. data/test/rails_app/config/environments/production.rb +80 -0
  193. data/test/rails_app/config/environments/test.rb +36 -0
  194. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  195. data/test/rails_app/config/initializers/devise.rb +181 -0
  196. data/test/rails_app/config/initializers/inflections.rb +2 -0
  197. data/test/rails_app/config/initializers/secret_token.rb +8 -0
  198. data/test/rails_app/config/initializers/session_store.rb +1 -0
  199. data/test/rails_app/config/routes.rb +108 -0
  200. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +71 -0
  201. data/test/rails_app/db/schema.rb +55 -0
  202. data/test/rails_app/lib/shared_admin.rb +17 -0
  203. data/test/rails_app/lib/shared_user.rb +29 -0
  204. data/test/rails_app/public/404.html +26 -0
  205. data/test/rails_app/public/422.html +26 -0
  206. data/test/rails_app/public/500.html +26 -0
  207. data/test/rails_app/public/favicon.ico +0 -0
  208. data/test/routes_test.rb +262 -0
  209. data/test/support/action_controller/record_identifier.rb +10 -0
  210. data/test/support/assertions.rb +40 -0
  211. data/test/support/helpers.rb +70 -0
  212. data/test/support/integration.rb +92 -0
  213. data/test/support/locale/en.yml +8 -0
  214. data/test/support/mongoid.yml +6 -0
  215. data/test/support/webrat/integrations/rails.rb +24 -0
  216. data/test/test_helper.rb +27 -0
  217. data/test/test_helpers_test.rb +173 -0
  218. data/test/test_models.rb +33 -0
  219. metadata +480 -0
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class PasswordsControllerTest < ActionController::TestCase
4
+ tests Devise::PasswordsController
5
+ include Devise::TestHelpers
6
+
7
+ setup do
8
+ request.env["devise.mapping"] = Devise.mappings[:user]
9
+ @user = create_user.tap(&:confirm!)
10
+ @raw = @user.send_reset_password_instructions
11
+ end
12
+
13
+ def put_update_with_params
14
+ put :update, "user" => {
15
+ "reset_password_token" => @raw, "password" => "123456", "password_confirmation" => "123456"
16
+ }
17
+ end
18
+
19
+ test 'redirect to after_sign_in_path_for if after_resetting_password_path_for is not overridden' do
20
+ put_update_with_params
21
+ assert_redirected_to "http://test.host/"
22
+ end
23
+
24
+ test 'redirect accordingly if after_resetting_password_path_for is overridden' do
25
+ custom_path = "http://custom.path/"
26
+ Devise::PasswordsController.any_instance.stubs(:after_resetting_password_path_for).with(@user).returns(custom_path)
27
+
28
+ put_update_with_params
29
+ assert_redirected_to custom_path
30
+ end
31
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+
3
+ class SessionsControllerTest < ActionController::TestCase
4
+ tests Devise::SessionsController
5
+ include Devise::TestHelpers
6
+
7
+ test "#create doesn't raise unpermitted params when sign in fails" do
8
+ begin
9
+ subscriber = ActiveSupport::Notifications.subscribe /unpermitted_parameters/ do |name, start, finish, id, payload|
10
+ flunk "Unpermitted params: #{payload}"
11
+ end
12
+ request.env["devise.mapping"] = Devise.mappings[:user]
13
+ request.session["user_return_to"] = 'foo.bar'
14
+ create_user
15
+ post :create, user: {
16
+ email: "wrong@email.com",
17
+ password: "wrongpassword"
18
+ }
19
+ assert_equal 200, @response.status
20
+ ensure
21
+ ActiveSupport::Notifications.unsubscribe(subscriber)
22
+ end
23
+ end
24
+
25
+ test "#create works even with scoped views" do
26
+ swap Devise, scoped_views: true do
27
+ request.env["devise.mapping"] = Devise.mappings[:user]
28
+ post :create
29
+ assert_equal 200, @response.status
30
+ assert_template "users/sessions/new"
31
+ end
32
+ end
33
+
34
+ test "#create delete the url stored in the session if the requested format is navigational" do
35
+ request.env["devise.mapping"] = Devise.mappings[:user]
36
+ request.session["user_return_to"] = 'foo.bar'
37
+
38
+ user = create_user
39
+ user.confirm!
40
+ post :create, user: {
41
+ email: user.email,
42
+ password: user.password
43
+ }
44
+
45
+ assert_nil request.session["user_return_to"]
46
+ end
47
+
48
+ test "#create doesn't delete the url stored in the session if the requested format is not navigational" do
49
+ request.env["devise.mapping"] = Devise.mappings[:user]
50
+ request.session["user_return_to"] = 'foo.bar'
51
+
52
+ user = create_user
53
+ user.confirm!
54
+ post :create, format: 'json', user: {
55
+ email: user.email,
56
+ password: user.password
57
+ }
58
+
59
+ assert_equal 'foo.bar', request.session["user_return_to"]
60
+ end
61
+
62
+ test "#create doesn't raise exception after Warden authentication fails when TestHelpers included" do
63
+ request.env["devise.mapping"] = Devise.mappings[:user]
64
+ post :create, user: {
65
+ email: "nosuchuser@example.com",
66
+ password: "wevdude"
67
+ }
68
+ assert_equal 200, @response.status
69
+ assert_template "devise/sessions/new"
70
+ end
71
+
72
+ test "#destroy doesn't set the flash if the requested format is not navigational" do
73
+ request.env["devise.mapping"] = Devise.mappings[:user]
74
+ user = create_user
75
+ user.confirm!
76
+ post :create, format: 'json', user: {
77
+ email: user.email,
78
+ password: user.password
79
+ }
80
+
81
+ delete :destroy, format: 'json'
82
+ assert flash[:notice].blank?, "flash[:notice] should be blank, not #{flash[:notice].inspect}"
83
+ assert_equal 204, @response.status
84
+ end
85
+
86
+ if defined?(ActiveRecord) && ActiveRecord::Base.respond_to?(:mass_assignment_sanitizer)
87
+ test "#new doesn't raise mass-assignment exception even if sign-in key is attr_protected" do
88
+ request.env["devise.mapping"] = Devise.mappings[:user]
89
+
90
+ ActiveRecord::Base.mass_assignment_sanitizer = :strict
91
+ User.class_eval { attr_protected :email }
92
+
93
+ begin
94
+ assert_nothing_raised ActiveModel::MassAssignmentSecurity::Error do
95
+ get :new, user: { email: "allez viens!" }
96
+ end
97
+ ensure
98
+ ActiveRecord::Base.mass_assignment_sanitizer = :logger
99
+ User.class_eval { attr_accessible :email }
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+
3
+ class RoutesTest < ActionController::TestCase
4
+ tests ApplicationController
5
+
6
+ def assert_path_and_url(name, prepend_path=nil)
7
+ @request.path = '/users/session'
8
+ prepend_path = "#{prepend_path}_" if prepend_path
9
+
10
+ # Resource param
11
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", :user),
12
+ send(:"#{prepend_path}user_#{name}_path")
13
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", :user),
14
+ send(:"#{prepend_path}user_#{name}_url")
15
+
16
+ # Default url params
17
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", :user, param: 123),
18
+ send(:"#{prepend_path}user_#{name}_path", param: 123)
19
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", :user, param: 123),
20
+ send(:"#{prepend_path}user_#{name}_url", param: 123)
21
+
22
+ @request.path = nil
23
+ # With an object
24
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", User.new),
25
+ send(:"#{prepend_path}user_#{name}_path")
26
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", User.new),
27
+ send(:"#{prepend_path}user_#{name}_url")
28
+ end
29
+
30
+
31
+ test 'should alias session to mapped user session' do
32
+ assert_path_and_url :session
33
+ assert_path_and_url :session, :new
34
+ assert_path_and_url :session, :destroy
35
+ end
36
+
37
+ test 'should alias password to mapped user password' do
38
+ assert_path_and_url :password
39
+ assert_path_and_url :password, :new
40
+ assert_path_and_url :password, :edit
41
+ end
42
+
43
+ test 'should alias confirmation to mapped user confirmation' do
44
+ assert_path_and_url :confirmation
45
+ assert_path_and_url :confirmation, :new
46
+ end
47
+
48
+ test 'should alias unlock to mapped user unlock' do
49
+ assert_path_and_url :unlock
50
+ assert_path_and_url :unlock, :new
51
+ end
52
+
53
+ test 'should alias registration to mapped user registration' do
54
+ assert_path_and_url :registration
55
+ assert_path_and_url :registration, :new
56
+ assert_path_and_url :registration, :edit
57
+ assert_path_and_url :registration, :cancel
58
+ end
59
+ end
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class DelegatorTest < ActiveSupport::TestCase
4
+ def delegator
5
+ Devise::Delegator.new
6
+ end
7
+
8
+ test 'failure_app returns default failure app if no warden options in env' do
9
+ assert_equal Devise::FailureApp, delegator.failure_app({})
10
+ end
11
+
12
+ test 'failure_app returns default failure app if no scope in warden options' do
13
+ assert_equal Devise::FailureApp, delegator.failure_app({"warden.options" => {}})
14
+ end
15
+
16
+ test 'failure_app returns associated failure app by scope in the given environment' do
17
+ assert_kind_of Proc, delegator.failure_app({"warden.options" => {scope: "manager"}})
18
+ end
19
+ end
@@ -0,0 +1,94 @@
1
+ require 'test_helper'
2
+
3
+ module Devise
4
+ def self.yield_and_restore
5
+ @@warden_configured = nil
6
+ c, b = @@warden_config, @@warden_config_block
7
+ yield
8
+ ensure
9
+ @@warden_config, @@warden_config_block = c, b
10
+ end
11
+ end
12
+
13
+ class DeviseTest < ActiveSupport::TestCase
14
+ test 'bcrypt on the class' do
15
+ password = "super secret"
16
+ klass = Struct.new(:pepper, :stretches).new("blahblah", 2)
17
+ hash = Devise.bcrypt(klass, password)
18
+ assert_equal ::BCrypt::Password.create(hash), hash
19
+
20
+ klass = Struct.new(:pepper, :stretches).new("bla", 2)
21
+ hash = Devise.bcrypt(klass, password)
22
+ assert_not_equal ::BCrypt::Password.new(hash), hash
23
+ end
24
+
25
+ test 'model options can be configured through Devise' do
26
+ swap Devise, allow_unconfirmed_access_for: 113, pepper: "foo" do
27
+ assert_equal 113, Devise.allow_unconfirmed_access_for
28
+ assert_equal "foo", Devise.pepper
29
+ end
30
+ end
31
+
32
+ test 'setup block yields self' do
33
+ Devise.setup do |config|
34
+ assert_equal Devise, config
35
+ end
36
+ end
37
+
38
+ test 'stores warden configuration' do
39
+ assert_kind_of Devise::Delegator, Devise.warden_config.failure_app
40
+ assert_equal :user, Devise.warden_config.default_scope
41
+ end
42
+
43
+ test 'warden manager user configuration through a block' do
44
+ Devise.yield_and_restore do
45
+ @executed = false
46
+ Devise.warden do |config|
47
+ @executed = true
48
+ assert_kind_of Warden::Config, config
49
+ end
50
+
51
+ Devise.configure_warden!
52
+ assert @executed
53
+ end
54
+ end
55
+
56
+ test 'add new module using the helper method' do
57
+ assert_nothing_raised(Exception) { Devise.add_module(:coconut) }
58
+ assert_equal 1, Devise::ALL.select { |v| v == :coconut }.size
59
+ assert_not Devise::STRATEGIES.include?(:coconut)
60
+ assert_not defined?(Devise::Models::Coconut)
61
+ Devise::ALL.delete(:coconut)
62
+
63
+ assert_nothing_raised(Exception) { Devise.add_module(:banana, strategy: :fruits) }
64
+ assert_equal :fruits, Devise::STRATEGIES[:banana]
65
+ Devise::ALL.delete(:banana)
66
+ Devise::STRATEGIES.delete(:banana)
67
+
68
+ assert_nothing_raised(Exception) { Devise.add_module(:kivi, controller: :fruits) }
69
+ assert_equal :fruits, Devise::CONTROLLERS[:kivi]
70
+ Devise::ALL.delete(:kivi)
71
+ Devise::CONTROLLERS.delete(:kivi)
72
+ end
73
+
74
+ test 'should complain when comparing empty or different sized passes' do
75
+ [nil, ""].each do |empty|
76
+ assert_not Devise.secure_compare(empty, "something")
77
+ assert_not Devise.secure_compare("something", empty)
78
+ assert_not Devise.secure_compare(empty, empty)
79
+ end
80
+ assert_not Devise.secure_compare("size_1", "size_four")
81
+ end
82
+
83
+ test 'Devise.email_regexp should match valid email addresses' do
84
+ valid_emails = ["test@example.com", "jo@jo.co", "f4$_m@you.com", "testing.example@example.com.ua"]
85
+ non_valid_emails = ["rex", "test@go,com", "test user@example.com", "test_user@example server.com"]
86
+
87
+ valid_emails.each do |email|
88
+ assert_match Devise.email_regexp, email
89
+ end
90
+ non_valid_emails.each do |email|
91
+ assert_no_match Devise.email_regexp, email
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,232 @@
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 FailureWithI18nOptions < Devise::FailureApp
12
+ def i18n_options(options)
13
+ options.merge(name: 'Steve')
14
+ end
15
+ end
16
+
17
+ def self.context(name, &block)
18
+ instance_eval(&block)
19
+ end
20
+
21
+ def call_failure(env_params={})
22
+ env = {
23
+ 'REQUEST_URI' => 'http://test.host/',
24
+ 'HTTP_HOST' => 'test.host',
25
+ 'REQUEST_METHOD' => 'GET',
26
+ 'warden.options' => { scope: :user },
27
+ 'rack.session' => {},
28
+ 'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
29
+ 'rack.input' => "",
30
+ 'warden' => OpenStruct.new(message: nil)
31
+ }.merge!(env_params)
32
+
33
+ @response = (env.delete(:app) || Devise::FailureApp).call(env).to_a
34
+ @request = ActionDispatch::Request.new(env)
35
+ end
36
+
37
+ context 'When redirecting' do
38
+ test 'returns to the default redirect location' do
39
+ call_failure
40
+ assert_equal 302, @response.first
41
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
42
+ assert_equal 'http://test.host/users/sign_in', @response.second['Location']
43
+ end
44
+
45
+ test 'returns to the default redirect location for wildcard requests' do
46
+ call_failure 'action_dispatch.request.formats' => nil, 'HTTP_ACCEPT' => '*/*'
47
+ assert_equal 302, @response.first
48
+ assert_equal 'http://test.host/users/sign_in', @response.second['Location']
49
+ end
50
+
51
+ 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
54
+ assert_equal 302, @response.first
55
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
56
+ assert_equal 'http://test.host/', @response.second['Location']
57
+ end
58
+ end
59
+
60
+ if Rails.application.config.respond_to?(:relative_url_root)
61
+ test 'returns to the default redirect location considering the relative url root' do
62
+ swap Rails.application.config, relative_url_root: "/sample" do
63
+ call_failure
64
+ assert_equal 302, @response.first
65
+ assert_equal 'http://test.host/sample/users/sign_in', @response.second['Location']
66
+ end
67
+ end
68
+ end
69
+
70
+ 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]
73
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
74
+ end
75
+
76
+ test 'uses custom i18n options' do
77
+ call_failure('warden' => OpenStruct.new(message: :does_not_exist), app: FailureWithI18nOptions)
78
+ assert_equal 'User Steve does not exist', @request.flash[:alert]
79
+ end
80
+
81
+ test 'uses the proxy failure message as string' do
82
+ call_failure('warden' => OpenStruct.new(message: 'Hello world'))
83
+ assert_equal 'Hello world', @request.flash[:alert]
84
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
85
+ end
86
+
87
+ test 'set content type to default text/html' do
88
+ call_failure
89
+ assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
90
+ end
91
+
92
+ test 'setup a default message' do
93
+ call_failure
94
+ assert_match(/You are being/, @response.last.body)
95
+ assert_match(/redirected/, @response.last.body)
96
+ assert_match(/users\/sign_in/, @response.last.body)
97
+ end
98
+
99
+ test 'works for any navigational format' do
100
+ swap Devise, navigational_formats: [:xml] do
101
+ call_failure('formats' => Mime::XML)
102
+ assert_equal 302, @response.first
103
+ end
104
+ end
105
+
106
+ 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)
109
+ assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'For HTTP request' do
115
+ test 'return 401 status' do
116
+ call_failure('formats' => Mime::XML)
117
+ assert_equal 401, @response.first
118
+ end
119
+
120
+ test 'return appropriate body for xml' do
121
+ call_failure('formats' => Mime::XML)
122
+ 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
+ assert_equal result, @response.last.body
124
+ end
125
+
126
+ test 'return appropriate body for json' do
127
+ call_failure('formats' => Mime::JSON)
128
+ result = %({"error":"You need to sign in or sign up before continuing."})
129
+ assert_equal result, @response.last.body
130
+ end
131
+
132
+ test 'return 401 status for unknown formats' do
133
+ call_failure 'formats' => []
134
+ assert_equal 401, @response.first
135
+ end
136
+
137
+ test 'return WWW-authenticate headers if model allows' do
138
+ call_failure('formats' => Mime::XML)
139
+ assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
140
+ end
141
+
142
+ 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)
145
+ assert_nil @response.second["WWW-Authenticate"]
146
+ end
147
+ end
148
+
149
+ test 'works for any non navigational format' do
150
+ swap Devise, navigational_formats: [] do
151
+ call_failure('formats' => Mime::HTML)
152
+ assert_equal 401, @response.first
153
+ end
154
+ end
155
+
156
+ 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
159
+ end
160
+
161
+ context 'on ajax call' do
162
+ context 'when http_authenticatable_on_xhr is false' do
163
+ 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')
166
+ assert_equal 302, @response.first
167
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
168
+ end
169
+ end
170
+
171
+ 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')
174
+ assert_equal 302, @response.first
175
+ assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
176
+ end
177
+ end
178
+ end
179
+
180
+ context 'when http_authenticatable_on_xhr is true' do
181
+ test 'return 401' do
182
+ swap Devise, http_authenticatable_on_xhr: true do
183
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
184
+ assert_equal 401, @response.first
185
+ end
186
+ end
187
+
188
+ 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')
191
+ assert_nil @response.second['WWW-Authenticate']
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ context 'With recall' do
199
+ test 'calls the original controller if invalid email or password' do
200
+ env = {
201
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in" },
202
+ "devise.mapping" => Devise.mappings[:user],
203
+ "warden" => stub_everything
204
+ }
205
+ call_failure(env)
206
+ assert @response.third.body.include?('<h2>Sign in</h2>')
207
+ assert @response.third.body.include?('Invalid email or password.')
208
+ end
209
+
210
+ test 'calls the original controller if not confirmed email' do
211
+ env = {
212
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :unconfirmed },
213
+ "devise.mapping" => Devise.mappings[:user],
214
+ "warden" => stub_everything
215
+ }
216
+ call_failure(env)
217
+ assert @response.third.body.include?('<h2>Sign in</h2>')
218
+ assert @response.third.body.include?('You have to confirm your email address before continuing.')
219
+ end
220
+
221
+ test 'calls the original controller if inactive account' do
222
+ env = {
223
+ "warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", message: :inactive },
224
+ "devise.mapping" => Devise.mappings[:user],
225
+ "warden" => stub_everything
226
+ }
227
+ call_failure(env)
228
+ assert @response.third.body.include?('<h2>Sign in</h2>')
229
+ assert @response.third.body.include?('Your account is not activated yet.')
230
+ end
231
+ end
232
+ end