2011-04-14 02:38:19 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of the Symfony package.
|
|
|
|
*
|
|
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
2012-03-28 14:43:52 +01:00
|
|
|
namespace Symfony\Component\Form\Tests;
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
use Symfony\Component\Form\FormError;
|
|
|
|
|
|
|
|
abstract class AbstractTableLayoutTest extends AbstractLayoutTest
|
|
|
|
{
|
|
|
|
public function testRow()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$form = $this->factory->createNamed('text', 'name');
|
2011-04-14 02:38:19 +01:00
|
|
|
$form->addError(new FormError('Error!'));
|
2011-04-15 12:52:11 +01:00
|
|
|
$view = $form->createView();
|
2011-04-14 14:02:51 +01:00
|
|
|
$html = $this->renderRow($view);
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
$this->assertMatchesXpath($html,
|
|
|
|
'/tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[
|
|
|
|
./ul
|
|
|
|
[./li[.="[trans]Error![/trans]"]]
|
|
|
|
[count(./li)=1]
|
|
|
|
/following-sibling::input[@id="name"]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRepeatedRow()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$form = $this->factory->createNamed('repeated', 'name');
|
2011-04-15 12:52:11 +01:00
|
|
|
$html = $this->renderRow($form->createView());
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
$this->assertMatchesXpath($html,
|
2012-04-19 09:37:16 +01:00
|
|
|
'/tr
|
2011-04-14 02:38:19 +01:00
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_first"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_first"]]
|
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_second"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_second"]]
|
|
|
|
]
|
2012-04-13 13:11:09 +01:00
|
|
|
[count(../tr)=3]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
2011-04-14 02:38:19 +01:00
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRepeatedRowWithErrors()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$form = $this->factory->createNamed('repeated', 'name');
|
2011-04-14 02:38:19 +01:00
|
|
|
$form->addError(new FormError('Error!'));
|
2011-04-15 12:52:11 +01:00
|
|
|
$view = $form->createView();
|
2011-04-14 14:02:51 +01:00
|
|
|
$html = $this->renderRow($view);
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
$this->assertMatchesXpath($html,
|
|
|
|
'/tr
|
|
|
|
[./td[@colspan="2"]/ul
|
|
|
|
[./li[.="[trans]Error![/trans]"]]
|
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_first"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_first"]]
|
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_second"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_second"]]
|
|
|
|
]
|
2012-04-13 13:11:09 +01:00
|
|
|
[count(../tr)=4]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
2011-04-14 02:38:19 +01:00
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRest()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$view = $this->factory->createNamedBuilder('form', 'name')
|
2011-04-14 02:38:19 +01:00
|
|
|
->add('field1', 'text')
|
|
|
|
->add('field2', 'repeated')
|
|
|
|
->add('field3', 'text')
|
|
|
|
->add('field4', 'text')
|
2011-04-14 13:42:17 +01:00
|
|
|
->getForm()
|
2011-04-15 12:52:11 +01:00
|
|
|
->createView();
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
// Render field2 row -> does not implicitely call renderWidget because
|
|
|
|
// it is a repeated field!
|
2011-04-14 14:02:51 +01:00
|
|
|
$this->renderRow($view['field2']);
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
// Render field3 widget
|
2011-04-14 14:02:51 +01:00
|
|
|
$this->renderWidget($view['field3']);
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
// Rest should only contain field1 and field4
|
2011-04-14 14:02:51 +01:00
|
|
|
$html = $this->renderRest($view);
|
2011-04-14 02:38:19 +01:00
|
|
|
|
|
|
|
$this->assertMatchesXpath($html,
|
2012-04-19 09:37:16 +01:00
|
|
|
'/tr
|
2011-04-14 02:38:19 +01:00
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_field1"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_field1"]]
|
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_field4"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_field4"]]
|
|
|
|
]
|
|
|
|
[count(../tr)=3]
|
|
|
|
[count(..//label)=2]
|
|
|
|
[count(..//input)=3]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
2011-04-14 02:38:19 +01:00
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testCollection()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$form = $this->factory->createNamed('collection', 'name', array('a', 'b'), array(
|
2011-04-14 02:38:19 +01:00
|
|
|
'type' => 'text',
|
|
|
|
));
|
|
|
|
|
2011-04-15 12:52:11 +01:00
|
|
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
2011-04-14 02:38:19 +01:00
|
|
|
'/table
|
|
|
|
[
|
2012-04-19 09:37:16 +01:00
|
|
|
./tr[./td/input[@type="text"][@value="a"]]
|
2011-04-14 02:38:19 +01:00
|
|
|
/following-sibling::tr[./td/input[@type="text"][@value="b"]]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"][./td[@colspan="2"]/input[@type="hidden"][@id="name__token"]]
|
2011-04-14 02:38:19 +01:00
|
|
|
]
|
2011-06-10 21:18:09 +01:00
|
|
|
[count(./tr[./td/input])=3]
|
2011-04-14 02:38:19 +01:00
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2012-04-20 17:42:21 +01:00
|
|
|
public function testEmptyCollection()
|
|
|
|
{
|
|
|
|
$form = $this->factory->createNamed('collection', 'name', array(), array(
|
|
|
|
'type' => 'text',
|
|
|
|
));
|
|
|
|
|
|
|
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
|
|
|
'/table
|
|
|
|
[count(./tr[./td/input])=0]
|
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2011-04-14 02:38:19 +01:00
|
|
|
public function testForm()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$view = $this->factory->createNamedBuilder('form', 'name')
|
2011-04-14 02:38:19 +01:00
|
|
|
->add('firstName', 'text')
|
|
|
|
->add('lastName', 'text')
|
2011-04-14 13:42:17 +01:00
|
|
|
->getForm()
|
2011-04-15 12:52:11 +01:00
|
|
|
->createView();
|
2011-04-14 02:38:19 +01:00
|
|
|
|
2011-04-14 14:02:51 +01:00
|
|
|
$this->assertWidgetMatchesXpath($view, array(),
|
2011-04-14 02:38:19 +01:00
|
|
|
'/table
|
|
|
|
[
|
2012-04-19 09:37:16 +01:00
|
|
|
./tr
|
2011-04-14 02:38:19 +01:00
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_firstName"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_firstName"]]
|
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_lastName"]]
|
|
|
|
/following-sibling::td
|
|
|
|
[./input[@id="name_lastName"]]
|
|
|
|
]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
2011-04-14 02:38:19 +01:00
|
|
|
]
|
|
|
|
[count(.//input)=3]
|
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2012-02-10 10:41:19 +00:00
|
|
|
// https://github.com/symfony/symfony/issues/2308
|
|
|
|
public function testNestedFormError()
|
|
|
|
{
|
|
|
|
$form = $this->factory->createNamedBuilder('form', 'name')
|
2012-04-13 15:06:32 +01:00
|
|
|
->add($this->factory
|
|
|
|
->createNamedBuilder('form', 'child', null, array('error_bubbling' => false))
|
|
|
|
->add('grandChild', 'form')
|
|
|
|
)
|
2012-02-10 10:41:19 +00:00
|
|
|
->getForm();
|
|
|
|
|
|
|
|
$form->get('child')->addError(new FormError('Error!'));
|
|
|
|
|
|
|
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
|
|
|
'/table
|
|
|
|
[
|
|
|
|
./tr/td/table
|
|
|
|
[@id="name_child"]
|
|
|
|
[./tr/td/ul/li[.="[trans]Error![/trans]"]]
|
|
|
|
]
|
|
|
|
[count(.//li[.="[trans]Error![/trans]"])=1]
|
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2012-04-13 13:11:09 +01:00
|
|
|
public function testCsrf()
|
|
|
|
{
|
|
|
|
$this->csrfProvider->expects($this->any())
|
|
|
|
->method('generateCsrfToken')
|
|
|
|
->will($this->returnValue('foo&bar'));
|
|
|
|
|
|
|
|
$form = $this->factory->createNamedBuilder('form', 'name')
|
|
|
|
->add($this->factory
|
|
|
|
// No CSRF protection on nested forms
|
|
|
|
->createNamedBuilder('form', 'child')
|
|
|
|
->add($this->factory->createNamedBuilder('text', 'grandchild'))
|
|
|
|
)
|
|
|
|
->getForm();
|
|
|
|
|
|
|
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
|
|
|
'/table
|
|
|
|
[
|
|
|
|
./tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
[count(.//input[@type="hidden"])=1]
|
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2011-04-14 02:38:19 +01:00
|
|
|
public function testRepeated()
|
|
|
|
{
|
2011-04-22 09:42:21 +01:00
|
|
|
$form = $this->factory->createNamed('repeated', 'name', 'foobar', array(
|
2011-04-14 02:38:19 +01:00
|
|
|
'type' => 'text',
|
|
|
|
));
|
|
|
|
|
2011-04-15 12:52:11 +01:00
|
|
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
2011-04-14 02:38:19 +01:00
|
|
|
'/table
|
|
|
|
[
|
2012-04-19 09:37:16 +01:00
|
|
|
./tr
|
2011-04-14 02:38:19 +01:00
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_first"]]
|
|
|
|
/following-sibling::td
|
2011-06-27 12:07:16 +01:00
|
|
|
[./input[@type="text"][@id="name_first"]]
|
2011-04-14 02:38:19 +01:00
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_second"]]
|
|
|
|
/following-sibling::td
|
2011-06-27 12:07:16 +01:00
|
|
|
[./input[@type="text"][@id="name_second"]]
|
|
|
|
]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
2011-06-27 12:07:16 +01:00
|
|
|
]
|
2012-04-13 13:11:09 +01:00
|
|
|
[count(.//input)=3]
|
2011-06-27 12:07:16 +01:00
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRepeatedWithCustomOptions()
|
|
|
|
{
|
|
|
|
$form = $this->factory->createNamed('repeated', 'name', 'foobar', array(
|
2011-09-24 09:44:47 +01:00
|
|
|
'type' => 'password',
|
2011-06-27 12:07:16 +01:00
|
|
|
'first_options' => array('label' => 'Test', 'required' => false),
|
|
|
|
'second_options' => array('label' => 'Test2')
|
|
|
|
));
|
|
|
|
|
|
|
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
|
|
|
'/table
|
|
|
|
[
|
2012-04-19 09:37:16 +01:00
|
|
|
./tr
|
2011-06-27 12:07:16 +01:00
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_first"][.="[trans]Test[/trans]"]]
|
|
|
|
/following-sibling::td
|
2011-09-24 09:44:47 +01:00
|
|
|
[./input[@type="password"][@id="name_first"][@required="required"]]
|
2011-06-27 12:07:16 +01:00
|
|
|
]
|
|
|
|
/following-sibling::tr
|
|
|
|
[
|
|
|
|
./td
|
|
|
|
[./label[@for="name_second"][.="[trans]Test2[/trans]"]]
|
|
|
|
/following-sibling::td
|
2011-09-24 09:44:47 +01:00
|
|
|
[./input[@type="password"][@id="name_second"][@required="required"]]
|
2011-04-14 02:38:19 +01:00
|
|
|
]
|
2012-04-19 09:37:16 +01:00
|
|
|
/following-sibling::tr[@style="display: none"]
|
|
|
|
[./td[@colspan="2"]/input
|
|
|
|
[@type="hidden"]
|
|
|
|
[@id="name__token"]
|
|
|
|
]
|
2011-04-14 02:38:19 +01:00
|
|
|
]
|
2012-04-13 13:11:09 +01:00
|
|
|
[count(.//input)=3]
|
2011-04-14 02:38:19 +01:00
|
|
|
'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|