]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/form/Symfony/Component/Form/Tests/CompoundFormTest.php
b240d2d0b3335f3f7fba8707ce06359aa2ec1101
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / Tests / CompoundFormTest.php
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;
13
14 use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
15 use Symfony\Component\Form\FormError;
16 use Symfony\Component\HttpFoundation\Request;
17 use Symfony\Component\HttpFoundation\File\UploadedFile;
18 use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer;
19
20 class CompoundFormTest extends AbstractFormTest
21 {
22 public function testValidIfAllChildrenAreValid()
23 {
24 $this->form->add($this->getValidForm('firstName'));
25 $this->form->add($this->getValidForm('lastName'));
26
27 $this->form->submit(array(
28 'firstName' => 'Bernhard',
29 'lastName' => 'Schussek',
30 ));
31
32 $this->assertTrue($this->form->isValid());
33 }
34
35 public function testInvalidIfChildIsInvalid()
36 {
37 $this->form->add($this->getValidForm('firstName'));
38 $this->form->add($this->getInvalidForm('lastName'));
39
40 $this->form->submit(array(
41 'firstName' => 'Bernhard',
42 'lastName' => 'Schussek',
43 ));
44
45 $this->assertFalse($this->form->isValid());
46 }
47
48 public function testSubmitForwardsNullIfValueIsMissing()
49 {
50 $child = $this->getMockForm('firstName');
51
52 $this->form->add($child);
53
54 $child->expects($this->once())
55 ->method('submit')
56 ->with($this->equalTo(null));
57
58 $this->form->submit(array());
59 }
60
61 public function testSubmitDoesNotForwardNullIfNotClearMissing()
62 {
63 $child = $this->getMockForm('firstName');
64
65 $this->form->add($child);
66
67 $child->expects($this->never())
68 ->method('submit');
69
70 $this->form->submit(array(), false);
71 }
72
73 public function testClearMissingFlagIsForwarded()
74 {
75 $child = $this->getMockForm('firstName');
76
77 $this->form->add($child);
78
79 $child->expects($this->once())
80 ->method('submit')
81 ->with($this->equalTo('foo'), false);
82
83 $this->form->submit(array('firstName' => 'foo'), false);
84 }
85
86 public function testCloneChildren()
87 {
88 $child = $this->getBuilder('child')->getForm();
89 $this->form->add($child);
90
91 $clone = clone $this->form;
92
93 $this->assertNotSame($this->form, $clone);
94 $this->assertNotSame($child, $clone['child']);
95 }
96
97 public function testNotEmptyIfChildNotEmpty()
98 {
99 $child = $this->getMockForm();
100 $child->expects($this->once())
101 ->method('isEmpty')
102 ->will($this->returnValue(false));
103
104 $this->form->setData(null);
105 $this->form->add($child);
106
107 $this->assertFalse($this->form->isEmpty());
108 }
109
110 public function testValidIfSubmittedAndDisabledWithChildren()
111 {
112 $this->factory->expects($this->once())
113 ->method('createNamedBuilder')
114 ->with('name', 'text', null, array())
115 ->will($this->returnValue($this->getBuilder('name')));
116
117 $form = $this->getBuilder('person')
118 ->setDisabled(true)
119 ->setCompound(true)
120 ->setDataMapper($this->getDataMapper())
121 ->add('name', 'text')
122 ->getForm();
123 $form->submit(array('name' => 'Jacques Doe'));
124
125 $this->assertTrue($form->isValid());
126 }
127
128 public function testNotValidIfChildNotValid()
129 {
130 $child = $this->getMockForm();
131 $child->expects($this->once())
132 ->method('isValid')
133 ->will($this->returnValue(false));
134
135 $this->form->add($child);
136 $this->form->submit(array());
137
138 $this->assertFalse($this->form->isValid());
139 }
140
141 public function testAdd()
142 {
143 $child = $this->getBuilder('foo')->getForm();
144 $this->form->add($child);
145
146 $this->assertTrue($this->form->has('foo'));
147 $this->assertSame($this->form, $child->getParent());
148 $this->assertSame(array('foo' => $child), $this->form->all());
149 }
150
151 public function testAddUsingNameAndType()
152 {
153 $child = $this->getBuilder('foo')->getForm();
154
155 $this->factory->expects($this->once())
156 ->method('createNamed')
157 ->with('foo', 'text', null, array(
158 'bar' => 'baz',
159 'auto_initialize' => false,
160 ))
161 ->will($this->returnValue($child));
162
163 $this->form->add('foo', 'text', array('bar' => 'baz'));
164
165 $this->assertTrue($this->form->has('foo'));
166 $this->assertSame($this->form, $child->getParent());
167 $this->assertSame(array('foo' => $child), $this->form->all());
168 }
169
170 public function testAddUsingIntegerNameAndType()
171 {
172 $child = $this->getBuilder(0)->getForm();
173
174 $this->factory->expects($this->once())
175 ->method('createNamed')
176 ->with('0', 'text', null, array(
177 'bar' => 'baz',
178 'auto_initialize' => false,
179 ))
180 ->will($this->returnValue($child));
181
182 // in order to make casting unnecessary
183 $this->form->add(0, 'text', array('bar' => 'baz'));
184
185 $this->assertTrue($this->form->has(0));
186 $this->assertSame($this->form, $child->getParent());
187 $this->assertSame(array(0 => $child), $this->form->all());
188 }
189
190 public function testAddUsingNameButNoType()
191 {
192 $this->form = $this->getBuilder('name', null, '\stdClass')
193 ->setCompound(true)
194 ->setDataMapper($this->getDataMapper())
195 ->getForm();
196
197 $child = $this->getBuilder('foo')->getForm();
198
199 $this->factory->expects($this->once())
200 ->method('createForProperty')
201 ->with('\stdClass', 'foo')
202 ->will($this->returnValue($child));
203
204 $this->form->add('foo');
205
206 $this->assertTrue($this->form->has('foo'));
207 $this->assertSame($this->form, $child->getParent());
208 $this->assertSame(array('foo' => $child), $this->form->all());
209 }
210
211 public function testAddUsingNameButNoTypeAndOptions()
212 {
213 $this->form = $this->getBuilder('name', null, '\stdClass')
214 ->setCompound(true)
215 ->setDataMapper($this->getDataMapper())
216 ->getForm();
217
218 $child = $this->getBuilder('foo')->getForm();
219
220 $this->factory->expects($this->once())
221 ->method('createForProperty')
222 ->with('\stdClass', 'foo', null, array(
223 'bar' => 'baz',
224 'auto_initialize' => false,
225 ))
226 ->will($this->returnValue($child));
227
228 $this->form->add('foo', null, array('bar' => 'baz'));
229
230 $this->assertTrue($this->form->has('foo'));
231 $this->assertSame($this->form, $child->getParent());
232 $this->assertSame(array('foo' => $child), $this->form->all());
233 }
234
235 /**
236 * @expectedException \Symfony\Component\Form\Exception\AlreadySubmittedException
237 */
238 public function testAddThrowsExceptionIfAlreadySubmitted()
239 {
240 $this->form->submit(array());
241 $this->form->add($this->getBuilder('foo')->getForm());
242 }
243
244 public function testRemove()
245 {
246 $child = $this->getBuilder('foo')->getForm();
247 $this->form->add($child);
248 $this->form->remove('foo');
249
250 $this->assertNull($child->getParent());
251 $this->assertCount(0, $this->form);
252 }
253
254 /**
255 * @expectedException \Symfony\Component\Form\Exception\AlreadySubmittedException
256 */
257 public function testRemoveThrowsExceptionIfAlreadySubmitted()
258 {
259 $this->form->add($this->getBuilder('foo')->setCompound(false)->getForm());
260 $this->form->submit(array('foo' => 'bar'));
261 $this->form->remove('foo');
262 }
263
264 public function testRemoveIgnoresUnknownName()
265 {
266 $this->form->remove('notexisting');
267 }
268
269 public function testArrayAccess()
270 {
271 $child = $this->getBuilder('foo')->getForm();
272
273 $this->form[] = $child;
274
275 $this->assertTrue(isset($this->form['foo']));
276 $this->assertSame($child, $this->form['foo']);
277
278 unset($this->form['foo']);
279
280 $this->assertFalse(isset($this->form['foo']));
281 }
282
283 public function testCountable()
284 {
285 $this->form->add($this->getBuilder('foo')->getForm());
286 $this->form->add($this->getBuilder('bar')->getForm());
287
288 $this->assertCount(2, $this->form);
289 }
290
291 public function testIterator()
292 {
293 $this->form->add($this->getBuilder('foo')->getForm());
294 $this->form->add($this->getBuilder('bar')->getForm());
295
296 $this->assertSame($this->form->all(), iterator_to_array($this->form));
297 }
298
299 public function testAddMapsViewDataToFormIfInitialized()
300 {
301 $test = $this;
302 $mapper = $this->getDataMapper();
303 $form = $this->getBuilder()
304 ->setCompound(true)
305 ->setDataMapper($mapper)
306 ->addViewTransformer(new FixedDataTransformer(array(
307 '' => '',
308 'foo' => 'bar',
309 )))
310 ->setData('foo')
311 ->getForm();
312
313 $child = $this->getBuilder()->getForm();
314 $mapper->expects($this->once())
315 ->method('mapDataToForms')
316 ->with('bar', $this->isInstanceOf('\RecursiveIteratorIterator'))
317 ->will($this->returnCallback(function ($data, \RecursiveIteratorIterator $iterator) use ($child, $test) {
318 $test->assertInstanceOf('Symfony\Component\Form\Util\InheritDataAwareIterator', $iterator->getInnerIterator());
319 $test->assertSame(array($child), iterator_to_array($iterator));
320 }));
321
322 $form->initialize();
323 $form->add($child);
324 }
325
326 public function testAddDoesNotMapViewDataToFormIfNotInitialized()
327 {
328 $mapper = $this->getDataMapper();
329 $form = $this->getBuilder()
330 ->setCompound(true)
331 ->setDataMapper($mapper)
332 ->getForm();
333
334 $child = $this->getBuilder()->getForm();
335 $mapper->expects($this->never())
336 ->method('mapDataToForms');
337
338 $form->add($child);
339 }
340
341 public function testAddDoesNotMapViewDataToFormIfInheritData()
342 {
343 $mapper = $this->getDataMapper();
344 $form = $this->getBuilder()
345 ->setCompound(true)
346 ->setDataMapper($mapper)
347 ->setInheritData(true)
348 ->getForm();
349
350 $child = $this->getBuilder()->getForm();
351 $mapper->expects($this->never())
352 ->method('mapDataToForms');
353
354 $form->initialize();
355 $form->add($child);
356 }
357
358 public function testSetDataMapsViewDataToChildren()
359 {
360 $test = $this;
361 $mapper = $this->getDataMapper();
362 $form = $this->getBuilder()
363 ->setCompound(true)
364 ->setDataMapper($mapper)
365 ->addViewTransformer(new FixedDataTransformer(array(
366 '' => '',
367 'foo' => 'bar',
368 )))
369 ->getForm();
370
371 $form->add($child1 = $this->getBuilder('firstName')->getForm());
372 $form->add($child2 = $this->getBuilder('lastName')->getForm());
373
374 $mapper->expects($this->once())
375 ->method('mapDataToForms')
376 ->with('bar', $this->isInstanceOf('\RecursiveIteratorIterator'))
377 ->will($this->returnCallback(function ($data, \RecursiveIteratorIterator $iterator) use ($child1, $child2, $test) {
378 $test->assertInstanceOf('Symfony\Component\Form\Util\InheritDataAwareIterator', $iterator->getInnerIterator());
379 $test->assertSame(array('firstName' => $child1, 'lastName' => $child2), iterator_to_array($iterator));
380 }));
381
382 $form->setData('foo');
383 }
384
385 public function testSubmitMapsSubmittedChildrenOntoExistingViewData()
386 {
387 $test = $this;
388 $mapper = $this->getDataMapper();
389 $form = $this->getBuilder()
390 ->setCompound(true)
391 ->setDataMapper($mapper)
392 ->addViewTransformer(new FixedDataTransformer(array(
393 '' => '',
394 'foo' => 'bar',
395 )))
396 ->setData('foo')
397 ->getForm();
398
399 $form->add($child1 = $this->getBuilder('firstName')->setCompound(false)->getForm());
400 $form->add($child2 = $this->getBuilder('lastName')->setCompound(false)->getForm());
401
402 $mapper->expects($this->once())
403 ->method('mapFormsToData')
404 ->with($this->isInstanceOf('\RecursiveIteratorIterator'), 'bar')
405 ->will($this->returnCallback(function (\RecursiveIteratorIterator $iterator) use ($child1, $child2, $test) {
406 $test->assertInstanceOf('Symfony\Component\Form\Util\InheritDataAwareIterator', $iterator->getInnerIterator());
407 $test->assertSame(array('firstName' => $child1, 'lastName' => $child2), iterator_to_array($iterator));
408 $test->assertEquals('Bernhard', $child1->getData());
409 $test->assertEquals('Schussek', $child2->getData());
410 }));
411
412 $form->submit(array(
413 'firstName' => 'Bernhard',
414 'lastName' => 'Schussek',
415 ));
416 }
417
418 public function testMapFormsToDataIsNotInvokedIfInheritData()
419 {
420 $mapper = $this->getDataMapper();
421 $form = $this->getBuilder()
422 ->setCompound(true)
423 ->setDataMapper($mapper)
424 ->setInheritData(true)
425 ->addViewTransformer(new FixedDataTransformer(array(
426 '' => '',
427 'foo' => 'bar',
428 )))
429 ->getForm();
430
431 $form->add($child1 = $this->getBuilder('firstName')->setCompound(false)->getForm());
432 $form->add($child2 = $this->getBuilder('lastName')->setCompound(false)->getForm());
433
434 $mapper->expects($this->never())
435 ->method('mapFormsToData');
436
437 $form->submit(array(
438 'firstName' => 'Bernhard',
439 'lastName' => 'Schussek',
440 ));
441 }
442
443 /*
444 * https://github.com/symfony/symfony/issues/4480
445 */
446 public function testSubmitRestoresViewDataIfCompoundAndEmpty()
447 {
448 $mapper = $this->getDataMapper();
449 $object = new \stdClass();
450 $form = $this->getBuilder('name', null, 'stdClass')
451 ->setCompound(true)
452 ->setDataMapper($mapper)
453 ->setData($object)
454 ->getForm();
455
456 $form->submit(array());
457
458 $this->assertSame($object, $form->getData());
459 }
460
461 public function testSubmitMapsSubmittedChildrenOntoEmptyData()
462 {
463 $test = $this;
464 $mapper = $this->getDataMapper();
465 $object = new \stdClass();
466 $form = $this->getBuilder()
467 ->setCompound(true)
468 ->setDataMapper($mapper)
469 ->setEmptyData($object)
470 ->setData(null)
471 ->getForm();
472
473 $form->add($child = $this->getBuilder('name')->setCompound(false)->getForm());
474
475 $mapper->expects($this->once())
476 ->method('mapFormsToData')
477 ->with($this->isInstanceOf('\RecursiveIteratorIterator'), $object)
478 ->will($this->returnCallback(function (\RecursiveIteratorIterator $iterator) use ($child, $test) {
479 $test->assertInstanceOf('Symfony\Component\Form\Util\InheritDataAwareIterator', $iterator->getInnerIterator());
480 $test->assertSame(array('name' => $child), iterator_to_array($iterator));
481 }));
482
483 $form->submit(array(
484 'name' => 'Bernhard',
485 ));
486 }
487
488 public function requestMethodProvider()
489 {
490 return array(
491 array('POST'),
492 array('PUT'),
493 array('DELETE'),
494 array('PATCH'),
495 );
496 }
497
498 /**
499 * @dataProvider requestMethodProvider
500 */
501 public function testSubmitPostOrPutRequest($method)
502 {
503 if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
504 $this->markTestSkipped('The "HttpFoundation" component is not available');
505 }
506
507 $path = tempnam(sys_get_temp_dir(), 'sf2');
508 touch($path);
509
510 $values = array(
511 'author' => array(
512 'name' => 'Bernhard',
513 'image' => array('filename' => 'foobar.png'),
514 ),
515 );
516
517 $files = array(
518 'author' => array(
519 'error' => array('image' => UPLOAD_ERR_OK),
520 'name' => array('image' => 'upload.png'),
521 'size' => array('image' => 123),
522 'tmp_name' => array('image' => $path),
523 'type' => array('image' => 'image/png'),
524 ),
525 );
526
527 $request = new Request(array(), $values, array(), array(), $files, array(
528 'REQUEST_METHOD' => $method,
529 ));
530
531 $form = $this->getBuilder('author')
532 ->setMethod($method)
533 ->setCompound(true)
534 ->setDataMapper($this->getDataMapper())
535 ->setRequestHandler(new HttpFoundationRequestHandler())
536 ->getForm();
537 $form->add($this->getBuilder('name')->getForm());
538 $form->add($this->getBuilder('image')->getForm());
539
540 $form->handleRequest($request);
541
542 $file = new UploadedFile($path, 'upload.png', 'image/png', 123, UPLOAD_ERR_OK);
543
544 $this->assertEquals('Bernhard', $form['name']->getData());
545 $this->assertEquals($file, $form['image']->getData());
546
547 unlink($path);
548 }
549
550 /**
551 * @dataProvider requestMethodProvider
552 */
553 public function testSubmitPostOrPutRequestWithEmptyRootFormName($method)
554 {
555 if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
556 $this->markTestSkipped('The "HttpFoundation" component is not available');
557 }
558
559 $path = tempnam(sys_get_temp_dir(), 'sf2');
560 touch($path);
561
562 $values = array(
563 'name' => 'Bernhard',
564 'extra' => 'data',
565 );
566
567 $files = array(
568 'image' => array(
569 'error' => UPLOAD_ERR_OK,
570 'name' => 'upload.png',
571 'size' => 123,
572 'tmp_name' => $path,
573 'type' => 'image/png',
574 ),
575 );
576
577 $request = new Request(array(), $values, array(), array(), $files, array(
578 'REQUEST_METHOD' => $method,
579 ));
580
581 $form = $this->getBuilder('')
582 ->setMethod($method)
583 ->setCompound(true)
584 ->setDataMapper($this->getDataMapper())
585 ->setRequestHandler(new HttpFoundationRequestHandler())
586 ->getForm();
587 $form->add($this->getBuilder('name')->getForm());
588 $form->add($this->getBuilder('image')->getForm());
589
590 $form->handleRequest($request);
591
592 $file = new UploadedFile($path, 'upload.png', 'image/png', 123, UPLOAD_ERR_OK);
593
594 $this->assertEquals('Bernhard', $form['name']->getData());
595 $this->assertEquals($file, $form['image']->getData());
596 $this->assertEquals(array('extra' => 'data'), $form->getExtraData());
597
598 unlink($path);
599 }
600
601 /**
602 * @dataProvider requestMethodProvider
603 */
604 public function testSubmitPostOrPutRequestWithSingleChildForm($method)
605 {
606 if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
607 $this->markTestSkipped('The "HttpFoundation" component is not available');
608 }
609
610 $path = tempnam(sys_get_temp_dir(), 'sf2');
611 touch($path);
612
613 $files = array(
614 'image' => array(
615 'error' => UPLOAD_ERR_OK,
616 'name' => 'upload.png',
617 'size' => 123,
618 'tmp_name' => $path,
619 'type' => 'image/png',
620 ),
621 );
622
623 $request = new Request(array(), array(), array(), array(), $files, array(
624 'REQUEST_METHOD' => $method,
625 ));
626
627 $form = $this->getBuilder('image')
628 ->setMethod($method)
629 ->setRequestHandler(new HttpFoundationRequestHandler())
630 ->getForm();
631
632 $form->handleRequest($request);
633
634 $file = new UploadedFile($path, 'upload.png', 'image/png', 123, UPLOAD_ERR_OK);
635
636 $this->assertEquals($file, $form->getData());
637
638 unlink($path);
639 }
640
641 /**
642 * @dataProvider requestMethodProvider
643 */
644 public function testSubmitPostOrPutRequestWithSingleChildFormUploadedFile($method)
645 {
646 if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
647 $this->markTestSkipped('The "HttpFoundation" component is not available');
648 }
649
650 $path = tempnam(sys_get_temp_dir(), 'sf2');
651 touch($path);
652
653 $values = array(
654 'name' => 'Bernhard',
655 );
656
657 $request = new Request(array(), $values, array(), array(), array(), array(
658 'REQUEST_METHOD' => $method,
659 ));
660
661 $form = $this->getBuilder('name')
662 ->setMethod($method)
663 ->setRequestHandler(new HttpFoundationRequestHandler())
664 ->getForm();
665
666 $form->handleRequest($request);
667
668 $this->assertEquals('Bernhard', $form->getData());
669
670 unlink($path);
671 }
672
673 public function testSubmitGetRequest()
674 {
675 if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
676 $this->markTestSkipped('The "HttpFoundation" component is not available');
677 }
678
679 $values = array(
680 'author' => array(
681 'firstName' => 'Bernhard',
682 'lastName' => 'Schussek',
683 ),
684 );
685
686 $request = new Request($values, array(), array(), array(), array(), array(
687 'REQUEST_METHOD' => 'GET',
688 ));
689
690 $form = $this->getBuilder('author')
691 ->setMethod('GET')
692 ->setCompound(true)
693 ->setDataMapper($this->getDataMapper())
694 ->setRequestHandler(new HttpFoundationRequestHandler())
695 ->getForm();
696 $form->add($this->getBuilder('firstName')->getForm());
697 $form->add($this->getBuilder('lastName')->getForm());
698
699 $form->handleRequest($request);
700
701 $this->assertEquals('Bernhard', $form['firstName']->getData());
702 $this->assertEquals('Schussek', $form['lastName']->getData());
703 }
704
705 public function testSubmitGetRequestWithEmptyRootFormName()
706 {
707 if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
708 $this->markTestSkipped('The "HttpFoundation" component is not available');
709 }
710
711 $values = array(
712 'firstName' => 'Bernhard',
713 'lastName' => 'Schussek',
714 'extra' => 'data'
715 );
716
717 $request = new Request($values, array(), array(), array(), array(), array(
718 'REQUEST_METHOD' => 'GET',
719 ));
720
721 $form = $this->getBuilder('')
722 ->setMethod('GET')
723 ->setCompound(true)
724 ->setDataMapper($this->getDataMapper())
725 ->setRequestHandler(new HttpFoundationRequestHandler())
726 ->getForm();
727 $form->add($this->getBuilder('firstName')->getForm());
728 $form->add($this->getBuilder('lastName')->getForm());
729
730 $form->handleRequest($request);
731
732 $this->assertEquals('Bernhard', $form['firstName']->getData());
733 $this->assertEquals('Schussek', $form['lastName']->getData());
734 $this->assertEquals(array('extra' => 'data'), $form->getExtraData());
735 }
736
737 public function testGetErrorsAsStringDeep()
738 {
739 $parent = $this->getBuilder()
740 ->setCompound(true)
741 ->setDataMapper($this->getDataMapper())
742 ->getForm();
743
744 $this->form->addError(new FormError('Error!'));
745
746 $parent->add($this->form);
747 $parent->add($this->getBuilder('foo')->getForm());
748
749 $this->assertEquals("name:\n ERROR: Error!\nfoo:\n No errors\n", $parent->getErrorsAsString());
750 }
751
752 protected function createForm()
753 {
754 return $this->getBuilder()
755 ->setCompound(true)
756 ->setDataMapper($this->getDataMapper())
757 ->getForm();
758 }
759 }