mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Fixes validate_uniqueness_of when scope is taken
Re-implement how to get previous value in order to test validate_uniquenes_of matcher, after the scope changes. This way, new value should not be taken by a previous record. Fixes #207.
This commit is contained in:
parent
2b9130b462
commit
2065a654e6
3 changed files with 41 additions and 5 deletions
3
NEWS.md
3
NEWS.md
|
@ -2,6 +2,9 @@
|
|||
|
||||
* Fix `have_and_belong_to_many` matcher issue for Rails 4.
|
||||
|
||||
* Fix `validate_uniqueness_of.scoped_to` issue when the scoped field is already
|
||||
taken (#207).
|
||||
|
||||
# v 2.1.0
|
||||
|
||||
* Add missing `failure_message_for_should_not` implementations to
|
||||
|
|
|
@ -156,15 +156,13 @@ module Shoulda # :nodoc:
|
|||
@existing_record = create_record_in_database
|
||||
end
|
||||
|
||||
# TODO: There is a chance that we could change the scoped field
|
||||
# to a value that's already taken. An alternative implementation
|
||||
# could actually find all values for scope and create a unique
|
||||
def validate_after_scope_change?
|
||||
if @options[:scopes].blank?
|
||||
true
|
||||
else
|
||||
all_records = @subject.class.all
|
||||
@options[:scopes].all? do |scope|
|
||||
previous_value = existing_record.send(scope)
|
||||
previous_value = all_records.map(&scope).max
|
||||
|
||||
# Assume the scope is a foreign key if the field is nil
|
||||
previous_value ||= correct_type_for_column(@subject.class.columns_hash[scope.to_s])
|
||||
|
|
|
@ -118,6 +118,13 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|||
should matcher.scoped_to(:scope1)
|
||||
end
|
||||
|
||||
context 'with an existing record that conflicts with scope.next' do
|
||||
it 'accepts' do
|
||||
validating_scoped_uniqueness_with_conflicting_next(:scope1, :date, :scope1 => Date.today).
|
||||
should matcher.scoped_to(:scope1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when too narrow of a scope is specified' do
|
||||
it 'rejects' do
|
||||
validating_scoped_uniqueness([:scope1, :scope2], :date, :scope1 => Date.today, :scope2 => Date.today).
|
||||
|
@ -132,6 +139,13 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|||
should matcher.scoped_to(:scope1)
|
||||
end
|
||||
|
||||
context 'with an existing record that conflicts with scope.next' do
|
||||
it 'accepts' do
|
||||
validating_scoped_uniqueness_with_conflicting_next(:scope1, :datetime, :scope1 => DateTime.now).
|
||||
should matcher.scoped_to(:scope1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a nil value' do
|
||||
it 'accepts' do
|
||||
validating_scoped_uniqueness([:scope1], :datetime, :scope1 => nil).
|
||||
|
@ -145,11 +159,22 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|||
should_not matcher.scoped_to(:scope1, :scope2, :other)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an existing record that conflicts with scope.next' do
|
||||
it 'accepts' do
|
||||
validating_scoped_uniqueness_with_conflicting_next(:scope1, :scope1 => 1).
|
||||
should matcher.scoped_to(:scope1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_existing_record(attributes = {})
|
||||
@existing ||= create_record(attributes)
|
||||
end
|
||||
|
||||
def create_record(attributes = {})
|
||||
default_attributes = {:attr => 'value', :scope1 => 1, :scope2 => 2, :other => 3}
|
||||
@existing ||= Example.create!(default_attributes.merge(attributes))
|
||||
Example.create!(default_attributes.merge(attributes))
|
||||
end
|
||||
|
||||
def define_scoped_model(scope, scope_attr_type = :integer)
|
||||
|
@ -166,6 +191,16 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|||
create_existing_record(attributes)
|
||||
model
|
||||
end
|
||||
|
||||
def validating_scoped_uniqueness_with_conflicting_next(*args)
|
||||
attributes = args.extract_options!
|
||||
model = define_scoped_model(*args).new
|
||||
2.times do
|
||||
attributes[:scope1] = attributes[:scope1].next
|
||||
create_record(attributes)
|
||||
end
|
||||
model
|
||||
end
|
||||
end
|
||||
|
||||
context 'a model with a case-sensitive uniqueness validation on a string attribute and an existing record' do
|
||||
|
|
Loading…
Reference in a new issue