Add have_secure_password matcher

This commit is contained in:
Matt Daubert 2013-08-18 13:17:19 -04:00 committed by Elliot Winkler
parent ce3d1e8251
commit 5815d38fa0
11 changed files with 105 additions and 0 deletions

View File

@ -6,6 +6,7 @@ if RUBY_VERSION < '2.0'
appraise '3.1' do
gem 'rails', '~> 3.1.8'
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'jquery-rails'
gem 'sass-rails'
gem 'strong_parameters'
@ -14,6 +15,7 @@ end
appraise '3.2' do
gem 'rails', '~> 3.2.13'
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'jquery-rails'
gem 'sass-rails'
gem 'strong_parameters'
@ -21,6 +23,7 @@ end
appraise '4.0' do
gem 'rails', '4.0.0'
gem 'bcrypt-ruby', '~> 3.0.0' #FIXME: This should be ~> 3.1.0 for Rails 4.0
gem 'jquery-rails'
gem 'sass-rails', '~> 4.0.0'

View File

@ -42,6 +42,7 @@ describe User do
it { should allow_value("a@b.com").for(:email) }
it { should ensure_inclusion_of(:age).in_range(1..100) }
it { should_not allow_mass_assignment_of(:password) }
it { should have_secure_password }
end
```

View File

@ -10,6 +10,7 @@ gem "jdbc-sqlite3", :platform=>:jruby
gem "jruby-openssl", :platform=>:jruby
gem "therubyrhino", :platform=>:jruby
gem "rails", "~> 3.1.8"
gem "bcrypt-ruby", "~> 3.0.0"
gem "jquery-rails"
gem "sass-rails"
gem "strong_parameters"

View File

@ -43,6 +43,7 @@ GEM
childprocess (~> 0.3.6)
cucumber (>= 1.1.1)
rspec-expectations (>= 2.7.0)
bcrypt-ruby (3.0.1)
bourne (1.4.0)
mocha (~> 0.13.2)
builder (3.0.4)
@ -143,6 +144,7 @@ DEPENDENCIES
activerecord-jdbcsqlite3-adapter
appraisal (~> 0.4)
aruba
bcrypt-ruby (~> 3.0.0)
bourne (~> 1.3)
bundler (~> 1.1)
cucumber (~> 1.1)

View File

@ -10,6 +10,7 @@ gem "jdbc-sqlite3", :platform=>:jruby
gem "jruby-openssl", :platform=>:jruby
gem "therubyrhino", :platform=>:jruby
gem "rails", "~> 3.2.13"
gem "bcrypt-ruby", "~> 3.0.0"
gem "jquery-rails"
gem "sass-rails"
gem "strong_parameters"

View File

@ -42,6 +42,7 @@ GEM
childprocess (~> 0.3.6)
cucumber (>= 1.1.1)
rspec-expectations (>= 2.7.0)
bcrypt-ruby (3.0.1)
bourne (1.4.0)
mocha (~> 0.13.2)
builder (3.0.4)
@ -141,6 +142,7 @@ DEPENDENCIES
activerecord-jdbcsqlite3-adapter
appraisal (~> 0.4)
aruba
bcrypt-ruby (~> 3.0.0)
bourne (~> 1.3)
bundler (~> 1.1)
cucumber (~> 1.1)

View File

@ -10,6 +10,7 @@ gem "jdbc-sqlite3", :platform=>:jruby
gem "jruby-openssl", :platform=>:jruby
gem "therubyrhino", :platform=>:jruby
gem "rails", "4.0.0"
gem "bcrypt-ruby", "~> 3.0.0"
gem "jquery-rails"
gem "sass-rails", "~> 4.0.0"
gem "protected_attributes"

View File

@ -40,6 +40,7 @@ GEM
cucumber (>= 1.1.1)
rspec-expectations (>= 2.7.0)
atomic (1.1.13)
bcrypt-ruby (3.0.1)
bourne (1.5.0)
mocha (>= 0.13.2, < 0.15)
builder (3.1.4)
@ -135,6 +136,7 @@ DEPENDENCIES
activerecord-jdbcsqlite3-adapter
appraisal (~> 0.4)
aruba
bcrypt-ruby (~> 3.0.0)
bourne (~> 1.3)
bundler (~> 1.1)
cucumber (~> 1.1)

View File

@ -17,6 +17,7 @@ require 'shoulda/matchers/active_model/validate_confirmation_of_matcher'
require 'shoulda/matchers/active_model/validate_numericality_of_matcher'
require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
require 'shoulda/matchers/active_model/errors'
require 'shoulda/matchers/active_model/have_secure_password_matcher'
module Shoulda

View File

@ -0,0 +1,71 @@
module Shoulda # :nodoc:
module Matchers
module ActiveModel # :nodoc:
# Ensures that the model exhibits behavior added by has_secure_password.
#
# Example:
# it { should have_secure_password }
def have_secure_password
HaveSecurePasswordMatcher.new
end
class HaveSecurePasswordMatcher # :nodoc:
attr_reader :failure_message_for_should
CORRECT_PASSWORD = "aBcDe12345"
INCORRECT_PASSWORD = "password"
EXPECTED_METHODS = [
:authenticate,
:password=,
:password_confirmation=,
:password_digest,
:password_digest=,
]
MESSAGES = {
authenticated_incorrect_password: "expected %{subject} to not authenticate an incorrect password",
did_not_authenticate_correct_password: "expected %{subject} to authenticate the correct password",
method_not_found: "expected %{subject} to respond to %{methods}"
}
def description
"have a secure password"
end
def matches?(subject)
@subject = subject
if failure = validate
key, params = failure
@failure_message_for_should = MESSAGES[key] % { subject: subject.class }.merge(params)
end
failure.nil?
end
private
attr_reader :subject
def validate
missing_methods = EXPECTED_METHODS.select {|m| !subject.respond_to?(m) }
if missing_methods.present?
[:method_not_found, { methods: missing_methods.to_sentence }]
else
subject.password = CORRECT_PASSWORD
subject.password_confirmation = CORRECT_PASSWORD
if not subject.authenticate(CORRECT_PASSWORD)
[:did_not_authenticate_correct_password, {}]
elsif subject.authenticate(INCORRECT_PASSWORD)
[:authenticated_incorrect_password, {}]
end
end
end
end
end
end
end

View File

@ -0,0 +1,20 @@
require 'spec_helper'
describe Shoulda::Matchers::ActiveModel::HaveSecurePasswordMatcher do
if active_model_3_1?
it 'matches when the subject configures has_secure_password with default options' do
working_model = define_model(:example, password_digest: :string) { has_secure_password }
expect(working_model.new).to have_secure_password
end
it 'does not match when the subject does not authenticate a password' do
no_secure_password = define_model(:example)
expect(no_secure_password.new).not_to have_secure_password
end
it 'does not match when the subject is missing the password_digest attribute' do
no_digest_column = define_model(:example) { has_secure_password }
expect(no_digest_column.new).not_to have_secure_password
end
end
end