devise-security 0.13.0 → 0.14.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +30 -12
  6. data/Appraisals +21 -5
  7. data/Gemfile +8 -1
  8. data/README.md +47 -7
  9. data/app/views/devise/paranoid_verification_code/show.html.erb +1 -1
  10. data/app/views/devise/password_expired/show.html.erb +1 -1
  11. data/config/locales/de.yml +11 -11
  12. data/config/locales/fr.yml +13 -13
  13. data/config/locales/ja.yml +29 -0
  14. data/devise-security.gemspec +12 -6
  15. data/gemfiles/rails_4.2_stable.gemfile +9 -1
  16. data/gemfiles/rails_5.0_stable.gemfile +8 -1
  17. data/gemfiles/rails_5.1_stable.gemfile +8 -1
  18. data/gemfiles/{rails_5.2.0.gemfile → rails_5.2_stable.gemfile} +8 -1
  19. data/gemfiles/rails_6.0_beta.gemfile +15 -0
  20. data/lib/devise-security.rb +2 -4
  21. data/lib/devise-security/models/{old_password.rb → active_record/old_password.rb} +1 -2
  22. data/lib/devise-security/models/compatibility.rb +6 -15
  23. data/lib/devise-security/models/compatibility/active_record.rb +29 -0
  24. data/lib/devise-security/models/compatibility/mongoid.rb +21 -0
  25. data/lib/devise-security/models/database_authenticatable_patch.rb +1 -1
  26. data/lib/devise-security/models/expirable.rb +6 -2
  27. data/lib/devise-security/models/mongoid/old_password.rb +21 -0
  28. data/lib/devise-security/models/password_archivable.rb +16 -7
  29. data/lib/devise-security/models/password_expirable.rb +5 -0
  30. data/lib/devise-security/models/secure_validatable.rb +2 -2
  31. data/lib/devise-security/orm/mongoid.rb +7 -0
  32. data/lib/devise-security/patches/controller_security_question.rb +1 -1
  33. data/lib/devise-security/version.rb +1 -1
  34. data/lib/generators/devise_security/install_generator.rb +1 -1
  35. data/test/dummy/app/models/application_record.rb +8 -2
  36. data/test/dummy/app/models/application_user_record.rb +11 -0
  37. data/test/dummy/app/models/captcha_user.rb +5 -2
  38. data/test/dummy/app/models/mongoid/confirmable_fields.rb +13 -0
  39. data/test/dummy/app/models/mongoid/database_authenticable_fields.rb +17 -0
  40. data/test/dummy/app/models/mongoid/expirable_fields.rb +11 -0
  41. data/test/dummy/app/models/mongoid/lockable_fields.rb +13 -0
  42. data/test/dummy/app/models/mongoid/mappings.rb +13 -0
  43. data/test/dummy/app/models/mongoid/omniauthable_fields.rb +11 -0
  44. data/test/dummy/app/models/mongoid/paranoid_verification_fields.rb +10 -0
  45. data/test/dummy/app/models/mongoid/password_archivable_fields.rb +9 -0
  46. data/test/dummy/app/models/mongoid/password_expirable_fields.rb +10 -0
  47. data/test/dummy/app/models/mongoid/recoverable_fields.rb +11 -0
  48. data/test/dummy/app/models/mongoid/registerable_fields.rb +19 -0
  49. data/test/dummy/app/models/mongoid/rememberable_fields.rb +10 -0
  50. data/test/dummy/app/models/mongoid/secure_validatable_fields.rb +11 -0
  51. data/test/dummy/app/models/mongoid/security_questionable_fields.rb +13 -0
  52. data/test/dummy/app/models/mongoid/session_limitable_fields.rb +10 -0
  53. data/test/dummy/app/models/mongoid/timeoutable_fields.rb +9 -0
  54. data/test/dummy/app/models/mongoid/trackable_fields.rb +14 -0
  55. data/test/dummy/app/models/mongoid/validatable_fields.rb +7 -0
  56. data/test/dummy/app/models/secure_user.rb +5 -1
  57. data/test/dummy/app/models/security_question_user.rb +7 -4
  58. data/test/dummy/app/models/user.rb +5 -0
  59. data/test/dummy/app/models/widget.rb +4 -0
  60. data/test/dummy/app/mongoid/admin.rb +31 -0
  61. data/test/dummy/app/mongoid/one_user.rb +58 -0
  62. data/test/dummy/app/mongoid/shim.rb +25 -0
  63. data/test/dummy/app/mongoid/user_on_engine.rb +41 -0
  64. data/test/dummy/app/mongoid/user_on_main_app.rb +41 -0
  65. data/test/dummy/app/mongoid/user_with_validations.rb +37 -0
  66. data/test/dummy/app/mongoid/user_without_email.rb +35 -0
  67. data/test/dummy/config/application.rb +10 -7
  68. data/test/dummy/config/environments/test.rb +2 -2
  69. data/test/dummy/config/initializers/devise.rb +3 -4
  70. data/test/dummy/config/initializers/migration_class.rb +8 -6
  71. data/test/dummy/config/mongoid.yml +6 -0
  72. data/test/dummy/lib/shared_expirable_columns.rb +14 -0
  73. data/test/dummy/lib/shared_security_questions_fields.rb +16 -0
  74. data/test/dummy/lib/shared_user.rb +32 -0
  75. data/test/dummy/lib/shared_user_with_password_verification.rb +13 -0
  76. data/test/dummy/lib/shared_user_without_email.rb +28 -0
  77. data/test/dummy/lib/shared_user_without_omniauth.rb +15 -0
  78. data/test/dummy/lib/shared_verification_fields.rb +15 -0
  79. data/test/orm/active_record.rb +12 -0
  80. data/test/orm/mongoid.rb +12 -0
  81. data/test/support/mongoid.yml +6 -0
  82. data/test/test_helper.rb +16 -9
  83. data/test/test_install_generator.rb +1 -0
  84. data/test/test_password_archivable.rb +6 -7
  85. data/test/test_password_expirable.rb +3 -1
  86. data/test/test_secure_validatable.rb +11 -10
  87. data/test/test_security_question_controller.rb +9 -11
  88. metadata +125 -16
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shared_user_without_email"
4
+
5
+ class UserWithoutEmail
6
+ include Mongoid::Document
7
+ include Shim
8
+ include SharedUserWithoutEmail
9
+
10
+ field :username, type: String
11
+ field :facebook_token, type: String
12
+
13
+ ## Database authenticatable
14
+ field :email, type: String, default: ""
15
+ field :encrypted_password, type: String, default: ""
16
+
17
+ ## Recoverable
18
+ field :reset_password_token, type: String
19
+ field :reset_password_sent_at, type: Time
20
+
21
+ ## Rememberable
22
+ field :remember_created_at, type: Time
23
+
24
+ ## Trackable
25
+ field :sign_in_count, type: Integer, default: 0
26
+ field :current_sign_in_at, type: Time
27
+ field :last_sign_in_at, type: Time
28
+ field :current_sign_in_ip, type: String
29
+ field :last_sign_in_ip, type: String
30
+
31
+ ## Lockable
32
+ field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
33
+ field :unlock_token, type: String # Only if unlock strategy is :email or :both
34
+ field :locked_at, type: Time
35
+ end
@@ -2,22 +2,25 @@
2
2
 
3
3
  require File.expand_path('../boot', __FILE__)
4
4
 
5
+ require 'action_mailer/railtie'
6
+ require "action_mailer/railtie"
7
+ require "rails/test_unit/railtie"
8
+
9
+ Bundler.require :default, DEVISE_ORM
10
+ require "#{DEVISE_ORM}/railtie"
11
+
5
12
  require 'rails/all'
6
13
  require 'devise-security'
7
14
 
8
- if defined?(Bundler)
9
- # If you precompile assets before deploying to production, use this line
10
- Bundler.require(*Rails.groups(assets: %w[development test]))
11
- # If you want your assets lazily compiled in production, use this line
12
- # Bundler.require(:default, :assets, Rails.env)
13
- end
14
-
15
15
  module RailsApp
16
16
  class Application < Rails::Application
17
17
  config.encoding = 'utf-8'
18
18
 
19
19
  config.filter_parameters += [:password]
20
20
 
21
+ config.autoload_paths += ["#{config.root}/app/#{DEVISE_ORM}"]
22
+ config.autoload_paths += ["#{config.root}/lib"]
23
+
21
24
  config.assets.enabled = true
22
25
 
23
26
  config.assets.version = '1.0'
@@ -27,10 +27,10 @@ RailsApp::Application.configure do
27
27
 
28
28
  config.active_support.test_order = :sorted
29
29
  config.log_level = :debug
30
- if Rails.gem_version >= Gem::Version.new('4.2') && Rails.gem_version < Gem::Version.new('5.0')
30
+ if Rails.gem_version >= Gem::Version.new('4.2') && Rails.gem_version.release < Gem::Version.new('5.0')
31
31
  config.active_record.raise_in_transactional_callbacks = true
32
32
  end
33
- if Rails.gem_version.release >= Gem::Version.new('5.2')
33
+ if Rails.gem_version.release >= Gem::Version.new('5.2') && Rails.gem_version.release < Gem::Version.new('6.0')
34
34
  config.active_record.sqlite3.represent_boolean_as_integer = true
35
35
  end
36
36
  end
@@ -1,18 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails_email_validator'
4
+ require "devise/orm/#{DEVISE_ORM}"
5
+
4
6
  Devise.setup do |config|
5
7
  config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
6
-
7
- require 'devise/orm/active_record'
8
8
  config.secret_key = 'f08cf11a38906f531d2dfc9a2c2d671aa0021be806c21255d4'
9
9
  config.case_insensitive_keys = [:email]
10
-
11
10
  config.strip_whitespace_keys = [:email]
12
-
13
11
  config.password_complexity = {
14
12
  digit: 1,
15
13
  lower: 1,
16
14
  upper: 1,
17
15
  }
16
+ config.password_length = 7..128
18
17
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- MIGRATION_CLASS =
4
- if ActiveRecord::VERSION::MAJOR >= 5
5
- ActiveRecord::Migration[4.2]
6
- else
7
- ActiveRecord::Migration
8
- end
3
+ if DEVISE_ORM == :active_record
4
+ MIGRATION_CLASS =
5
+ if Rails.gem_version >= Gem::Version.new('5.0')
6
+ ActiveRecord::Migration[Rails.version.to_f]
7
+ else
8
+ ActiveRecord::Migration
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ <%= Mongoid::VERSION.to_i > 4 ? 'clients' : 'sessions' %>:
3
+ default:
4
+ database: devise_security_test
5
+ hosts:
6
+ - localhost: <%= ENV.fetch('MONGODB_PORT', '27017') %>
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ require 'shared_user'
3
+
4
+ module SharedVerificationColumns
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include SharedUser
9
+ devise :expirable
10
+
11
+ field :expired_at, type: Time
12
+ field :last_activity_at, type: Time
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ require 'shared_user'
3
+
4
+ module SharedSecurityQuestionsFields
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include SharedUser
9
+ devise :lockable, :security_questionable
10
+
11
+ field :locked_at, type: Time
12
+ field :unlock_token, type: String
13
+ field :security_question_id, type: Integer
14
+ field :security_question_answer, type: String
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SharedUser
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ devise :database_authenticatable, :confirmable, :lockable, :recoverable,
8
+ :registerable, :rememberable, :timeoutable,
9
+ :trackable, :secure_validatable, :omniauthable, :validatable, password_length: 7..72,
10
+ reconfirmable: false
11
+
12
+ attr_accessor :other_key
13
+
14
+ # They need to be included after Devise is called.
15
+ extend ExtendMethods
16
+ end
17
+
18
+ def raw_confirmation_token
19
+ @raw_confirmation_token
20
+ end
21
+
22
+ module ExtendMethods
23
+ def new_with_session(params, session)
24
+ super.tap do |user|
25
+ if data = session["devise.facebook_data"]
26
+ user.email = data["email"]
27
+ user.confirmed_at = Time.zone.now
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SharedUserWithPasswordVerification
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include SharedVerificationFields
8
+ end
9
+
10
+ def raw_confirmation_token
11
+ @raw_confirmation_token
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SharedUserWithoutEmail
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ # NOTE: This is missing :validatable and :confirmable, as they both require
8
+ # an email field at the moment. It is also missing :omniauthable because that
9
+ # adds unnecessary complexity to the setup
10
+ devise :database_authenticatable, :lockable, :recoverable,
11
+ :registerable, :rememberable, :timeoutable,
12
+ :trackable
13
+ end
14
+
15
+ # This test stub is a bit rubbish because it's tied very closely to the
16
+ # implementation where we care about this one case. However, completely
17
+ # removing the email field breaks "recoverable" tests completely, so we are
18
+ # just taking the approach here that "email" is something that is a not an
19
+ # ActiveRecord field.
20
+ def email_changed?
21
+ raise NoMethodError
22
+ end
23
+
24
+ def respond_to?(method_name, include_all=false)
25
+ return false if method_name.to_sym == :email_changed?
26
+ super(method_name, include_all)
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SharedUserWithoutOmniauth
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ devise :database_authenticatable, :confirmable, :lockable, :recoverable,
8
+ :registerable, :rememberable, :timeoutable,
9
+ :trackable, :validatable, reconfirmable: false
10
+ end
11
+
12
+ def raw_confirmation_token
13
+ @raw_confirmation_token
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ require 'shared_user'
3
+
4
+ module SharedVerificationFields
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include SharedUser
9
+ devise :paranoid_verification
10
+
11
+ field :paranoid_verified_at, type: Time
12
+ field :paranoid_verification_attempt, type: Integer, default: 0
13
+ field :paranoid_verification_code, type: String
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Migration.verbose = false
4
+ ActiveRecord::Base.logger = Logger.new(nil)
5
+ if Rails.gem_version >= Gem::Version.new('5.2.0')
6
+ ActiveRecord::MigrationContext.new(File.expand_path('../../dummy/db/migrate', __FILE__)).migrate
7
+ else
8
+ ActiveRecord::Migrator.migrate(File.expand_path('../../dummy/db/migrate', __FILE__))
9
+ end
10
+
11
+ DatabaseCleaner[:active_record].strategy = :transaction
12
+ ORMInvalidRecordException = ActiveRecord::RecordInvalid
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mongoid/version'
4
+
5
+ Mongoid.configure do |config|
6
+ config.load!('test/support/mongoid.yml', Rails.env)
7
+ config.use_utc = true
8
+ config.include_root_in_json = true
9
+ end
10
+
11
+ DatabaseCleaner[:mongoid].strategy = :truncation
12
+ ORMInvalidRecordException = Mongoid::Errors::Validations
@@ -0,0 +1,6 @@
1
+ test:
2
+ <%= Mongoid::VERSION.to_i > 4 ? 'clients' : 'sessions' %>:
3
+ default:
4
+ database: devise-test-suite
5
+ hosts:
6
+ - localhost:<%= ENV.fetch('MONGODB_PORT', '27017') %>
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ENV['RAILS_ENV'] ||= 'test'
4
+ DEVISE_ORM = ENV.fetch('DEVISE_ORM', 'active_record').to_sym
4
5
 
5
6
  require 'simplecov'
6
7
  SimpleCov.start do
7
8
  add_filter 'gemfiles'
8
9
  add_group 'Tests', 'test'
9
- add_group 'Password Expireable', "password_expirable"
10
+ add_group 'Password Archivable', 'password_archivable'
11
+ add_group 'Password Expirable', 'password_expirable'
10
12
  end
11
13
 
12
14
  if ENV['CI']
@@ -15,17 +17,22 @@ if ENV['CI']
15
17
  Coveralls.wear!
16
18
  end
17
19
 
20
+ require 'pry'
18
21
  require 'dummy/config/environment'
19
22
  require 'minitest/autorun'
20
23
  require 'rails/test_help'
21
-
22
24
  require 'devise-security'
23
- require 'pry'
25
+ require 'database_cleaner'
26
+ require "orm/#{DEVISE_ORM}"
24
27
 
25
- ActiveRecord::Migration.verbose = false
26
- ActiveRecord::Base.logger = Logger.new(nil)
27
- if Rails.gem_version >= Gem::Version.new('5.2.0')
28
- ActiveRecord::MigrationContext.new(File.expand_path('../dummy/db/migrate', __FILE__)).migrate
29
- else
30
- ActiveRecord::Migrator.migrate(File.expand_path('../dummy/db/migrate', __FILE__))
28
+ class Minitest::Test
29
+ def before_setup
30
+ DatabaseCleaner.start
31
+ end
32
+
33
+ def after_teardown
34
+ DatabaseCleaner.clean
35
+ end
31
36
  end
37
+
38
+ DatabaseCleaner.clean
@@ -17,6 +17,7 @@ class TestInstallGenerator < Rails::Generators::TestCase
17
17
  assert_file 'config/locales/devise.security_extension.es.yml'
18
18
  assert_file 'config/locales/devise.security_extension.fr.yml'
19
19
  assert_file 'config/locales/devise.security_extension.it.yml'
20
+ assert_file 'config/locales/devise.security_extension.ja.yml'
20
21
  assert_file 'config/locales/devise.security_extension.tr.yml'
21
22
  end
22
23
  end
@@ -3,6 +3,7 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class TestPasswordArchivable < ActiveSupport::TestCase
6
+
6
7
  setup do
7
8
  Devise.password_archiving_count = 2
8
9
  end
@@ -19,7 +20,7 @@ class TestPasswordArchivable < ActiveSupport::TestCase
19
20
 
20
21
  test 'cannot use same password' do
21
22
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
22
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password1') }
23
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
23
24
  end
24
25
 
25
26
  test 'indirectly saving associated user does not cause deprecation warning' do
@@ -37,17 +38,15 @@ class TestPasswordArchivable < ActiveSupport::TestCase
37
38
  assert_equal 0, OldPassword.count
38
39
  end
39
40
 
40
- test 'cannot use archived passwords' do
41
+ test 'cannot reuse archived passwords' do
41
42
  assert_equal 2, Devise.password_archiving_count
42
43
 
43
44
  user = User.create! email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
44
45
  assert_equal 0, OldPassword.count
45
-
46
46
  set_password(user, 'Password2')
47
47
  assert_equal 1, OldPassword.count
48
48
 
49
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password1') }
50
-
49
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
51
50
  set_password(user, 'Password3')
52
51
  assert_equal 2, OldPassword.count
53
52
 
@@ -70,8 +69,8 @@ class TestPasswordArchivable < ActiveSupport::TestCase
70
69
 
71
70
  assert set_password(user, 'Password2')
72
71
 
73
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password2') }
72
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password2') }
74
73
 
75
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password1') }
74
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
76
75
  end
77
76
  end
@@ -58,12 +58,14 @@ class TestPasswordArchivable < ActiveSupport::TestCase
58
58
 
59
59
  test 'updating a record updates the time the password was changed if the password is changed' do
60
60
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
61
+ user.update(password_changed_at: Time.now.ago(3.months))
62
+ original_password_changed_at = user.password_changed_at
61
63
  user.expire_password!
62
64
  assert user.password_change_requested?
63
65
  user.password = "NewPassword1"
64
66
  user.password_confirmation = "NewPassword1"
65
67
  user.save
66
- assert user.previous_changes.key?(:password_changed_at)
68
+ assert user.password_changed_at > original_password_changed_at
67
69
  refute user.password_change_requested?
68
70
  end
69
71
 
@@ -4,9 +4,10 @@ require 'test_helper'
4
4
  require 'rails_email_validator'
5
5
 
6
6
  class TestSecureValidatable < ActiveSupport::TestCase
7
- class User < ActiveRecord::Base
7
+ class User < ApplicationRecord
8
8
  devise :database_authenticatable, :password_archivable,
9
9
  :paranoid_verification, :password_expirable, :secure_validatable
10
+ include ::Mongoid::Mappings if DEVISE_ORM == :mongoid
10
11
  end
11
12
 
12
13
  test 'email cannot be blank' do
@@ -15,7 +16,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
15
16
 
16
17
  assert_equal(false, user.valid?)
17
18
  assert_equal([msg], user.errors.full_messages)
18
- assert_raises(ActiveRecord::RecordInvalid) do
19
+ assert_raises(ORMInvalidRecordException) do
19
20
  user.save!
20
21
  end
21
22
  end
@@ -25,7 +26,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
25
26
  user = User.create email: 'bob', password: 'passWord1', password_confirmation: 'passWord1'
26
27
  assert_equal(false, user.valid?)
27
28
  assert_equal([msg], user.errors.full_messages)
28
- assert_raises(ActiveRecord::RecordInvalid) do
29
+ assert_raises(ORMInvalidRecordException) do
29
30
  user.save!
30
31
  end
31
32
  end
@@ -35,7 +36,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
35
36
  user = User.create email: 'bob@@foo.tv', password: 'password1', password_confirmation: 'password1'
36
37
  assert_equal(false, user.valid?)
37
38
  assert_equal(msgs, user.errors.full_messages)
38
- assert_raises(ActiveRecord::RecordInvalid) { user.save! }
39
+ assert_raises(ORMInvalidRecordException) { user.save! }
39
40
  end
40
41
 
41
42
  test 'password must have capital letter' do
@@ -43,7 +44,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
43
44
  user = User.create email: 'bob@microsoft.com', password: 'password1', password_confirmation: 'password1'
44
45
  assert_equal(false, user.valid?)
45
46
  assert_equal(msgs, user.errors.full_messages)
46
- assert_raises(ActiveRecord::RecordInvalid) { user.save! }
47
+ assert_raises(ORMInvalidRecordException) { user.save! }
47
48
  end
48
49
 
49
50
  test 'password must have lowercase letter' do
@@ -51,7 +52,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
51
52
  user = User.create email: 'bob@microsoft.com', password: 'PASSWORD1', password_confirmation: 'PASSWORD1'
52
53
  assert_equal(false, user.valid?)
53
54
  assert_equal([msg], user.errors.full_messages)
54
- assert_raises(ActiveRecord::RecordInvalid) { user.save! }
55
+ assert_raises(ORMInvalidRecordException) { user.save! }
55
56
  end
56
57
 
57
58
  test 'password must have number' do
@@ -59,15 +60,15 @@ class TestSecureValidatable < ActiveSupport::TestCase
59
60
  user = User.create email: 'bob@microsoft.com', password: 'PASSword', password_confirmation: 'PASSword'
60
61
  assert_equal(false, user.valid?)
61
62
  assert_equal([msg], user.errors.full_messages)
62
- assert_raises(ActiveRecord::RecordInvalid) { user.save! }
63
+ assert_raises(ORMInvalidRecordException) { user.save! }
63
64
  end
64
65
 
65
66
  test 'password must have minimum length' do
66
- msg = 'Password is too short (minimum is 6 characters)'
67
+ msg = 'Password is too short (minimum is 7 characters)'
67
68
  user = User.create email: 'bob@microsoft.com', password: 'Pa3zZ', password_confirmation: 'Pa3zZ'
68
69
  assert_equal(false, user.valid?)
69
70
  assert_equal([msg], user.errors.full_messages)
70
- assert_raises(ActiveRecord::RecordInvalid) { user.save! }
71
+ assert_raises(ORMInvalidRecordException) { user.save! }
71
72
  end
72
73
 
73
74
  test 'duplicate email validation message is added only once' do
@@ -79,6 +80,6 @@ class TestSecureValidatable < ActiveSupport::TestCase
79
80
  SecureUser.create!(options)
80
81
  user = SecureUser.new(options)
81
82
  refute user.valid?
82
- assert_equal ['Email has already been taken'], user.errors.full_messages
83
+ assert_equal DEVISE_ORM == :active_record ? ['Email has already been taken'] : ['Email is already taken'], user.errors.full_messages
83
84
  end
84
85
  end