8000 rework form validator tests · symfony/symfony@2fbf8f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2fbf8f5

Browse files
committed
rework form validator tests
1 parent 9f3b43a commit 2fbf8f5

File tree

3 files changed

+315
-304
lines changed

3 files changed

+315
-304
lines changed
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Form\AbstractType;
16+
use Symfony\Component\Form\Extension\Core\Type\FormType;
17+
use Symfony\Component\Form\Extension\Core\Type\TextType;
18+
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
19+
use Symfony\Component\Form\FormBuilderInterface;
20+
use Symfony\Component\Form\FormFactoryBuilder;
21+
use Symfony\Component\Form\Test\ 8000 ForwardCompatTestTrait;
22+
use Symfony\Component\OptionsResolver\OptionsResolver;
23+
use Symfony\Component\Validator\Constraints\Collection;
24+
use Symfony\Component\Validator\Constraints\GroupSequence;
25+
use Symfony\Component\Validator\Constraints\Length;
26+
use Symfony\Component\Validator\Constraints\NotBlank;
27+
use Symfony\Component\Validator\Mapping\ClassMetadata;
28+
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
29+
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
30+
use Symfony\Component\Validator\Validation;
31+
32+
class FormValidatorFunctionalTest extends TestCase
33+
{
34+
use ForwardCompatTestTrait;
35+
36+
private $validator;
37+
private $formFactory;
38+
39+
private function doSetUp()
40+
{
41+
$this->validator = Validation::createValidatorBuilder()
42+
->setMetadataFactory(new LazyLoadingMetadataFactory(new StaticMethodLoader()))
43+
->getValidator();
44+
$this->formFactory = (new FormFactoryBuilder())
45+
->addExtension(new ValidatorExtension($this->validator))
46+
->getFormFactory();
47+
}
48+
49+
public function testDataConstraintsInvalidateFormEvenIfFieldIsNotSubmitted()
50+
{
51+
$form = $this->formFactory->create(FooType::class);
52+
$form->submit(['baz' => 'foobar'], false);
53+
54+
$this->assertTrue($form->isSubmitted());
55+
$this->assertFalse($form->isValid());
56+
$this->assertFalse($form->get('bar')->isSubmitted());
57+
$this->assertCount(1, $form->get('bar')->getErrors());
58+
}
59+
60+
public function testFieldConstraintsDoNotInvalidateFormIfFieldIsNotSubmitted()
61+
{
62+
$form = $this->formFactory->create(FooType::class);
63+
$form->submit(['bar' => 'foobar'], false);
64+
65+
$this->assertTrue($form->isSubmitted());
66+
$this->assertTrue($form->isValid());
67+
}
68+
69+
public function testFieldConstraintsInvalidateFormIfFieldIsSubmitted()
70+
{
71+
$form = $this->formFactory->create(FooType::class);
72+
$form->submit(['bar' => 'foobar', 'baz' => ''], false);
73+
74+
$this->assertTrue($form->isSubmitted());
75+
$this->assertFalse($form->isValid());
76+
$this->assertTrue($form->get('bar')->isSubmitted());
77+
$this->assertTrue($form->get('bar')->isValid());
78+
$this->assertTrue($form->get('baz')->isSubmitted());
79+
$this->assertFalse($form->get('baz')->isValid());
80+
}
81+
82+
public function testNonCompositeConstraintValidatedOnce()
83+
{
84+
$form = $this->formFactory->create(TextType::class, null, [
85+
'constraints' => [new NotBlank(['groups' => ['foo', 'bar']])],
86+
'validation_groups' => ['foo', 'bar'],
87+
]);
88+
$form->submit('');
89+
90+
$violations = $this->validator->validate($form);
91+
92+
$this->assertCount(1, $violations);
93+
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
94+
$this->assertSame('data', $violations[0]->getPropertyPath());
95+
}
96+
97+
public function testCompositeConstraintValidatedInEachGroup()
98+
{
99+
$form = $this->formFactory->create(FormType::class, null, [
100+
'constraints' => [
101+
new Collection([
102+
'field1' => new NotBlank([
103+
'groups' => ['field1'],
104+
]),
105+
'field2' => new NotBlank([
106+
'groups' => ['field2'],
107+
]),
108+
]),
109+
],
110+
'validation_groups' => ['field1', 'field2'],
111+
]);
112+
$form->add('field1');
113+
$form->add('field2');
114+
$form->submit([
115+
'field1' => '',
116+
'field2' => '',
117+
]);
118+
119+
$violations = $this->validator->validate($form);
120+
121+
$this->assertCount(2, $violations);
122+
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
123+
$this->assertSame('data[field1]', $violations[0]->getPropertyPath());
124+
$this->assertSame('This value should not be blank.', $violations[1]->getMessage());
125+
$this->assertSame('data[field2]', $violations[1]->getPropertyPath());
126+
}
127+
128+
public function testCompositeConstraintValidatedInSequence()
129+
{
130+
$form = $this->formFactory->create(FormType::class, null, [
131+
'constraints' => [
132+
new Collection([
133+
'field1' => new NotBlank([
134+
'groups' => ['field1'],
135+
]),
136+
'field2' => new NotBlank([
137+
'groups' => ['field2'],
138+
]),
139+
]),
140+
],
141+
'validation_groups' => new GroupSequence(['field1', 'field2']),
142+
]);
143+
$form->add('field1');
144+
$form->add('field2');
145+
146+
$form->submit([
147+
'field1' => '',
148+
'field2' => '',
149+
]);
150+
151+
$violations = $this->validator->validate($form);
152+
153+
$this->assertCount(1, $violations);
154+
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
155+
$this->assertSame('data[field1]', $violations[0]->getPropertyPath());
156+
}
157+
158+
public function testFieldsValidateInSequence()
159+
{
160+
$form = $this->formFactory->create(FormType::class, null, [
161+
'validation_groups' => new GroupSequence(['group1', 'group2']),
162+
])
163+
->add('foo', TextType::class, [
164+
'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])],
165+
])
166+
->add('bar', TextType::class, [
167+
'constraints' => [new NotBlank(['groups' => ['group2']])],
168+
])
169+
;
170+
171+
$form->submit(['foo' => 'invalid', 'bar' => null]);
172+
173+
$errors = $form->getErrors(true);
174+
175+
$this->assertCount(1, $errors);
176+
$this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint());
177+
}
178+
179+
public function testFieldsValidateInSequenceWithNestedGroupsArray()
180+
{
181+
$form = $this->formFactory->create(FormType::class, null, [
182+
'validation_groups' => new GroupSequence([['group1', 'group2'], 'group3']),
183+
])
184+
->add('foo', TextType::class, [
185+
'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])],
186+
])
187+
->add('bar', TextType::class, [
188+
'constraints' => [new Length(['min' => 10, 'groups' => ['group2']])],
189+
])
190+
->add('baz', TextType::class, [
191+
'constraints' => [new NotBlank(['groups' => ['group3']])],
192+
])
193+
;
194+
195+
$form->submit(['foo' => 'invalid', 'bar' => 'invalid', 'baz' => null]);
196+
197+
$errors = $form->getErrors(true);
198+
199+
$this->assertCount(2, $errors);
200+
$this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint());
201+
$this->assertInstanceOf(Length::class, $errors[1]->getCause()->getConstraint());
202+
}
203+
204+
public function testConstraintsInDifferentGroupsOnSingleField()
205+
{
206+
$form = $this->formFactory->create(FormType::class, null, [
207+
'validation_groups' => new GroupSequence(['group1', 'group2']),
208+
])
209+
->add('foo', TextType::class, [
210+
'constraints' => [
211+
new NotBlank([
212+
'groups' => ['group1'],
213+
]),
214+
new Length([
215+
'groups' => ['group2'],
216+
'max' => 3,
217+
]),
218+
],
219+
]);
220+
$form->submit([
221+
'foo' => 'test@example.com',
222+
]);
223+
224+
$errors = $form->getErrors(true);
225+
226+
$this->assertFalse($form->isValid());
227+
$this->assertCount(1, $errors);
228+
$this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint());
229+
}
230+
231+
public function testCascadeValidationToChildFormsUsingPropertyPaths()
232+
{
233+
$form = $this->formFactory->create(FormType::class, null, [
234+
'validation_groups' => ['group1', 'group2'],
235+
])
236+
->add('field1', null, [
237+
'constraints' => [new NotBlank(['groups' => 'group1'])],
238+
'property_path' => '[foo]',
239+
])
240+
->add('field2', null, [
241+
'constraints' => [new NotBlank(['groups' => 'group2'])],
242+
'property_path' => '[bar]',
243+
])
244+
;
245+
246+
$form->submit([
247+
'field1' => '',
248+
'field2' => '',
249+
]);
250+
251+
$violations = $this->validator->validate($form);
252+
253+
$this->assertCount(2, $violations);
254+
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
255+
$this->assertSame('children[field1].data', $violations[0]->getPropertyPath());
256+
$this->assertSame('This value should not be blank.', $violations[1]->getMessage());
257+
$this->assertSame('children[field2].data', $violations[1]->getPropertyPath());
258+
}
259+
260+
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
261+
{
262+
$form = $this->formFactory->create(FormType::class, null, [
263+
'validation_groups' => new GroupSequence(['group1', 'group2']),
264+
])
265+
->add('field1', null, [
266+
'constraints' => [new NotBlank(['groups' => 'group1'])],
267+
'property_path' => '[foo]',
268+
])
269+
->add('field2', null, [
270+
'constraints' => [new NotBlank(['groups' => 'group2'])],
271+
'property_path' => '[bar]',
272+
])
273+
;
274+
275+
$form->submit([
276+
'field1' => '',
277+
'field2' => '',
278+
]);
279+
280+
$violations = $this->validator->validate($form);
281+
282+
$this->assertCount(1, $violations);
283+
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
284+
$this->assertSame('children[field1].data', $violations[0]->getPropertyPath());
285+
}
286+
}
287+
288+
class Foo
289+
{
290+
public $bar;
291+
public $baz;
292+
293+
public static function loadValidatorMetadata(ClassMetadata $metadata)
294+
{
295+
$metadata->addPropertyConstraint('bar', new NotBlank());
296+
}
297+
}
298+
299+
class FooType extends AbstractType
300+
{
301+
public function buildForm(FormBuilderInterface $builder, array $options)
302+
{
303+
$builder
304+
->add('bar')
305+
->add('baz', null, [
306+
'constraints' => [new NotBlank()],
307+
])
308+
;
309+
}
310+
311+
public function configureOptions(OptionsResolver $resolver)
312+
{
313+
$resolver->setDefault('data_class', Foo::class);
314+
}
315+
}

0 commit comments

Comments
 (0)
0