/
validation_uniqueness_spec.rb
223 lines (180 loc) · 6.04 KB
/
validation_uniqueness_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
describe Neo4j::ActiveNode::Validations do
before(:each) do
delete_db
clear_model_memory_caches
stub_active_node_class('Foo') do
property :name
validates_uniqueness_of :name
end
end
context 'validating uniqueness of' do
it 'should not fail if object is new' do
o = Foo.new
o.should_not have_error_on(:name)
end
it 'should not fail when new object is out of scope' do
other_clazz = UniqueClass.create do
include Neo4j::ActiveNode
property :name
property :adult
validates_uniqueness_of :name, scope: :adult
end
o = other_clazz.new('name' => 'joe', :adult => true)
o.save.should be true
o2 = other_clazz.new('name' => 'joe', :adult => false)
o2.should be_valid
end
it 'should work with i18n taken message' do
Foo.create(name: 'joe')
o = Foo.create(name: 'joe')
o.should have_error_on(:name, 'has already been taken')
end
it 'should allow to update an object' do
o = Foo.new('name' => 'joe')
o.save.should be true
o.name = 'joe'
o.valid?.should be true
o.should_not have_error_on(:name)
end
it 'should fail if object name is not unique' do
o = Foo.new('name' => 'joe')
o.save.should be true
Foo \
.stub(:first) \
.with(name: 'joe') \
.and_return(o)
o2 = Foo.new('name' => 'joe')
o2.should have_error_on(:name)
end
it 'should allow multiple blank entries if :allow_blank => true' do
other_clazz = UniqueClass.create do
include Neo4j::ActiveNode
property :name
validates_uniqueness_of :name, allow_blank: :true
end
o = other_clazz.new('name' => '')
o.save.should be true
other_clazz \
.stub(:first) \
.with(name: '') \
.and_return(o)
o2 = other_clazz.new('name' => '')
o2.should_not have_error_on(:name)
end
it 'should allow multiple nil entries if :allow_nil => true' do
other_clazz = UniqueClass.create do
include Neo4j::ActiveNode
property :name
validates_uniqueness_of :name, allow_nil: :true
end
o = other_clazz.new('name' => nil)
o.save.should be true
o2 = other_clazz.new('name' => nil)
o2.should_not have_error_on(:name)
end
it 'should allow entries that differ only in case by default' do
other_clazz = UniqueClass.create do
include Neo4j::ActiveNode
property :name
validates_uniqueness_of :name
end
o = other_clazz.new('name' => 'BLAMMO')
o.save.should be true
o2 = other_clazz.new('name' => 'blammo')
o2.should_not have_error_on(:name)
end
context 'with :case_sensitive => false' do
before do
stub_active_node_class('Foo') do
property :name
validates_uniqueness_of :name, case_sensitive: false
end
end
it 'should fail on entries that differ only in case' do
o = Foo.new('name' => 'BLAMMO')
o.save.should be true
o2 = Foo.new('name' => 'blammo')
o2.should have_error_on(:name)
end
it 'should not raise an error if value is nil' do
o = Foo.new('name' => nil)
lambda { o.valid? }.should_not raise_error
end
it 'should not raise an error if special Regexp characters used' do
o = Foo.new('name' => '?')
lambda { o.valid? }.should_not raise_error
end
it 'should not always match if Regexp wildcard used' do
o = Foo.new('name' => 'John')
o.save.should be true
o2 = Foo.new('name' => '.*')
o2.valid?.should be true
end
it 'should check for uniqueness using entire string' do
o = Foo.new('name' => 'John Doe')
o.save.should be true
o2 = Foo.new('name' => 'John')
o2.valid?.should be true
end
end
context 'scoped by a single attribute' do
before do
stub_active_node_class('Foo') do
property :name
property :scope
validates_uniqueness_of :name, scope: :scope
end
end
it 'should fail if the same name exists in the scope' do
o = Foo.new('name' => 'joe', 'scope' => 'one')
o.save.should be true
Foo \
.stub(:first) \
.with(name: 'joe', scope: 'one') \
.and_return(o)
o2 = Foo.new('name' => 'joe', 'scope' => 'one')
o2.should have_error_on(:name)
end
it 'should pass if the same name exists in a different scope' do
o = Foo.new('name' => 'joe', 'scope' => 'one')
o.save.should be true
Foo \
.stub(:first) \
.with(name: 'joe', scope: 'two') \
.and_return(nil)
o2 = Foo.new('name' => 'joe', 'scope' => 'two')
o2.should_not have_error_on(:name)
end
end
context 'scoped by a multiple attributes' do
before do
stub_active_node_class('Foo') do
property :name
property :first_scope
property :second_scope
validates_uniqueness_of :name, scope: [:first_scope, :second_scope]
end
end
it 'should fail if the same name exists in the scope' do
o = Foo.new('name' => 'joe', 'first_scope' => 'one', 'second_scope' => 'two')
o.save.should be true
Foo \
.stub(:first) \
.with(name: 'joe', first_scope: 'one', second_scope: 'two') \
.and_return(o)
o2 = Foo.new('name' => 'joe', 'first_scope' => 'one', 'second_scope' => 'two')
o2.should have_error_on(:name)
end
it 'should pass if the same name exists in a different scope' do
o = Foo.new('name' => 'joe', 'first_scope' => 'one', 'second_scope' => 'two')
o.save.should be true
Foo \
.stub(:first) \
.with(name: 'joe', first_scope: 'one', second_scope: 'one') \
.and_return(nil)
o2 = Foo.new('name' => 'joe', 'first_scope' => 'one', 'second_scope' => 'one')
o2.should_not have_error_on(:name)
end
end
end
end