1
|
|
|
<?php namespace spec\Felixkiss\UniqueWithValidator; |
2
|
|
|
|
3
|
|
|
use Illuminate\Contracts\Translation\Translator; |
4
|
|
|
use Illuminate\Validation\Factory; |
5
|
|
|
use Illuminate\Validation\PresenceVerifierInterface; |
6
|
|
|
use PhpSpec\ObjectBehavior; |
7
|
|
|
use Prophecy\Argument; |
8
|
|
|
|
9
|
|
|
class ValidatorSpec extends ObjectBehavior |
10
|
|
|
{ |
11
|
|
|
private $translator; |
12
|
|
|
private $presenceVerifier; |
13
|
|
|
private $validator; |
14
|
|
|
private $validationMessage; |
15
|
|
|
|
16
|
|
|
function let(Translator $translator, PresenceVerifierInterface $presenceVerifier) |
17
|
|
|
{ |
18
|
|
|
$this->translator = $translator; |
19
|
|
|
$this->presenceVerifier = $presenceVerifier; |
20
|
|
|
|
21
|
|
|
$this->translator->trans(Argument::cetera())->willReturnArgument(0); |
22
|
|
|
$this->setValidationMessage('This combination of :fields already exists.'); |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
function it_is_initializable() |
26
|
|
|
{ |
27
|
|
|
$this->shouldHaveType('Felixkiss\UniqueWithValidator\Validator'); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
View Code Duplication |
function it_passes_validation_if_presence_verifier_reports_no_existing_database_rows() |
|
|
|
|
31
|
|
|
{ |
32
|
|
|
$this->presenceVerifier->getCount(Argument::cetera())->willReturn(0); |
33
|
|
|
|
34
|
|
|
$this->validateData( |
35
|
|
|
['first_name' => 'unique_with:users,last_name'], |
36
|
|
|
[ |
37
|
|
|
'first_name' => 'Foo', |
38
|
|
|
'last_name' => 'Bar', |
39
|
|
|
] |
40
|
|
|
)->shouldReturn(true); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
View Code Duplication |
function it_fails_validation_if_presence_verifier_reports_existing_database_rows() |
|
|
|
|
44
|
|
|
{ |
45
|
|
|
$this->presenceVerifier->getCount(Argument::cetera())->willReturn(1); |
46
|
|
|
|
47
|
|
|
$this->validateData( |
48
|
|
|
['first_name' => 'unique_with:users,last_name'], |
49
|
|
|
[ |
50
|
|
|
'first_name' => 'Foo', |
51
|
|
|
'last_name' => 'Bar', |
52
|
|
|
] |
53
|
|
|
)->shouldReturn(false); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
function it_checks_presence_of_a_simple_two_field_combination_correctly() |
57
|
|
|
{ |
58
|
|
|
$this->validateData( |
59
|
|
|
['first_name' => 'unique_with:users,last_name'], |
60
|
|
|
[ |
61
|
|
|
'first_name' => 'Foo', |
62
|
|
|
'last_name' => 'Bar', |
63
|
|
|
] |
64
|
|
|
); |
65
|
|
|
|
66
|
|
|
$this->presenceVerifier->getCount( |
67
|
|
|
'users', |
68
|
|
|
'first_name', |
69
|
|
|
'Foo', |
70
|
|
|
null, |
71
|
|
|
null, |
72
|
|
|
['last_name' => 'Bar'] |
73
|
|
|
)->shouldHaveBeenCalled(); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
View Code Duplication |
function it_reads_parameters_without_explicit_column_names() |
|
|
|
|
77
|
|
|
{ |
78
|
|
|
$this->validateData( |
79
|
|
|
['first_name' => 'unique_with:users,middle_name,last_name'], |
80
|
|
|
[ |
81
|
|
|
'first_name' => 'Foo', |
82
|
|
|
'middle_name' => 'Bar', |
83
|
|
|
'last_name' => 'Baz', |
84
|
|
|
] |
85
|
|
|
); |
86
|
|
|
|
87
|
|
|
$this->presenceVerifier->getCount( |
88
|
|
|
'users', |
89
|
|
|
'first_name', |
90
|
|
|
'Foo', |
91
|
|
|
null, |
92
|
|
|
null, |
93
|
|
|
['middle_name' => 'Bar', 'last_name' => 'Baz'] |
94
|
|
|
)->shouldHaveBeenCalled(); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
View Code Duplication |
function it_reads_parameters_with_explicit_column_names() |
|
|
|
|
98
|
|
|
{ |
99
|
|
|
$this->validateData( |
100
|
|
|
['first_name' => 'unique_with:users,first_name = name,middle_name = mid_name,last_name=sur_name'], |
101
|
|
|
[ |
102
|
|
|
'first_name' => 'Foo', |
103
|
|
|
'middle_name' => 'Bar', |
104
|
|
|
'last_name' => 'Baz', |
105
|
|
|
] |
106
|
|
|
); |
107
|
|
|
|
108
|
|
|
$this->presenceVerifier->getCount( |
109
|
|
|
'users', |
110
|
|
|
'name', |
111
|
|
|
'Foo', |
112
|
|
|
null, |
113
|
|
|
null, |
114
|
|
|
['mid_name' => 'Bar', 'sur_name' => 'Baz'] |
115
|
|
|
)->shouldHaveBeenCalled(); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
View Code Duplication |
function it_reads_implicit_integer_ignore_id_with_default_column_name() |
|
|
|
|
119
|
|
|
{ |
120
|
|
|
$this->validateData( |
121
|
|
|
['first_name' => 'unique_with:users,last_name,1'], |
122
|
|
|
[ |
123
|
|
|
'first_name' => 'Foo', |
124
|
|
|
'last_name' => 'Bar', |
125
|
|
|
] |
126
|
|
|
); |
127
|
|
|
|
128
|
|
|
$this->presenceVerifier->getCount( |
129
|
|
|
'users', |
130
|
|
|
'first_name', |
131
|
|
|
'Foo', |
132
|
|
|
1, |
133
|
|
|
null, |
134
|
|
|
['last_name' => 'Bar'] |
135
|
|
|
)->shouldHaveBeenCalled(); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
View Code Duplication |
function it_reads_implicit_integer_ignore_id_with_custom_column_name() |
|
|
|
|
139
|
|
|
{ |
140
|
|
|
$this->validateData( |
141
|
|
|
['first_name' => 'unique_with:users,first_name,last_name,1 = UserKey'], |
142
|
|
|
[ |
143
|
|
|
'first_name' => 'Foo', |
144
|
|
|
'last_name' => 'Bar', |
145
|
|
|
] |
146
|
|
|
); |
147
|
|
|
|
148
|
|
|
$this->presenceVerifier->getCount( |
149
|
|
|
'users', |
150
|
|
|
'first_name', |
151
|
|
|
'Foo', |
152
|
|
|
1, |
153
|
|
|
'UserKey', |
154
|
|
|
['last_name' => 'Bar'] |
155
|
|
|
)->shouldHaveBeenCalled(); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
View Code Duplication |
function it_reads_explicit_ignore_id_with_default_column_name() |
|
|
|
|
159
|
|
|
{ |
160
|
|
|
$this->validateData( |
161
|
|
|
['first_name' => 'unique_with:users,last_name,ignore:1'], |
162
|
|
|
[ |
163
|
|
|
'first_name' => 'Foo', |
164
|
|
|
'last_name' => 'Bar', |
165
|
|
|
] |
166
|
|
|
); |
167
|
|
|
|
168
|
|
|
$this->presenceVerifier->getCount( |
169
|
|
|
'users', |
170
|
|
|
'first_name', |
171
|
|
|
'Foo', |
172
|
|
|
1, |
173
|
|
|
null, |
174
|
|
|
['last_name' => 'Bar'] |
175
|
|
|
)->shouldHaveBeenCalled(); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
View Code Duplication |
function it_reads_explicit_ignore_id_with_custom_column_name() |
|
|
|
|
179
|
|
|
{ |
180
|
|
|
$this->validateData( |
181
|
|
|
['first_name' => 'unique_with:users,first_name,last_name,ignore:1 = UserKey'], |
182
|
|
|
[ |
183
|
|
|
'first_name' => 'Foo', |
184
|
|
|
'last_name' => 'Bar', |
185
|
|
|
] |
186
|
|
|
); |
187
|
|
|
|
188
|
|
|
$this->presenceVerifier->getCount( |
189
|
|
|
'users', |
190
|
|
|
'first_name', |
191
|
|
|
'Foo', |
192
|
|
|
1, |
193
|
|
|
'UserKey', |
194
|
|
|
['last_name' => 'Bar'] |
195
|
|
|
)->shouldHaveBeenCalled(); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
function it_replaces_fields_in_error_message_correctly() |
199
|
|
|
{ |
200
|
|
|
$this->presenceVerifier->getCount(Argument::cetera())->willReturn(1); |
201
|
|
|
$this->translator->trans('validation.attributes')->shouldBeCalled()->willReturn([]); |
202
|
|
|
|
203
|
|
|
$this->validateData( |
204
|
|
|
['first_name' => 'unique_with:users,first_name,last_name'], |
205
|
|
|
[ |
206
|
|
|
'first_name' => 'Foo', |
207
|
|
|
'last_name' => 'Bar', |
208
|
|
|
] |
209
|
|
|
); |
210
|
|
|
|
211
|
|
|
$expectedErrorMessage = str_replace(':fields', 'first name, last name', $this->getValidationMessage()); |
212
|
|
|
expect($this->validator->getMessageBag()->toArray())->toBe(['first_name' => [$expectedErrorMessage]]); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
function it_uses_custom_error_message_coming_from_translator() |
216
|
|
|
{ |
217
|
|
|
$customErrorMessage = 'Error: Found combination of :fields in database.'; |
218
|
|
|
|
219
|
|
|
$this->presenceVerifier->getCount(Argument::cetera())->willReturn(1); |
220
|
|
|
$this->translator->trans('uniquewith-validator::validation.unique_with')->shouldBeCalled() |
221
|
|
|
->willReturn($customErrorMessage); |
222
|
|
|
$this->translator->trans('validation.attributes')->shouldBeCalled()->willReturn([]); |
223
|
|
|
|
224
|
|
|
$this->validateData( |
225
|
|
|
['first_name' => 'unique_with:users,first_name,middle_name,last_name'], |
226
|
|
|
[ |
227
|
|
|
'first_name' => 'Foo', |
228
|
|
|
'middle_name' => 'Bar', |
229
|
|
|
'last_name' => 'Baz', |
230
|
|
|
] |
231
|
|
|
); |
232
|
|
|
|
233
|
|
|
$expectedErrorMessage = str_replace(':fields', 'first name, middle name, last name', $customErrorMessage); |
234
|
|
|
expect($this->validator->getMessageBag()->toArray())->toBe(['first_name' => [$expectedErrorMessage]]); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
function it_uses_custom_attribute_names_coming_from_translator() |
238
|
|
|
{ |
239
|
|
|
$this->presenceVerifier->getCount(Argument::cetera())->willReturn(1); |
240
|
|
|
$this->translator->trans('validation.attributes')->shouldBeCalled()->willReturn([ |
241
|
|
|
'first_name' => 'Vorname', |
242
|
|
|
'last_name' => 'Nachname', |
243
|
|
|
]); |
244
|
|
|
|
245
|
|
|
$this->validateData( |
246
|
|
|
['first_name' => 'unique_with:users,first_name,last_name'], |
247
|
|
|
[ |
248
|
|
|
'first_name' => 'Foo', |
249
|
|
|
'last_name' => 'Bar', |
250
|
|
|
] |
251
|
|
|
); |
252
|
|
|
|
253
|
|
|
$expectedErrorMessage = str_replace(':fields', 'Vorname, Nachname', $this->getValidationMessage()); |
254
|
|
|
expect($this->validator->getMessageBag()->toArray())->toBe(['first_name' => [$expectedErrorMessage]]); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
protected function validateData(array $rules = [], array $data = []) |
258
|
|
|
{ |
259
|
|
|
$result = null; |
260
|
|
|
|
261
|
|
|
$message = $this->translator->getWrappedObject()->trans('uniquewith-validator::validation.unique_with'); |
262
|
|
|
$factory = new Factory($this->translator->getWrappedObject()); |
263
|
|
|
$factory->extend('unique_with', function() use (&$result) { |
264
|
|
|
$result = call_user_func_array([$this, 'validateUniqueWith'], func_get_args()); |
265
|
|
|
}, $message); |
266
|
|
|
$factory->replacer('unique_with', function() { |
267
|
|
|
$translator = $this->translator->getWrappedObject(); |
|
|
|
|
268
|
|
|
return call_user_func_array([$this, 'replaceUniqueWith'], array_merge(func_get_args(), [$translator]))->getWrappedObject(); |
269
|
|
|
}); |
270
|
|
|
$factory->setPresenceVerifier($this->presenceVerifier->getWrappedObject()); |
|
|
|
|
271
|
|
|
|
272
|
|
|
$validator = $factory->make($data, $rules); |
273
|
|
|
$validator->passes(); |
274
|
|
|
|
275
|
|
|
$this->validator = $validator; |
276
|
|
|
|
277
|
|
|
return $result; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
protected function setValidationMessage($message) |
281
|
|
|
{ |
282
|
|
|
$this->validationMessage = $message; |
283
|
|
|
$this->translator->trans('uniquewith-validator::validation.unique_with') |
284
|
|
|
->willReturn($message); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
protected function getValidationMessage() |
288
|
|
|
{ |
289
|
|
|
return $this->validationMessage; |
290
|
|
|
} |
291
|
|
|
} |
292
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.