Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f75a3a2

Browse files
add test for CollectionType error property paths
1 parent c8b48d8 commit f75a3a2

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
use Symfony\Component\Form\Form;
1717
use Symfony\Component\Form\Forms;
1818
use Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait;
19+
use Symfony\Component\Form\Tests\Extension\Core\Type\CollectionTypeTest;
1920
use Symfony\Component\Form\Tests\Extension\Core\Type\FormTypeTest;
2021
use Symfony\Component\Form\Tests\Extension\Core\Type\TextTypeTest;
2122
use Symfony\Component\Form\Tests\Fixtures\Author;
23+
use Symfony\Component\Form\Tests\Fixtures\AuthorType;
24+
use Symfony\Component\Form\Tests\Fixtures\Organization;
2225
use Symfony\Component\Validator\Constraints\GroupSequence;
2326
use Symfony\Component\Validator\Constraints\Length;
2427
use Symfony\Component\Validator\Constraints\NotBlank;
@@ -158,4 +161,92 @@ protected function createForm(array $options = [])
158161
{
159162
return $this->factory->create(FormTypeTest::TESTED_TYPE, null, $options);
160163
}
164+
165+
public function testErrorPathOnCollections()
166+
{
167+
$formMetadata = new ClassMetadata(Form::class);
168+
$authorMetadata = (new ClassMetadata(Author::class))
169+
->addPropertyConstraint('firstName', new NotBlank());
170+
$organizationMetadata = (new ClassMetadata(Organization::class))
171+
->addPropertyConstraint('authors', new Valid());
172+
$metadataFactory = $this->createMock(MetadataFactoryInterface::class);
173+
$metadataFactory->expects($this->any())
174+
->method('getMetadataFor')
175+
->willReturnCallback(static function ($classOrObject) use ($formMetadata, $authorMetadata, $organizationMetadata) {
176+
if (Author::class === $classOrObject || $classOrObject instanceof Author) {
177+
return $authorMetadata;
178+
}
179+
180+
if (Organization::class === $classOrObject || $classOrObject instanceof Organization) {
181+
return $organizationMetadata;
182+
}
183+
184+
if (Form::class === $classOrObject || $classOrObject instanceof Form) {
185+
return $formMetadata;
186+
}
187+
188+
return new ClassMetadata(\is_string($classOrObject) ? $classOrObject : \get_class($classOrObject));
189+
});
190+
191+
$validator = Validation::createValidatorBuilder()
192+
->setMetadataFactory($metadataFactory)
193+
->getValidator();
194+
195+
$form = Forms::createFormFactoryBuilder()
196+
->addExtension(new ValidatorExtension($validator))
197+
->getFormFactory()
198+
->create(FormTypeTest::TESTED_TYPE, new Organization([]), [
199+
'data_class' => Organization::class,
200+
'by_reference' => false,
201+
])
202+
->add('authors', CollectionTypeTest::TESTED_TYPE, [
203+
'entry_type' => AuthorType::class,
204+
'allow_add' => true,
205+
'allow_delete' => true,
206+
])
207+
;
208+
209+
$form->submit([
210+
'authors' => [
211+
0 => [
212+
'firstName' => '', // Fires a Not Blank Error
213+
'lastName' => 'lastName1',
214+
],
215+
// key "1" could be missing if we add 4 blank form entries and then remove it.
216+
2 => [
217+
'firstName' => '', // Fires a Not Blank Error
218+
'lastName' => 'lastName3',
219+
],
220+
3 => [
221+
'firstName' => '', // Fires a Not Blank Error
222+
'lastName' => 'lastName3',
223+
],
224+
],
225+
]);
226+
227+
//Form behaves right (...?). It has index 0, 2 and 3 (1 has been removed)
228+
$this->assertTrue($form->get('authors')->has('0'));
229+
$this->assertFalse($form->get('authors')->has('1'));
230+
$this->assertTrue($form->get('authors')->has('2'));
231+
$this->assertTrue($form->get('authors')->has('3'));
232+
233+
//Form does have 3 not blank errors
234+
$errors = $form->getErrors(true);
235+
$this->assertCount(3, $errors);
236+
237+
//But errors property paths are messing up
238+
$errorPaths = [
239+
$errors[0]->getCause()->getPropertyPath(),
240+
$errors[1]->getCause()->getPropertyPath(),
241+
$errors[2]->getCause()->getPropertyPath(),
242+
];
243+
244+
$this->assertContains('data.authors[0].firstName', $errorPaths);
245+
$this->assertNotContains('data.authors[1].firstName', $errorPaths);
246+
$this->assertContains('data.authors[2].firstName', $errorPaths);
247+
$this->assertContains('data.authors[3].firstName', $errorPaths);
248+
249+
//In fact, root form should NOT contain errors but it does
250+
$this->assertCount(0, $form->getErrors(false));
251+
}
161252
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Symfony\Component\Form\Tests\Fixtures;
4+
5+
class Organization
6+
{
7+
public $authors = [];
8+
9+
public function __construct(array $authors = [])
10+
{
11+
$this->authors = $authors;
12+
}
13+
14+
public function getAuthors(): array
15+
{
16+
return $this->authors;
17+
}
18+
19+
public function addAuthor(Author $author): self
20+
{
21+
$this->authors[] = $author;
22+
return $this;
23+
}
24+
25+
public function removeAuthor(Author $author): self
26+
{
27+
if (false !== $key = array_search($author, $this->authors, true)) {
28+
array_splice($this->authors, $key, 1);
29+
}
30+
return $this;
31+
}
32+
}

0 commit comments

Comments
 (0)