2014-10-27 00:51:42 +00:00
|
|
|
require 'unit_spec_helper'
|
2009-01-21 01:20:30 +00:00
|
|
|
|
2014-12-24 21:37:04 +00:00
|
|
|
describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model do
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'a model with a presence validation' do
|
|
|
|
it 'accepts' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence).to matcher
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'does not override the default message with a blank' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence).to matcher.with_message(nil)
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'a model without a presence validation' do
|
|
|
|
it 'rejects' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(define_model(:example, attr: :string).new).not_to matcher
|
2011-01-24 16:19:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'an ActiveModel class with a presence validation' do
|
|
|
|
it 'accepts' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(active_model_validating_presence).to matcher
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'does not override the default message with a blank' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(active_model_validating_presence).to matcher.with_message(nil)
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'an ActiveModel class without a presence validation' do
|
|
|
|
it 'rejects' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(active_model).not_to matcher
|
2013-05-24 13:38:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'provides the correct failure message' do
|
Tweak allow_value failure_message
This commit changes the failure message that `allow_value` generates so
that it reads a bit nicer.
When a call to #valid? resulted in validation messages, `allow_value`
formerly failed with this message:
Expected errors to include "the message" when attr is set to "some value", got errors: ["another message (attribute: \"attr\", value: \"some value\")", "some other message (attribute: \"attr2\", value: \"some other value\")"]
Now it fails with this message:
Expected errors to include "the message" when attr is set to "some value",
got errors:
* "another message" (attribute: attr, value: "some value")
* "some other message" (attribute: attr2, value: "some other value")
Similarly, when a call to #valid resulted in an exception, `allow_value`
formerly failed with this message:
Expected errors to include "the message" when attr is set to "some value", got: some message
Now it fails with this message:
Expected errors to include "the message" when attr is set to "some value",
got: "some message"
2014-10-12 02:19:23 +00:00
|
|
|
message = %{Expected errors to include "can't be blank" when attr is set to nil,\ngot no errors}
|
2013-05-24 13:38:08 +00:00
|
|
|
|
2014-01-17 22:01:43 +00:00
|
|
|
expect { expect(active_model).to matcher }.to fail_with_message(message)
|
2011-01-24 16:19:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'a has_many association with a presence validation' do
|
|
|
|
it 'requires the attribute to be set' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(has_many_children(presence: true)).to validate_presence_of(:children)
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'a has_many association without a presence validation' do
|
|
|
|
it 'does not require the attribute to be set' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(has_many_children(presence: false)).
|
|
|
|
not_to validate_presence_of(:children)
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'a required has_and_belongs_to_many association' do
|
2010-12-13 22:28:59 +00:00
|
|
|
before do
|
2009-01-24 21:23:11 +00:00
|
|
|
define_model :child
|
|
|
|
@model = define_model :parent do
|
2009-01-21 01:20:30 +00:00
|
|
|
has_and_belongs_to_many :children
|
|
|
|
validates_presence_of :children
|
|
|
|
end.new
|
2014-01-17 20:20:44 +00:00
|
|
|
create_table 'children_parents', id: false do |t|
|
2011-09-12 10:25:31 +00:00
|
|
|
t.integer :child_id
|
|
|
|
t.integer :parent_id
|
|
|
|
end
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'accepts' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(@model).to validate_presence_of(:children)
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'an optional has_and_belongs_to_many association' do
|
2010-12-13 22:28:59 +00:00
|
|
|
before do
|
2009-01-24 21:23:11 +00:00
|
|
|
define_model :child
|
|
|
|
@model = define_model :parent do
|
2009-01-21 01:20:30 +00:00
|
|
|
has_and_belongs_to_many :children
|
|
|
|
end.new
|
2014-01-17 20:20:44 +00:00
|
|
|
create_table 'children_parents', id: false do |t|
|
2011-09-12 10:25:31 +00:00
|
|
|
t.integer :child_id
|
|
|
|
t.integer :parent_id
|
|
|
|
end
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'rejects' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(@model).not_to validate_presence_of(:children)
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-29 00:02:52 +00:00
|
|
|
context "an i18n translation containing %{attribute} and %{model}" do
|
|
|
|
before do
|
|
|
|
stub_translation(
|
|
|
|
"activerecord.errors.messages.blank",
|
|
|
|
"Please enter a %{attribute} for your %{model}")
|
|
|
|
end
|
|
|
|
|
|
|
|
after { I18n.backend.reload! }
|
|
|
|
|
|
|
|
it "does not raise an exception" do
|
|
|
|
expect {
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence).to validate_presence_of(:attr)
|
2013-03-29 00:02:52 +00:00
|
|
|
}.to_not raise_exception
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
if active_model_3_2?
|
|
|
|
context 'a strictly required attribute' do
|
|
|
|
it 'accepts when the :strict options match' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence(strict: true)).to matcher.strict
|
2012-09-12 00:53:21 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'rejects when the :strict options do not match' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence(strict: false)).not_to matcher.strict
|
2012-09-12 00:53:21 +00:00
|
|
|
end
|
|
|
|
end
|
2012-12-20 05:04:27 +00:00
|
|
|
|
|
|
|
it 'does not override the default message with a blank' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence(strict: true)).
|
|
|
|
to matcher.strict.with_message(nil)
|
2012-12-20 05:04:27 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-07-02 02:16:32 +00:00
|
|
|
context "an attribute with a context-dependent validation" do
|
|
|
|
context "without the validation context" do
|
|
|
|
it "does not match" do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence(on: :customisable)).not_to matcher
|
2013-07-02 02:16:32 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "with the validation context" do
|
|
|
|
it "matches" do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_presence(on: :customisable)).to matcher.on(:customisable)
|
2013-07-02 02:16:32 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-28 10:08:06 +00:00
|
|
|
context 'an active_resource model' do
|
|
|
|
context 'with the validation context' do
|
|
|
|
it 'does not raise an exception' do
|
|
|
|
expect {
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(active_resource_model).to validate_presence_of(:attr)
|
2013-08-28 10:08:06 +00:00
|
|
|
}.to_not raise_exception
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-11-22 20:46:59 +00:00
|
|
|
if rails_4_x?
|
|
|
|
context 'against a pre-set password in a model that has_secure_password' do
|
2014-04-16 06:24:02 +00:00
|
|
|
it 'raises a CouldNotSetPasswordError exception' do
|
2013-11-22 20:46:59 +00:00
|
|
|
user_class = define_model :user, password_digest: :string do
|
2014-04-16 06:24:02 +00:00
|
|
|
has_secure_password validations: false
|
2013-11-22 20:46:59 +00:00
|
|
|
validates_presence_of :password
|
|
|
|
end
|
|
|
|
|
|
|
|
user = user_class.new
|
|
|
|
user.password = 'something'
|
|
|
|
|
|
|
|
error_class = Shoulda::Matchers::ActiveModel::CouldNotSetPasswordError
|
2014-04-16 06:24:02 +00:00
|
|
|
expect do
|
2013-11-22 20:46:59 +00:00
|
|
|
expect(user).to validate_presence_of(:password)
|
2014-04-16 06:24:02 +00:00
|
|
|
end.to raise_error(error_class)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-09-30 04:28:59 +00:00
|
|
|
context 'when the attribute typecasts nil to an empty array' do
|
|
|
|
it 'accepts' do
|
|
|
|
model = define_active_model_class :example do
|
|
|
|
attr_reader :foo
|
|
|
|
|
|
|
|
def foo=(value)
|
|
|
|
@foo = Array.wrap(value)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(model.new).to validate_presence_of(:foo)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
def matcher
|
|
|
|
validate_presence_of(:attr)
|
|
|
|
end
|
|
|
|
|
|
|
|
def validating_presence(options = {})
|
2014-01-17 20:20:44 +00:00
|
|
|
define_model :example, attr: :string do
|
2012-12-20 05:04:27 +00:00
|
|
|
validates_presence_of :attr, options
|
|
|
|
end.new
|
2012-09-12 00:53:21 +00:00
|
|
|
end
|
|
|
|
|
2013-05-24 13:38:08 +00:00
|
|
|
def active_model(&block)
|
2014-01-17 20:20:44 +00:00
|
|
|
define_active_model_class('Example', accessors: [:attr], &block).new
|
2013-05-24 13:38:08 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
def active_model_validating_presence
|
2013-05-24 13:38:08 +00:00
|
|
|
active_model { validates_presence_of :attr }
|
2012-12-20 05:04:27 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def has_many_children(options = {})
|
|
|
|
define_model :child
|
|
|
|
define_model :parent do
|
|
|
|
has_many :children
|
|
|
|
if options[:presence]
|
|
|
|
validates_presence_of :children
|
|
|
|
end
|
|
|
|
end.new
|
|
|
|
end
|
2013-08-28 10:08:06 +00:00
|
|
|
|
|
|
|
def active_resource_model
|
2014-01-17 20:20:44 +00:00
|
|
|
define_active_resource_class :foo, attr: :string do
|
2013-08-28 10:08:06 +00:00
|
|
|
validates_presence_of :attr
|
|
|
|
end.new
|
|
|
|
end
|
2009-01-21 01:20:30 +00:00
|
|
|
end
|