From c879f791c07c698d8ed3d89520956a7a8a0e83d0 Mon Sep 17 00:00:00 2001 From: Sebastiaan Stok Date: Sun, 28 Jun 2015 17:20:57 +0200 Subject: [PATCH] add Symfony routing support for "action" type --- composer.json | 4 +- .../Compiler/RequestUriProviderPass.php | 49 +++ .../ActionTypeExtension.php | 153 ++++++++ .../EventSubscriber/RequestSubscriber.php | 54 +++ .../Symfony/RequestUriProviderByListener.php | 44 +++ .../RequestUriProviderByRequestStack.php | 35 ++ .../Symfony/RequestUriProviderInterface.php | 26 ++ src/Resources/config/services/type.xml | 19 + .../Compiler/RequestUriProviderPassTest.php | 63 ++++ .../ActionTypeExtensionTest.php | 356 ++++++++++++++++++ 10 files changed, 801 insertions(+), 2 deletions(-) create mode 100644 src/DependencyInjection/Compiler/RequestUriProviderPass.php create mode 100644 src/Extension/Symfony/ColumnTypeExtension/ActionTypeExtension.php create mode 100644 src/Extension/Symfony/EventSubscriber/RequestSubscriber.php create mode 100644 src/Extension/Symfony/RequestUriProviderByListener.php create mode 100644 src/Extension/Symfony/RequestUriProviderByRequestStack.php create mode 100644 src/Extension/Symfony/RequestUriProviderInterface.php create mode 100644 tests/DependencyInjection/Compiler/RequestUriProviderPassTest.php create mode 100644 tests/Extension/Symfony/ColumnTypeExtension/ActionTypeExtensionTest.php diff --git a/composer.json b/composer.json index 3c078bc..3a26111 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ ], "require": { "php": ">=5.5.0", - "rollerworks/datagrid": "~0.4", - "rollerworks/datagrid-twig": "~0.2", + "rollerworks/datagrid": "^0.6.1", + "rollerworks/datagrid-twig": "~0.3", "symfony/framework-bundle": "~2.3", "symfony/twig-bundle": "~2.3" }, diff --git a/src/DependencyInjection/Compiler/RequestUriProviderPass.php b/src/DependencyInjection/Compiler/RequestUriProviderPass.php new file mode 100644 index 0000000..60243be --- /dev/null +++ b/src/DependencyInjection/Compiler/RequestUriProviderPass.php @@ -0,0 +1,49 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\DependencyInjection\Compiler; + +use Rollerworks\Component\Datagrid\Twig\Extension\DatagridExtension as TwigDatagridExtension; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Sebastiaan Stok + */ +class RequestUriProviderPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('rollerworks_datagrid.column_extension.action')) { + return; + } + + $definition = $container->getDefinition('rollerworks_datagrid.column_extension.action'); + + // Symfony >=2.4 + if ($container->hasDefinition('request_stack') || $container->hasAlias('request_stack')) { + $definition->addArgument(new Reference('rollerworks_datagrid.request_uri_provider.request_stack')); + + $container->removeDefinition('rollerworks_datagrid.request_uri_provider.request_service'); + $container->removeDefinition('rollerworks_datagrid.event_subscriber.request'); + } else { + // Symfony 2.3 + $definition->addArgument(new Reference('rollerworks_datagrid.request_uri_provider.request_service')); + + $container->removeDefinition('rollerworks_datagrid.request_uri_provider.request_stack'); + } + } +} diff --git a/src/Extension/Symfony/ColumnTypeExtension/ActionTypeExtension.php b/src/Extension/Symfony/ColumnTypeExtension/ActionTypeExtension.php new file mode 100644 index 0000000..01dd5b4 --- /dev/null +++ b/src/Extension/Symfony/ColumnTypeExtension/ActionTypeExtension.php @@ -0,0 +1,153 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Extension\Symfony\ColumnTypeExtension; + +use Rollerworks\Bundle\DatagridBundle\Extension\Symfony\RequestUriProviderInterface; +use Rollerworks\Component\Datagrid\Column\AbstractColumnTypeExtension; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * @author Sebastiaan Stok + */ +class ActionTypeExtension extends AbstractColumnTypeExtension +{ + /** + * Router to generate urls. + * + * @var UrlGeneratorInterface + */ + private $router; + + /** + * RequestUriProvider. + * + * This is used for getting the current URI for redirects. + * + * @var RequestUriProviderInterface + */ + private $requestUriProvider; + + /** + * Constructor. + * + * @param UrlGeneratorInterface $router + * @param RequestUriProviderInterface $requestUriProvider + */ + public function __construct(UrlGeneratorInterface $router, RequestUriProviderInterface $requestUriProvider) + { + $this->router = $router; + $this->requestUriProvider = $requestUriProvider; + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults( + [ + 'route_name' => null, + 'parameters_field_mapping' => [], + 'additional_parameters' => [], + 'uri_scheme' => function (Options $options, $value) { + // Value was already provided so just use that one. + // Always do this check as lazy options don't overwrite. + if (is_string($value)) { + return $value; + } + + if (null !== $options['route_name']) { + return $this->createRouteGenerator( + $options['route_name'], + $options['reference_type'], + $options['parameters_field_mapping'], + $options['additional_parameters'] + ); + } + }, + 'reference_type' => UrlGeneratorInterface::ABSOLUTE_PATH, + + 'redirect_route' => null, + 'redirect_parameters_field_mapping' => [], + 'redirect_additional_parameters' => [], + 'redirect_uri' => function (Options $options, $value) { + // Value was already provided so just use that one. + // Always do this check as lazy options don't overwrite. + if (is_string($value)) { + return $value; + } + + if (null !== $options['redirect_route']) { + return $this->createRouteGenerator( + $options['redirect_route'], + $options['reference_type'], + $options['redirect_parameters_field_mapping'], + $options['redirect_additional_parameters'] + ); + } + + return $this->requestUriProvider->getRequestUri(); + }, + ] + ); + + if ($resolver instanceof OptionsResolverInterface) { + $resolver->setAllowedTypes( + [ + 'route_name' => ['string', 'null'], + 'parameters_field_mapping' => ['array'], + 'additional_parameters' => ['array'], + + 'redirect_route' => ['string', 'null'], + 'redirect_parameters_field_mapping' => ['array'], + 'redirect_additional_parameters' => ['array'], + ] + ); + } else { + $resolver->setAllowedTypes('route_name', ['string', 'null']); + $resolver->setAllowedTypes('parameters_field_mapping', ['array']); + $resolver->setAllowedTypes('additional_parameters', ['array']); + + $resolver->setAllowedTypes('redirect_route', ['string', 'null']); + $resolver->setAllowedTypes('redirect_parameters_field_mapping', ['array']); + $resolver->setAllowedTypes('redirect_additional_parameters', ['array']); + } + } + + /** + * {@inheritdoc} + */ + public function getExtendedType() + { + return 'action'; + } + + private function createRouteGenerator($routeName, $referenceType, array $fieldMapping, array $additionalParameters) + { + return function (array $values) use ($routeName, $referenceType, $fieldMapping, $additionalParameters) { + $routeParameters = []; + + foreach ($fieldMapping as $parameterName => $mappingField) { + $routeParameters[$parameterName] = $values[$mappingField]; + } + + return $this->router->generate( + $routeName, + array_merge($routeParameters, $additionalParameters), + $referenceType + ); + }; + } +} diff --git a/src/Extension/Symfony/EventSubscriber/RequestSubscriber.php b/src/Extension/Symfony/EventSubscriber/RequestSubscriber.php new file mode 100644 index 0000000..86e1947 --- /dev/null +++ b/src/Extension/Symfony/EventSubscriber/RequestSubscriber.php @@ -0,0 +1,54 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Extension\Symfony\EventSubscriber; + +use Rollerworks\Bundle\DatagridBundle\Extension\Symfony\RequestUriProviderByListener; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\KernelEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\KernelEvents; + +class RequestSubscriber implements EventSubscriberInterface +{ + /** + * @var RequestUriProviderByListener + */ + private $uriProvider; + + /** + * @param RequestUriProviderByListener $uriProvider + */ + public function __construct(RequestUriProviderByListener $uriProvider) + { + $this->uriProvider = $uriProvider; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ + KernelEvents::REQUEST => 'onRequest' + ]; + } + + /** + * @param KernelEvent $event + */ + public function onRequest(KernelEvent $event) + { + if ($event->getRequestType() === HttpKernelInterface::MASTER_REQUEST) { + $this->uriProvider->setRequest($event->getRequest()); + } + } +} diff --git a/src/Extension/Symfony/RequestUriProviderByListener.php b/src/Extension/Symfony/RequestUriProviderByListener.php new file mode 100644 index 0000000..564586b --- /dev/null +++ b/src/Extension/Symfony/RequestUriProviderByListener.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Extension\Symfony; + +use Symfony\Component\HttpFoundation\Request; + +class RequestUriProviderByListener implements RequestUriProviderInterface +{ + /** + * @var Request + */ + private $request; + + /** + * @return string + */ + public function getRequestUri() + { + if (null === $this->request) { + throw new \LogicException( + 'No Request set for RequestUriProviderByListener. Do not use this service manually.' + ); + } + + return $this->request->getRequestUri(); + } + + /** + * @param Request $request + */ + public function setRequest(Request $request = null) + { + $this->request = $request; + } +} diff --git a/src/Extension/Symfony/RequestUriProviderByRequestStack.php b/src/Extension/Symfony/RequestUriProviderByRequestStack.php new file mode 100644 index 0000000..14df7e4 --- /dev/null +++ b/src/Extension/Symfony/RequestUriProviderByRequestStack.php @@ -0,0 +1,35 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Extension\Symfony; + +use Symfony\Component\HttpFoundation\RequestStack; + +class RequestUriProviderByRequestStack implements RequestUriProviderInterface +{ + /** + * @var RequestStack + */ + private $requestStack; + + public function __construct(RequestStack $requestStack) + { + $this->requestStack = $requestStack; + } + + /** + * @return string + */ + public function getRequestUri() + { + return $this->requestStack->getMasterRequest()->getRequestUri(); + } +} diff --git a/src/Extension/Symfony/RequestUriProviderInterface.php b/src/Extension/Symfony/RequestUriProviderInterface.php new file mode 100644 index 0000000..c725619 --- /dev/null +++ b/src/Extension/Symfony/RequestUriProviderInterface.php @@ -0,0 +1,26 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Extension\Symfony; + +/** + * The RequestUriProvide provides access to the current URI of the master-request. + * + * This interface only exists to be compatible with Symfony <2.4, + * where the RequestStack did not exist yet. + */ +interface RequestUriProviderInterface +{ + /** + * @return string + */ + public function getRequestUri(); +} diff --git a/src/Resources/config/services/type.xml b/src/Resources/config/services/type.xml index 61a903e..31d52f4 100644 --- a/src/Resources/config/services/type.xml +++ b/src/Resources/config/services/type.xml @@ -47,5 +47,24 @@ + + + + + + + + + + + + + + + + + + + diff --git a/tests/DependencyInjection/Compiler/RequestUriProviderPassTest.php b/tests/DependencyInjection/Compiler/RequestUriProviderPassTest.php new file mode 100644 index 0000000..9364388 --- /dev/null +++ b/tests/DependencyInjection/Compiler/RequestUriProviderPassTest.php @@ -0,0 +1,63 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Tests\DependencyInjection\Compiler; + +use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; +use Rollerworks\Bundle\DatagridBundle\DependencyInjection\Compiler\RequestUriProviderPass; +use Rollerworks\Bundle\DatagridBundle\DependencyInjection\DatagridExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class RequestUriProviderPassTest extends AbstractCompilerPassTestCase +{ + protected function setUp() + { + parent::setUp(); + + $this->container->registerExtension(new DatagridExtension()); + $this->container->loadFromExtension('rollerworks_datagrid'); + } + + public function testSymfony23RequestListener() + { + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithArgument( + 'rollerworks_datagrid.column_extension.action', + 1, + new Reference('rollerworks_datagrid.request_uri_provider.request_service') + ); + + $this->assertFalse($this->container->hasDefinition('rollerworks_datagrid.request_uri_provider.request_stack')); + $this->assertContainerBuilderHasServiceDefinitionWithTag('rollerworks_datagrid.event_subscriber.request', 'kernel.event_subscriber'); + } + + public function testSymfony24AndHigherRequestStack() + { + $this->registerService('request_stack', 'stdClass'); + $this->compile(); + + $this->assertFalse($this->container->hasDefinition('rollerworks_datagrid.request_uri_provider.request_service')); + $this->assertFalse($this->container->hasDefinition('rollerworks_datagrid.event_subscriber.request')); + + $this->assertContainerBuilderHasServiceDefinitionWithArgument( + 'rollerworks_datagrid.column_extension.action', + 1, + new Reference('rollerworks_datagrid.request_uri_provider.request_stack') + ); + } + + protected function registerCompilerPass(ContainerBuilder $container) + { + $container->addCompilerPass(new RequestUriProviderPass()); + } +} diff --git a/tests/Extension/Symfony/ColumnTypeExtension/ActionTypeExtensionTest.php b/tests/Extension/Symfony/ColumnTypeExtension/ActionTypeExtensionTest.php new file mode 100644 index 0000000..5c8a017 --- /dev/null +++ b/tests/Extension/Symfony/ColumnTypeExtension/ActionTypeExtensionTest.php @@ -0,0 +1,356 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Rollerworks\Bundle\DatagridBundle\Tests\Extension\Symfony\ColumnTypeExtension; + +use Rollerworks\Bundle\DatagridBundle\Extension\Symfony\RequestUriProviderInterface; +use Rollerworks\Component\Datagrid\PreloadedExtension; +use Rollerworks\Component\Datagrid\Test\ColumnTypeTestCase; +use Rollerworks\Bundle\DatagridBundle\Extension\Symfony\ColumnTypeExtension\ActionTypeExtension; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +class ActionTypeExtensionTest extends ColumnTypeTestCase +{ + protected function getExtensions() + { + $urlGenerator = $this->prophesize(UrlGeneratorInterface::class); + $urlGenerator->generate('entity_edit', ['id' => 42], false)->will( + function ($args) { + return '/entity/'.$args[1]['id'].'/edit'; + } + ); + + $urlGenerator->generate('entity_edit', ['id' => 42], false)->will( + function ($args) { + return '/entity/'.$args[1]['id'].'/edit'; + } + ); + + $urlGenerator->generate('entity_edit', ['id' => 42, 'foo' => 'bar'], false)->will( + function ($args) { + return '/entity/'.$args[1]['id'].'/edit?foo=bar'; + } + ); + + $urlGenerator->generate('entity_delete', ['id' => 42], false)->will( + function ($args) { + return '/entity/'.$args[1]['id'].'/delete'; + } + ); + + $urlGenerator->generate('entity_list', [], false)->will( + function () { + return '/entity/list'; + } + ); + + $urlGenerator->generate('entity_list', ['filter' => 'something', 'user' => 'sheldon'], false)->will( + function () { + return '/list/?user=sheldon&filter=something'; + } + ); + + $requestUriProvider = $this->prophesize(RequestUriProviderInterface::class); + $requestUriProvider->getRequestUri()->willReturn('/datagrid'); + + return [ + new PreloadedExtension( + [], + [ + 'action' => [ + new ActionTypeExtension($urlGenerator->reveal(), $requestUriProvider->reveal()) + ] + ] + ) + ]; + } + + protected function getTestedType() + { + return 'action'; + } + + public function testPassLabelToView() + { + $column = $this->factory->createColumn( + 'edit', + $this->getTestedType(), + $this->datagrid, + [ + 'content' => 'My label', + 'field_mapping' => ['key'], + 'uri_scheme' => '/entity/{key}/edit', + ] + ); + + $object = new \stdClass(); + $object->key = ' foo '; + $this->datagrid->setData([1 => $object]); + + $datagridView = $this->datagrid->createView(); + $view = $column->createHeaderView($datagridView); + + $this->assertEquals('My label', $view->label); + } + + public function testActionWithAttr() + { + $options = [ + 'uri_scheme' => '/entity/{key}/edit', + 'redirect_uri' => null, + 'content' => 'edit', + 'attr' => ['class' => 'i-edit'], + 'url_attr' => ['data-new-window' => true], + ]; + + $expectedAttributesAttributes = [ + 'url' => '/entity/42/edit', + 'content' => 'edit', + 'attr' => ['class' => 'i-edit'], + 'url_attr' => ['data-new-window' => true], + ]; + + $this->assertCellValueEquals(['key' => 42], 42, $options, $expectedAttributesAttributes); + } + + public function testActionWithUriAsClosure() + { + $options = [ + 'content' => 'Delete', + 'redirect_uri' => null, + 'uri_scheme' => function ($values) { + return '/entity/'.$values['key'].'/delete'; + }, + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/delete', + 'content' => 'Delete', + 'attr' => [], + 'url_attr' => [], + ]; + + $this->assertCellValueEquals(['key' => 42], 42, $options, $expectedAttributes); + } + + public function testActionWithContentAsClosure() + { + $options = [ + 'uri_scheme' => '/entity/{key}/delete', + 'redirect_uri' => null, + 'content' => function ($values) { + return 'Delete #'.$values['key']; + }, + ]; + + $expectedAttributes = [ + 'content' => 'Delete #42', + 'url' => '/entity/42/delete', + 'attr' => [], + 'url_attr' => [], + ]; + + $this->assertCellValueEquals(['key' => 42], 42, $options, $expectedAttributes); + } + + public function testActionWithRedirectUri() + { + $options = [ + 'uri_scheme' => '/entity/{key}/edit', + 'content' => 'edit', + 'redirect_uri' => '/entity/list', + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?redirect_uri=%2Fentity%2Flist', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $this->assertCellValueEquals(['key' => 42], 42, $options, $expectedAttributes); + } + + public function testActionWithRedirectUriWithExistingQueryStringInUrl() + { + $options = [ + 'uri_scheme' => '/entity/{key}/edit?foo=bar', + 'content' => 'delete', + 'redirect_uri' => '/entity/list?filter=something', + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?foo=bar&redirect_uri=%2Fentity%2Flist%3Ffilter%3Dsomething', + 'content' => 'delete', + 'attr' => [], + 'url_attr' => [], + ]; + + $this->assertCellValueEquals(['key' => 42], 42, $options, $expectedAttributes); + } + + public function testActionWithRedirectUriAsClosure() + { + $options = [ + 'uri_scheme' => '/entity/{key}/edit', + 'content' => 'edit', + 'redirect_uri' => function ($values) { + return '/entity/list/?last-entity='.$values['key']; + }, + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?redirect_uri=%2Fentity%2Flist%2F%3Flast-entity%3D42', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $this->assertCellValueEquals(['key' => 42], 42, $options, $expectedAttributes); + } + + public function testActionWithMultipleFields() + { + $options = [ + 'uri_scheme' => '/entity/{id}/edit?name={username}', + 'redirect_uri' => null, + 'content' => 'edit', + 'field_mapping' => ['id' => 'id', 'username' => 'name'], + ]; + + $expectedAttributes = [ + 'url' => '/entity/50/edit?name=sheldon', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $object = new \stdClass(); + $object->id = 50; + $object->name = 'sheldon'; + + $data = [1 => $object]; + + $this->assertCellValueEquals(['id' => 50, 'username' => 'sheldon'], $data, $options, $expectedAttributes); + } + + // --- + + public function testActionWithRouteName() + { + $options = [ + 'route_name' => 'entity_edit', + 'parameters_field_mapping' => ['id' => 'id'], + 'content' => 'edit', + 'field_mapping' => ['id' => 'id', 'username' => 'name'], + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?redirect_uri=%2Fdatagrid', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $object = new \stdClass(); + $object->id = 42; + $object->name = 'sheldon'; + + $data = [1 => $object]; + + $this->assertCellValueEquals(['id' => 42, 'username' => 'sheldon'], $data, $options, $expectedAttributes); + } + + public function testActionWithAdditionalParams() + { + $options = [ + 'route_name' => 'entity_edit', + 'parameters_field_mapping' => ['id' => 'id'], + 'additional_parameters' => ['foo' => 'bar'], + 'content' => 'edit', + 'field_mapping' => ['id' => 'id', 'username' => 'name'], + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?foo=bar&redirect_uri=%2Fdatagrid', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $object = new \stdClass(); + $object->id = 42; + $object->name = 'sheldon'; + + $data = [1 => $object]; + + $this->assertCellValueEquals(['id' => 42, 'username' => 'sheldon'], $data, $options, $expectedAttributes); + } + + public function testActionWithRedirectRouteName() + { + $options = [ + 'route_name' => 'entity_edit', + 'redirect_route' => 'entity_list', + 'parameters_field_mapping' => ['id' => 'id'], + 'content' => 'edit', + 'field_mapping' => ['id' => 'id', 'username' => 'name'], + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?redirect_uri=%2Fentity%2Flist', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $object = new \stdClass(); + $object->id = 42; + $object->name = 'sheldon'; + + $data = [1 => $object]; + + $this->assertCellValueEquals(['id' => 42, 'username' => 'sheldon'], $data, $options, $expectedAttributes); + } + + public function testActionWithRedirectAdditionalParams() + { + $options = [ + 'route_name' => 'entity_edit', + 'parameters_field_mapping' => ['id' => 'id'], + 'additional_parameters' => ['foo' => 'bar'], + + 'redirect_route' => 'entity_list', + 'redirect_parameters_field_mapping' => ['user' => 'username'], + 'redirect_additional_parameters' => ['filter' => 'something'], + + 'content' => 'edit', + 'field_mapping' => ['id' => 'id', 'username' => 'name'], + ]; + + $expectedAttributes = [ + 'url' => '/entity/42/edit?foo=bar&redirect_uri=%2Flist%2F%3Fuser%3Dsheldon%26filter%3Dsomething', + 'content' => 'edit', + 'attr' => [], + 'url_attr' => [], + ]; + + $object = new \stdClass(); + $object->id = 42; + $object->name = 'sheldon'; + + $data = [1 => $object]; + + $this->assertCellValueEquals(['id' => 42, 'username' => 'sheldon'], $data, $options, $expectedAttributes); + } +}