[FrameworkBundle] Add renderForm() helper setting the appropriate HTTP status code

This commit is contained in:
Kévin Dunglas 2021-01-14 18:58:04 +01:00 committed by Fabien Potencier
parent fe49ed2e42
commit 4c77e50e6a
3 changed files with 70 additions and 3 deletions

View File

@ -4,6 +4,7 @@ CHANGELOG
5.3
---
* Added `AbstractController::renderForm()` to render a form and set the appropriate HTTP status code
* Added support for configuring PHP error level to log levels
* Added the `dispatcher` option to `debug:event-dispatcher`
* Added the `event_dispatcher.dispatcher` tag

View File

@ -17,6 +17,7 @@ use Psr\Link\LinkInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
@ -289,6 +290,22 @@ abstract class AbstractController implements ServiceSubscriberInterface
return $response;
}
/**
* Renders a form.
*
* The FormView instance is passed to the template in a variable named "form".
* If the form is invalid, a 422 status code is returned.
*/
public function renderForm(string $view, FormInterface $form, array $parameters = [], Response $response = null): Response
{
$response = $this->render($view, ['form' => $form->createView()] + $parameters, $response);
if ($form->isSubmitted() && !$form->isValid()) {
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
return $response;
}
/**
* Returns a NotFoundHttpException.
*

View File

@ -18,6 +18,8 @@ use Symfony\Component\DependencyInjection\ParameterBag\ContainerBag;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\JsonResponse;
@ -31,6 +33,7 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\WebLink\Link;
use Twig\Environment;
class AbstractControllerTest extends TestCase
{
@ -371,7 +374,7 @@ class AbstractControllerTest extends TestCase
public function testRenderViewTwig()
{
$twig = $this->getMockBuilder(\Twig\Environment::class)->disableOriginalConstructor()->getMock();
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
$twig->expects($this->once())->method('render')->willReturn('bar');
$container = new Container();
@ -385,7 +388,7 @@ class AbstractControllerTest extends TestCase
public function testRenderTwig()
{
$twig = $this->getMockBuilder(\Twig\Environment::class)->disableOriginalConstructor()->getMock();
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
$twig->expects($this->once())->method('render')->willReturn('bar');
$container = new Container();
@ -399,7 +402,7 @@ class AbstractControllerTest extends TestCase
public function testStreamTwig()
{
$twig = $this->getMockBuilder(\Twig\Environment::class)->disableOriginalConstructor()->getMock();
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
$container = new Container();
$container->set('twig', $twig);
@ -410,6 +413,52 @@ class AbstractControllerTest extends TestCase
$this->assertInstanceOf(\Symfony\Component\HttpFoundation\StreamedResponse::class, $controller->stream('foo'));
}
public function testRenderFormTwig()
{
$formView = new FormView();
$form = $this->getMockBuilder(FormInterface::class)->getMock();
$form->expects($this->once())->method('createView')->willReturn($formView);
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
$twig->expects($this->once())->method('render')->with('foo', ['form' => $formView, 'bar' => 'bar'])->willReturn('bar');
$container = new Container();
$container->set('twig', $twig);
$controller = $this->createController();
$controller->setContainer($container);
$response = $controller->renderForm('foo', $form, ['bar' => 'bar']);
$this->assertTrue($response->isSuccessful());
$this->assertSame('bar', $response->getContent());
}
public function testRenderInvalidFormTwig()
{
$formView = new FormView();
$form = $this->getMockBuilder(FormInterface::class)->getMock();
$form->expects($this->once())->method('createView')->willReturn($formView);
$form->expects($this->once())->method('isSubmitted')->willReturn(true);
$form->expects($this->once())->method('isValid')->willReturn(false);
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
$twig->expects($this->once())->method('render')->with('foo', ['form' => $formView, 'bar' => 'bar'])->willReturn('bar');
$container = new Container();
$container->set('twig', $twig);
$controller = $this->createController();
$controller->setContainer($container);
$response = $controller->renderForm('foo', $form, ['bar' => 'bar']);
$this->assertSame(Response::HTTP_UNPROCESSABLE_ENTITY, $response->getStatusCode());
$this->assertSame('bar', $response->getContent());
}
public function testRedirectToRoute()
{
$router = $this->getMockBuilder(\Symfony\Component\Routing\RouterInterface::class)->getMock();