This commit is contained in:
Kevin Adametz 2020-03-07 19:46:02 +01:00
parent a37785b391
commit 33458b2ca3
9915 changed files with 1247019 additions and 0 deletions

View file

@ -0,0 +1,27 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Configuration;
class ConfigurationAnnotationTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException RuntimeException
*/
public function testUndefinedSetterThrowsException()
{
$this->getMockForAbstractClass('Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation', array(
array(
'doesNotExists' => true,
),
));
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Configuration;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
/**
* @author Iltar van der Berg <ivanderberg@hostnet.nl>
*/
class RouteTest extends \PHPUnit_Framework_TestCase
{
public function testSetServiceWithoutPath()
{
$route = new Route(array());
$this->assertNull($route->getPath());
$this->assertNull($route->getService());
$route->setService('app.test');
$this->assertSame('', $route->getPath());
$this->assertSame('app.test', $route->getService());
}
public function testSetServiceWithPath()
{
$route = new Route(array());
$this->assertNull($route->getPath());
$this->assertNull($route->getService());
$route->setPath('/test/');
$route->setService('app.test');
$this->assertSame('/test/', $route->getPath());
$this->assertSame('app.test', $route->getService());
}
public function testSettersViaConstruct()
{
$route = new Route(array('service' => 'app.test'));
$this->assertSame('', $route->getPath());
$this->assertSame('app.test', $route->getService());
$route = new Route(array('service' => 'app.test', 'path' => '/test/'));
$this->assertSame('/test/', $route->getPath());
$this->assertSame('app.test', $route->getService());
}
}

View file

@ -0,0 +1,73 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\DependencyInjection;
use Sensio\Bundle\FrameworkExtraBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class AddExpressionLanguageProvidersPassTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AddExpressionLanguageProvidersPass
*/
private $pass;
/**
* @var ContainerBuilder
*/
private $container;
/**
* @var Definition
*/
private $expressionLangDefinition;
public function setUp()
{
$this->pass = new AddExpressionLanguageProvidersPass();
$this->container = new ContainerBuilder();
$this->expressionLangDefinition = new Definition();
$this->container->setDefinition('sensio_framework_extra.security.expression_language.default', $this->expressionLangDefinition);
}
public function testProcessNoOpNoExpressionLang()
{
$this->container->removeDefinition('sensio_framework_extra.security.expression_language.default');
$this->pass->process($this->container);
}
public function testProcessNoOpNoTaggedServices()
{
$this->pass->process($this->container);
$this->assertCount(0, $this->expressionLangDefinition->getMethodCalls());
}
public function testProcessAddsTaggedServices()
{
$provider = new Definition();
$provider->setTags(array(
'security.expression_language_provider' => array(
array(),
),
));
$this->container->setDefinition('provider', $provider);
$this->pass->process($this->container);
$methodCalls = $this->expressionLangDefinition->getMethodCalls();
$this->assertCount(1, $methodCalls);
$this->assertEquals(array('registerProvider', array(new Reference('provider'))), $methodCalls[0]);
}
}

View file

@ -0,0 +1,97 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\DependencyInjection;
use Sensio\Bundle\FrameworkExtraBundle\DependencyInjection\Compiler\AddParamConverterPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class AddParamConverterPassTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AddParamConverterPass
*/
private $pass;
/**
* @var ContainerBuilder
*/
private $container;
/**
* @var Definition
*/
private $managerDefinition;
public function setUp()
{
$this->pass = new AddParamConverterPass();
$this->container = new ContainerBuilder();
$this->managerDefinition = new Definition();
$this->container->setDefinition('sensio_framework_extra.converter.manager', $this->managerDefinition);
}
public function testProcessNoOpNoManager()
{
$this->container->removeDefinition('sensio_framework_extra.converter.manager');
$this->pass->process($this->container);
}
public function testProcessNoOpNoTaggedServices()
{
$this->pass->process($this->container);
$this->assertCount(0, $this->managerDefinition->getMethodCalls());
}
public function testProcessAddsTaggedServices()
{
$paramConverter1 = new Definition();
$paramConverter1->setTags(array(
'request.param_converter' => array(
array(
'priority' => 'false',
),
),
));
$paramConverter2 = new Definition();
$paramConverter2->setTags(array(
'request.param_converter' => array(
array(
'converter' => 'foo',
),
),
));
$paramConverter3 = new Definition();
$paramConverter3->setTags(array(
'request.param_converter' => array(
array(
'priority' => 5,
),
),
));
$this->container->setDefinition('param_converter_one', $paramConverter1);
$this->container->setDefinition('param_converter_two', $paramConverter2);
$this->container->setDefinition('param_converter_three', $paramConverter3);
$this->pass->process($this->container);
$methodCalls = $this->managerDefinition->getMethodCalls();
$this->assertCount(3, $methodCalls);
$this->assertEquals(array('add', array(new Reference('param_converter_one'), 0, null)), $methodCalls[0]);
$this->assertEquals(array('add', array(new Reference('param_converter_two'), 0, 'foo')), $methodCalls[1]);
$this->assertEquals(array('add', array(new Reference('param_converter_three'), 5, null)), $methodCalls[2]);
}
}

View file

@ -0,0 +1,124 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\DependencyInjection;
use Sensio\Bundle\FrameworkExtraBundle\DependencyInjection\SensioFrameworkExtraExtension;
use Sensio\Bundle\FrameworkExtraBundle\DependencyInjection\Compiler\LegacyPass;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
class SensioFrameworkExtraExtensionTest extends \PHPUnit_Framework_TestCase
{
/**
* @group legacy
*/
public function testLegacySecurityListener()
{
if (interface_exists('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')) {
$this->markTestSkipped();
}
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config'));
$loader->load('security.xml');
$r = new \ReflectionClass('Symfony\Bundle\SecurityBundle\SecurityBundle');
$loader = new XmlFileLoader($container, new FileLocator(dirname($r->getFileName()).'/Resources/config'));
$loader->load('security.xml');
$this->registerLegacyPass($container);
$container->compile();
$securityContext = $container->getDefinition('sensio_framework_extra.security.listener')->getArgument(0);
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $securityContext);
}
public function testSecurityListener()
{
if (!interface_exists('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')) {
$this->markTestSkipped();
}
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config'));
$loader->load('security.xml');
$r = new \ReflectionClass('Symfony\Bundle\SecurityBundle\SecurityBundle');
$loader = new XmlFileLoader($container, new FileLocator(dirname($r->getFileName()).'/Resources/config'));
$loader->load('security.xml');
$this->registerLegacyPass($container);
$container->compile();
$this->assertNull($container->getDefinition('sensio_framework_extra.security.listener')->getArgument(0));
}
public function testDefaultExpressionLanguageConfig()
{
$container = new ContainerBuilder();
$extension = new SensioFrameworkExtraExtension();
$extension->load(array(), $container);
$this->assertAlias($container, 'sensio_framework_extra.security.expression_language.default', 'sensio_framework_extra.security.expression_language');
}
public function testOverrideExpressionLanguageConfig()
{
$container = new ContainerBuilder();
$extension = new SensioFrameworkExtraExtension();
$config = array(
'security' => array(
'expression_language' => 'acme.security.expression_language',
),
);
$container->setDefinition('acme.security.expression_language', new Definition());
$extension->load(array($config), $container);
$this->assertAlias($container, 'acme.security.expression_language', 'sensio_framework_extra.security.expression_language');
}
public function testTemplatingControllerPatterns()
{
$container = new ContainerBuilder();
$extension = new SensioFrameworkExtraExtension();
$config = array(
'templating' => array(
'controller_patterns' => $patterns = array('/foo/', '/bar/', '/foobar/'),
),
);
$extension->load(array($config), $container);
$this->assertEquals($patterns, $container->getDefinition('sensio_framework_extra.view.guesser')->getArgument(1));
}
private function assertAlias(ContainerBuilder $container, $value, $key)
{
$this->assertEquals($value, (string) $container->getAlias($key), sprintf('%s alias is correct', $key));
}
private function registerLegacyPass(ContainerBuilder $container)
{
$passConfig = $container->getCompiler()->getPassConfig();
$passConfig->setAfterRemovingPasses(array());
$passConfig->setBeforeOptimizationPasses(array());
$passConfig->setBeforeRemovingPasses(array());
$passConfig->setOptimizationPasses(array());
$passConfig->setRemovingPasses(array());
$container->addCompilerPass(new LegacyPass());
}
}

View file

@ -0,0 +1,141 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerCacheAtClass;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerCacheAtClassAndMethod;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerCacheAtMethod;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerMultipleCacheAtClass;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerMultipleCacheAtMethod;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerParamConverterAtClassAndMethod;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class ControllerListenerTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->listener = new ControllerListener(new AnnotationReader());
$this->request = $this->createRequest();
// trigger the autoloading of the @Cache annotation
class_exists('Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache');
}
public function tearDown()
{
$this->listener = null;
$this->request = null;
}
public function testCacheAnnotationAtMethod()
{
$controller = new FooControllerCacheAtMethod();
$this->event = $this->getFilterControllerEvent(array($controller, 'barAction'), $this->request);
$this->listener->onKernelController($this->event);
$this->assertNotNull($this->getReadedCache());
$this->assertEquals(FooControllerCacheAtMethod::METHOD_SMAXAGE, $this->getReadedCache()->getSMaxAge());
}
public function testCacheAnnotationAtClass()
{
$controller = new FooControllerCacheAtClass();
$this->event = $this->getFilterControllerEvent(array($controller, 'barAction'), $this->request);
$this->listener->onKernelController($this->event);
$this->assertNotNull($this->getReadedCache());
$this->assertEquals(FooControllerCacheAtClass::CLASS_SMAXAGE, $this->getReadedCache()->getSMaxAge());
}
public function testCacheAnnotationAtClassAndMethod()
{
$controller = new FooControllerCacheAtClassAndMethod();
$this->event = $this->getFilterControllerEvent(array($controller, 'barAction'), $this->request);
$this->listener->onKernelController($this->event);
$this->assertNotNull($this->getReadedCache());
$this->assertEquals(FooControllerCacheAtClassAndMethod::METHOD_SMAXAGE, $this->getReadedCache()->getSMaxAge());
$this->event = $this->getFilterControllerEvent(array($controller, 'bar2Action'), $this->request);
$this->listener->onKernelController($this->event);
$this->assertNotNull($this->getReadedCache());
$this->assertEquals(FooControllerCacheAtClassAndMethod::CLASS_SMAXAGE, $this->getReadedCache()->getSMaxAge());
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage Multiple "cache" annotations are not allowed
*/
public function testMultipleAnnotationsOnClassThrowsExceptionUnlessConfigurationAllowsArray()
{
$controller = new FooControllerMultipleCacheAtClass();
$this->event = $this->getFilterControllerEvent(array($controller, 'barAction'), $this->request);
$this->listener->onKernelController($this->event);
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage Multiple "cache" annotations are not allowed
*/
public function testMultipleAnnotationsOnMethodThrowsExceptionUnlessConfigurationAllowsArray()
{
$controller = new FooControllerMultipleCacheAtMethod();
$this->event = $this->getFilterControllerEvent(array($controller, 'barAction'), $this->request);
$this->listener->onKernelController($this->event);
}
public function testMultipleParamConverterAnnotationsOnMethod()
{
$paramConverter = new \Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter(array());
$controller = new FooControllerParamConverterAtClassAndMethod();
$this->event = $this->getFilterControllerEvent(array($controller, 'barAction'), $this->request);
$this->listener->onKernelController($this->event);
$annotations = $this->request->attributes->get('_converters');
$this->assertNotNull($annotations);
$this->assertArrayHasKey(0, $annotations);
$this->assertInstanceOf('Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter', $annotations[0]);
$this->assertEquals('test', $annotations[0]->getName());
$this->assertArrayHasKey(1, $annotations);
$this->assertInstanceOf('Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter', $annotations[1]);
$this->assertEquals('test2', $annotations[1]->getName());
$this->assertEquals(2, count($annotations));
}
protected function createRequest(Cache $cache = null)
{
return new Request(array(), array(), array(
'_cache' => $cache,
));
}
protected function getFilterControllerEvent($controller, Request $request)
{
$mockKernel = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\Kernel', array('', ''));
return new FilterControllerEvent($mockKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
}
protected function getReadedCache()
{
return $this->request->attributes->get('_cache');
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
/**
* @Cache(smaxage="20")
*/
class FooControllerCacheAtClass
{
const CLASS_SMAXAGE = 20;
public function barAction()
{
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
/**
* @Cache(smaxage="20")
*/
class FooControllerCacheAtClassAndMethod
{
const CLASS_SMAXAGE = 20;
const METHOD_SMAXAGE = 25;
/**
* @Cache(smaxage="25")
*/
public function barAction()
{
}
public function bar2Action()
{
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
class FooControllerCacheAtMethod
{
const METHOD_SMAXAGE = 15;
/**
* @Cache(smaxage="15")
*/
public function barAction()
{
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
/**
* @Cache()
* @Cache()
*/
class FooControllerMultipleCacheAtClass
{
public function barAction()
{
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
class FooControllerMultipleCacheAtMethod
{
/**
* @Cache()
* @Cache()
*/
public function barAction()
{
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
class FooControllerNullableParameter
{
public function requiredParamAction(\DateTime $param)
{
}
public function defaultParamAction(\DateTime $param = null)
{
}
public function nullableParamAction(?\DateTime $param)
{
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* @ParamConverter("test")
*/
class FooControllerParamConverterAtClassAndMethod
{
/**
* @ParamConverter("test2")
*/
public function barAction($test, $test2)
{
}
}

View file

@ -0,0 +1,260 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\EventListener\HttpCacheListener;
class HttpCacheListenerTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->listener = new HttpCacheListener();
$this->response = new Response();
$this->cache = new Cache(array());
$this->request = $this->createRequest($this->cache);
$this->event = $this->createEventMock($this->request, $this->response);
}
public function testWontReassignResponseWhenResponseIsUnsuccessful()
{
$this->event
->expects($this->never())
->method('setResponse')
;
$this->response->setStatusCode(500);
$this->assertInternalType('null', $this->listener->onKernelResponse($this->event));
}
public function testWontReassignResponseWhenNoConfigurationIsPresent()
{
$this->event
->expects($this->never())
->method('setResponse')
;
$this->request->attributes->remove('_cache');
$this->assertInternalType('null', $this->listener->onKernelResponse($this->event));
}
public function testResponseIsPublicIfConfigurationIsPublicTrue()
{
$request = $this->createRequest(new Cache(array(
'public' => true,
)));
$this->listener->onKernelResponse($this->createEventMock($request, $this->response));
$this->assertTrue($this->response->headers->hasCacheControlDirective('public'));
$this->assertFalse($this->response->headers->hasCacheControlDirective('private'));
}
public function testResponseIsPrivateIfConfigurationIsPublicFalse()
{
$request = $this->createRequest(new Cache(array(
'public' => false,
)));
$this->listener->onKernelResponse($this->createEventMock($request, $this->response));
$this->assertFalse($this->response->headers->hasCacheControlDirective('public'));
$this->assertTrue($this->response->headers->hasCacheControlDirective('private'));
}
public function testResponseVary()
{
$vary = array('foobar');
$request = $this->createRequest(new Cache(array('vary' => $vary)));
$this->listener->onKernelResponse($this->createEventMock($request, $this->response));
$this->assertTrue($this->response->hasVary());
$result = $this->response->getVary();
$this->assertEquals($vary, $result);
}
public function testResponseVaryWhenVaryNotSet()
{
$request = $this->createRequest(new Cache(array()));
$vary = array('foobar');
$this->response->setVary($vary);
$this->listener->onKernelResponse($this->createEventMock($request, $this->response));
$this->assertTrue($this->response->hasVary());
$result = $this->response->getVary();
$this->assertFalse(empty($result), 'Existing vary headers should not be removed');
$this->assertEquals($vary, $result, 'Vary header should not be changed');
}
public function testResponseIsPrivateIfConfigurationIsPublicNotSet()
{
$request = $this->createRequest(new Cache(array()));
$this->listener->onKernelResponse($this->createEventMock($request, $this->response));
$this->assertFalse($this->response->headers->hasCacheControlDirective('public'));
}
public function testConfigurationAttributesAreSetOnResponse()
{
$this->assertInternalType('null', $this->response->getMaxAge());
$this->assertInternalType('null', $this->response->getExpires());
$this->assertFalse($this->response->headers->hasCacheControlDirective('s-maxage'));
$this->request->attributes->set('_cache', new Cache(array(
'expires' => 'tomorrow',
'smaxage' => '15',
'maxage' => '15',
)));
$this->listener->onKernelResponse($this->event);
$this->assertEquals('15', $this->response->getMaxAge());
$this->assertEquals('15', $this->response->headers->getCacheControlDirective('s-maxage'));
$this->assertInstanceOf('DateTime', $this->response->getExpires());
}
public function testCacheMaxAgeSupportsStrtotimeFormat()
{
$this->request->attributes->set('_cache', new Cache(array(
'smaxage' => '1 day',
'maxage' => '1 day',
)));
$this->listener->onKernelResponse($this->event);
$this->assertEquals(60 * 60 * 24, $this->response->headers->getCacheControlDirective('s-maxage'));
$this->assertEquals(60 * 60 * 24, $this->response->getMaxAge());
}
public function testLastModifiedNotModifiedResponse()
{
$request = $this->createRequest(new Cache(array('lastModified' => 'test.getDate()')));
$request->attributes->set('test', new TestEntity());
$request->headers->add(array('If-Modified-Since' => 'Fri, 23 Aug 2013 00:00:00 GMT'));
$listener = new HttpCacheListener();
$controllerEvent = new FilterControllerEvent($this->getKernel(), function () { return new Response(500); }, $request, null);
$listener->onKernelController($controllerEvent);
$response = call_user_func($controllerEvent->getController());
$this->assertEquals(304, $response->getStatusCode());
}
public function testLastModifiedHeader()
{
$request = $this->createRequest(new Cache(array('lastModified' => 'test.getDate()')));
$request->attributes->set('test', new TestEntity());
$response = new Response();
$listener = new HttpCacheListener();
$controllerEvent = new FilterControllerEvent($this->getKernel(), function () { return new Response(); }, $request, null);
$listener->onKernelController($controllerEvent);
$responseEvent = new FilterResponseEvent($this->getKernel(), $request, null, call_user_func($controllerEvent->getController()));
$listener->onKernelResponse($responseEvent);
$response = $responseEvent->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->headers->has('Last-Modified'));
$this->assertEquals('Fri, 23 Aug 2013 00:00:00 GMT', $response->headers->get('Last-Modified'));
}
public function testETagNotModifiedResponse()
{
$request = $this->createRequest(new Cache(array('etag' => 'test.getId()')));
$request->attributes->set('test', $entity = new TestEntity());
$request->headers->add(array('If-None-Match' => sprintf('"%s"', hash('sha256', $entity->getId()))));
$listener = new HttpCacheListener();
$controllerEvent = new FilterControllerEvent($this->getKernel(), function () { return new Response(500); }, $request, null);
$listener->onKernelController($controllerEvent);
$response = call_user_func($controllerEvent->getController());
$this->assertEquals(304, $response->getStatusCode());
}
public function testETagHeader()
{
$request = $this->createRequest(new Cache(array('ETag' => 'test.getId()')));
$request->attributes->set('test', $entity = new TestEntity());
$response = new Response();
$listener = new HttpCacheListener();
$controllerEvent = new FilterControllerEvent($this->getKernel(), function () { return new Response(); }, $request, null);
$listener->onKernelController($controllerEvent);
$responseEvent = new FilterResponseEvent($this->getKernel(), $request, null, call_user_func($controllerEvent->getController()));
$listener->onKernelResponse($responseEvent);
$response = $responseEvent->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue($response->headers->has('ETag'));
$this->assertContains(hash('sha256', $entity->getId()), $response->headers->get('ETag'));
}
private function createRequest(Cache $cache = null)
{
return new Request(array(), array(), array(
'_cache' => $cache,
));
}
private function createEventMock(Request $request, Response $response)
{
$event = $this
->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')
->disableOriginalConstructor()
->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->any())
->method('getResponse')
->will($this->returnValue($response))
;
return $event;
}
private function getKernel()
{
return $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
}
}
class TestEntity
{
public function getDate()
{
return new \DateTime('Fri, 23 Aug 2013 00:00:00 GMT');
}
public function getId()
{
return '12345';
}
}

View file

@ -0,0 +1,153 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\EventListener\ParamConverterListener;
use Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener\Fixture\FooControllerNullableParameter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class ParamConverterListenerTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider getControllerWithNoArgsFixtures
*/
public function testRequestIsSkipped($controllerCallable)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$request = new Request();
$listener = new ParamConverterListener($this->getParamConverterManager($request, array()));
$event = new FilterControllerEvent($kernel, $controllerCallable, $request, null);
$listener->onKernelController($event);
}
public function getControllerWithNoArgsFixtures()
{
return array(
array(array(new TestController(), 'noArgAction')),
array(new InvokableNoArgController()),
);
}
/**
* @dataProvider getControllerWithArgsFixtures
*/
public function testAutoConvert($controllerCallable)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$request = new Request(array(), array(), array('date' => '2014-03-14 09:00:00'));
$converter = new ParamConverter(array('name' => 'date', 'class' => 'DateTime'));
$listener = new ParamConverterListener($this->getParamConverterManager($request, array('date' => $converter)));
$event = new FilterControllerEvent($kernel, $controllerCallable, $request, null);
$listener->onKernelController($event);
}
/**
* @dataProvider settingOptionalParamProvider
* @requires PHP 7.1
*/
public function testSettingOptionalParam($function, $isOptional)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$request = new Request();
$converter = new ParamConverter(array('name' => 'param', 'class' => 'DateTime'));
$converter->setIsOptional($isOptional);
$listener = new ParamConverterListener($this->getParamConverterManager($request, array('param' => $converter)), true);
$event = new FilterControllerEvent(
$kernel,
array(
new FooControllerNullableParameter(),
$function,
),
$request,
null
);
$listener->onKernelController($event);
}
public function settingOptionalParamProvider()
{
return array(
array('requiredParamAction', false),
array('defaultParamAction', true),
array('nullableParamAction', true),
);
}
/**
* @dataProvider getControllerWithArgsFixtures
*/
public function testNoAutoConvert($controllerCallable)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$request = new Request(array(), array(), array('date' => '2014-03-14 09:00:00'));
$listener = new ParamConverterListener($this->getParamConverterManager($request, array()), false);
$event = new FilterControllerEvent($kernel, $controllerCallable, $request, null);
$listener->onKernelController($event);
}
public function getControllerWithArgsFixtures()
{
return array(
array(array(new TestController(), 'dateAction')),
array(new InvokableController()),
);
}
protected function getParamConverterManager(Request $request, $configurations)
{
$manager = $this->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager')->getMock();
$manager
->expects($this->once())
->method('apply')
->with($this->equalTo($request), $this->equalTo($configurations))
;
return $manager;
}
}
class TestController
{
public function noArgAction(Request $request)
{
}
public function dateAction(\DateTime $date)
{
}
}
class InvokableNoArgController
{
public function __invoke(Request $request)
{
}
}
class InvokableController
{
public function __invoke(\DateTime $date)
{
}
}

View file

@ -0,0 +1,61 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener;
use Sensio\Bundle\FrameworkExtraBundle\EventListener\PsrResponseListener;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Response;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
* @requires PHP 5.4
*/
class PsrResponseListenerTest extends \PHPUnit_Framework_TestCase
{
public function testConvertsControllerResult()
{
$listener = new PsrResponseListener(new HttpFoundationFactory());
$event = $this->createEventMock(new Response());
$event->expects($this->once())->method('setResponse')->with($this->isInstanceOf('Symfony\Component\HttpFoundation\Response'));
$listener->onKernelView($event);
}
public function testDoesNotConvertControllerResult()
{
$listener = new PsrResponseListener(new HttpFoundationFactory());
$event = $this->createEventMock(array());
$event->expects($this->never())->method('setResponse');
$listener->onKernelView($event);
$event = $this->createEventMock(null);
$event->expects($this->never())->method('setResponse');
$listener->onKernelView($event);
}
private function createEventMock($controllerResult)
{
$event = $this
->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent')
->disableOriginalConstructor()
->getMock()
;
$event
->expects($this->any())
->method('getControllerResult')
->will($this->returnValue($controllerResult))
;
return $event;
}
}

View file

@ -0,0 +1,96 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\EventListener;
use Sensio\Bundle\FrameworkExtraBundle\Security\ExpressionLanguage;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Sensio\Bundle\FrameworkExtraBundle\EventListener\SecurityListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class SecurityListenerTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
* @group legacy
*/
public function testLegacyAccessDenied()
{
if (!interface_exists('Symfony\Component\Security\Core\SecurityContextInterface')) {
$this->markTestSkipped();
}
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token->expects($this->once())->method('getRoles')->will($this->returnValue(array()));
$securityContext = $this->getMockBuilder('Symfony\Component\Security\Core\SecurityContextInterface')->getMock();
$securityContext->expects($this->once())->method('isGranted')->will($this->throwException(new AccessDeniedException()));
$securityContext->expects($this->exactly(2))->method('getToken')->will($this->returnValue($token));
$trustResolver = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock();
$language = new ExpressionLanguage();
$listener = new SecurityListener($securityContext, $language, $trustResolver);
$request = $this->createRequest(new Security(array('expression' => 'has_role("ROLE_ADMIN") or is_granted("FOO")')));
$event = new FilterControllerEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), function () { return new Response(); }, $request, null);
$listener->onKernelController($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
public function testAccessDenied()
{
if (!interface_exists('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')) {
$this->markTestSkipped();
}
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token->expects($this->once())->method('getRoles')->will($this->returnValue(array()));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage->expects($this->exactly(2))->method('getToken')->will($this->returnValue($token));
$authChecker = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface')->getMock();
$authChecker->expects($this->once())->method('isGranted')->will($this->throwException(new AccessDeniedException()));
$trustResolver = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock();
$language = new ExpressionLanguage();
$listener = new SecurityListener(null, $language, $trustResolver, null, $tokenStorage, $authChecker);
$request = $this->createRequest(new Security(array('expression' => 'has_role("ROLE_ADMIN") or is_granted("FOO")')));
$event = new FilterControllerEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), function () { return new Response(); }, $request, null);
$listener->onKernelController($event);
}
private function createRequest(Security $security = null)
{
return new Request(array(), array(), array(
'_security' => $security,
));
}
private function getKernel()
{
return $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
}
}

View file

@ -0,0 +1,18 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\ActionArgumentsBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ActionArgumentsBundle extends Bundle
{
}

View file

@ -0,0 +1,47 @@
<?php
namespace Tests\Fixtures\ActionArgumentsBundle\Controller;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route("/nullable-arguments")
*/
class NullableArgumentsController
{
/**
* @Route("/invoke/")
*/
public function __invoke(RequestInterface $request, MessageInterface $message, ServerRequestInterface $serverRequest)
{
return new Response('<html><body>ok</body></html>');
}
/**
* @Route("/with-default")
*/
public function withDefaultAction(string $d = null)
{
return new Response(null === $d ? 'yes' : 'no');
}
/**
* @Route("/without-default")
*/
public function withoutDefaultAction(string $d)
{
return new Response(null === $d ? 'yes' : 'no');
}
/**
* @Route("/nullable")
*/
public function nullableAction(?string $d)
{
return new Response(null === $d ? 'yes' : 'no');
}
}

View file

@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\FooBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* @Route(service="test.invokable_class_level.predefined")
* @Template("FooBundle:Invokable:predefined.html.twig")
*/
class InvokableClassLevelController
{
/**
* @Route("/invokable/class-level/service/")
*/
public function __invoke()
{
return array(
'foo' => 'bar',
);
}
}

View file

@ -0,0 +1,61 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\FooBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class InvokableContainerController extends Controller
{
/**
* @Route("/invokable/variable/container/{variable}/")
* @Template()
*/
public function variableAction($variable)
{
}
/**
* @Route("/invokable/another-variable/container/{variable}/")
* @Template("FooBundle:InvokableContainer:variable.html.twig")
*/
public function anotherVariableAction($variable)
{
return array(
'variable' => $variable,
);
}
/**
* @Route("/invokable/variable/container/{variable}/{another_variable}/")
* @Template("FooBundle:InvokableContainer:another_variable.html.twig")
*/
public function doubleVariableAction($variable, $another_variable)
{
return array(
'variable' => $variable,
'another_variable' => $another_variable,
);
}
/**
* @Route("/invokable/predefined/container/")
* @Template("FooBundle:Invokable:predefined.html.twig")
*/
public function __invoke()
{
return array(
'foo' => 'bar',
);
}
}

View file

@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\FooBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* @Route(service="test.invokable.predefined")
*/
class InvokableController
{
/**
* @Route("/invokable/predefined/service/")
* @Template("FooBundle:Invokable:predefined.html.twig")
*/
public function __invoke()
{
return array(
'foo' => 'bar',
);
}
}

View file

@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\FooBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
/**
* @Template("FooBundle:Invokable:predefined.html.twig")
*/
class MultipleActionsClassLevelTemplateController extends Controller
{
/**
* @Route("/multi/one-template/1/")
*/
public function firstAction()
{
return array(
'foo' => 'bar',
);
}
/**
* @Route("/multi/one-template/2/")
* @Route("/multi/one-template/3/")
*/
public function secondAction()
{
return array(
'foo' => 'bar',
);
}
/**
* @Route("/multi/one-template/4/")
* @Template("FooBundle::overwritten.html.twig")
*/
public function overwriteAction()
{
return array(
'foo' => 'foo bar baz',
);
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace Tests\Fixtures\FooBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route("/optional-arguments")
*/
class OptionalArgumentsController
{
/**
* @Route("/with-default-followed-by-mandatory", defaults={"e" = null})
* @ParamConverter(name="d", class="Tests\Fixtures\FooBundle\Entity\Foo")
*/
public function withDefaultFollowedByMandatory($d = null, $e)
{
return new Response(null === $d ? 'yes' : 'no');
}
}

View file

@ -0,0 +1,66 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\FooBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route(service="test.simple.multiple")
*/
class SimpleController
{
/**
* @Route("/simple/multiple/", defaults={"a": "a", "b": "b"})
* @Template()
*/
public function someAction($a, $b, $c = 'c')
{
}
/**
* @Route("/simple/multiple/{a}/{b}/")
* @Template("FooBundle:Simple:some.html.twig")
*/
public function someMoreAction($a, $b, $c = 'c')
{
}
/**
* @Route("/simple/multiple-with-vars/", defaults={"a": "a", "b": "b"})
* @Template(vars={"a", "b"})
*/
public function anotherAction($a, $b, $c = 'c')
{
}
/**
* @Route("/no-listener/")
*/
public function noListenerAction()
{
return new Response('<html><body>I did not get rendered via twig</body></html>');
}
/**
* @Route("/streamed/")
* @Template(isStreamable=true)
*/
public function streamedAction()
{
return array(
'foo' => 'foo',
'bar' => 'bar',
);
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Tests\Fixtures\FooBundle\Entity;
use Doctrine\ORM\Mapping;
/**
* @Mapping\Entity
*/
class Foo
{
/**
* @Mapping\Column(type="integer")
* @Mapping\Id
* @Mapping\GeneratedValue(strategy="AUTO")
*/
private $id;
}

View file

@ -0,0 +1,18 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures\FooBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class FooBundle extends Bundle
{
}

View file

@ -0,0 +1 @@
<html><body>{{ variable }},{{ another_variable }}</body></html>

View file

@ -0,0 +1 @@
<html><body>{{ a }}, {{ b }}</body></html>

View file

@ -0,0 +1 @@
<html><body>{{ a }}, {{ b }}, {{ c }}</body></html>

View file

@ -0,0 +1 @@
<html><body>{{ foo }}, {{ bar }}</body></html>

View file

@ -0,0 +1 @@
<html><body>{{ foo }}</body></html>

View file

@ -0,0 +1,49 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Tests\Fixtures;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
/**
* Used for functional tests.
*/
class TestKernel extends Kernel
{
public function registerBundles()
{
return array(
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new \Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new \Symfony\Bundle\TwigBundle\TwigBundle(),
new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new \Tests\Fixtures\FooBundle\FooBundle(),
new \Tests\Fixtures\ActionArgumentsBundle\ActionArgumentsBundle(),
);
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config.yml');
if (PHP_VERSION_ID >= 70100) {
$loader->load(__DIR__.'/config/nullable_type/config.yml');
}
}
public function getCacheDir()
{
return $this->rootDir.'/cache/'.$this->environment;
}
}
class_alias('Tests\Fixtures\TestKernel', 'TestKernel');

View file

@ -0,0 +1,24 @@
framework:
test: true
secret: test
templating:
engine: [twig, php]
router:
resource: "%kernel.root_dir%/config/routing.yml"
doctrine:
dbal:
driver: pdo_sqlite
path: "%kernel.root_dir%/data/db.sqlite"
orm:
auto_mapping: true
services:
test.invokable.predefined:
class: Tests\Fixtures\FooBundle\Controller\InvokableController
test.invokable_class_level.predefined:
class: Tests\Fixtures\FooBundle\Controller\InvokableClassLevelController
test.simple.multiple:
class: Tests\Fixtures\FooBundle\Controller\SimpleController

View file

@ -0,0 +1,3 @@
framework:
router:
resource: '%kernel.root_dir%/config/nullable_type/routing.yml'

View file

@ -0,0 +1,7 @@
foo_bundle:
resource: "@FooBundle/Controller"
type: annotation
action_arguments_bundle:
resource: "@ActionArgumentsBundle/Controller"
type: annotation

View file

@ -0,0 +1,3 @@
foo_bundle:
resource: "@FooBundle/Controller"
type: annotation

View file

@ -0,0 +1,33 @@
<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @requires PHP 7.1
*/
class NullableAnnotationTest extends WebTestCase
{
public function testMissingRequiredArgumentWillResultWithError()
{
$client = self::createClient();
$client->request('GET', '/nullable-arguments/without-default');
$this->assertSame(500, $client->getResponse()->getStatusCode());
}
public function testArgumentWithDefaultIsOptional()
{
$client = self::createClient();
$crawler = $client->request('GET', '/nullable-arguments/with-default');
$this->assertSame('yes', $crawler->text());
}
public function testNullableArgumentIsOptional()
{
$client = self::createClient();
$crawler = $client->request('GET', '/nullable-arguments/nullable');
$this->assertSame('yes', $crawler->text());
}
}

View file

@ -0,0 +1,14 @@
<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class OptionalArgumentsTest extends WebTestCase
{
public function testArgumentWithDefaultFollowedByMandatoryIsOptional()
{
$client = self::createClient();
$crawler = $client->request('GET', '/optional-arguments/with-default-followed-by-mandatory');
$this->assertSame('yes', $crawler->text());
}
}

View file

@ -0,0 +1,61 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\DomCrawler\Crawler;
class TemplateAnnotationTest extends WebTestCase
{
/**
* @dataProvider urlProvider
*/
public function testController($url, $checkHtml)
{
$client = self::createClient();
$crawler = $client->request('GET', $url);
$this->assertEquals($checkHtml, $crawler->filterXPath('//body')->html());
}
public static function urlProvider()
{
return array(
array('/multi/one-template/1/', 'bar'),
array('/multi/one-template/2/', 'bar'),
array('/multi/one-template/3/', 'bar'),
array('/multi/one-template/4/', 'foo bar baz'),
array('/invokable/predefined/service/', 'bar'),
array('/invokable/class-level/service/', 'bar'),
array('/simple/multiple/', 'a, b, c'),
array('/simple/multiple/henk/bar/', 'henk, bar, c'),
array('/simple/multiple-with-vars/', 'a, b'),
array('/invokable/predefined/container/', 'bar'),
array('/invokable/variable/container/the-var/', 'the-var'),
array('/invokable/another-variable/container/another-var/', 'another-var'),
array('/invokable/variable/container/the-var/another-var/', 'the-var,another-var'),
array('/no-listener/', 'I did not get rendered via twig'),
);
}
public function testStreamedControllerResponse()
{
$uri = '/streamed/';
ob_start();
$client = self::createClient();
$client->request('GET', $uri);
$crawler = new Crawler(null, $uri);
$crawler->addContent(ob_get_clean());
$this->assertEquals('foo, bar', $crawler->filterXPath('//body')->html());
}
}

View file

@ -0,0 +1,101 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DateTimeParamConverter;
class DateTimeParamConverterTest extends \PHPUnit_Framework_TestCase
{
private $converter;
public function setUp()
{
$this->converter = new DateTimeParamConverter();
}
public function testSupports()
{
$config = $this->createConfiguration('DateTime');
$this->assertTrue($this->converter->supports($config));
$config = $this->createConfiguration(__CLASS__);
$this->assertFalse($this->converter->supports($config));
$config = $this->createConfiguration();
$this->assertFalse($this->converter->supports($config));
}
public function testApply()
{
$request = new Request(array(), array(), array('start' => '2012-07-21 00:00:00'));
$config = $this->createConfiguration('DateTime', 'start');
$this->converter->apply($request, $config);
$this->assertInstanceOf('DateTime', $request->attributes->get('start'));
$this->assertEquals('2012-07-21', $request->attributes->get('start')->format('Y-m-d'));
}
public function testApplyInvalidDate404Exception()
{
$request = new Request(array(), array(), array('start' => 'Invalid DateTime Format'));
$config = $this->createConfiguration('DateTime', 'start');
$this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'Invalid date given for parameter "start".');
$this->converter->apply($request, $config);
}
public function testApplyWithFormatInvalidDate404Exception()
{
$request = new Request(array(), array(), array('start' => '2012-07-21'));
$config = $this->createConfiguration('DateTime', 'start');
$config->expects($this->any())->method('getOptions')->will($this->returnValue(array('format' => 'd.m.Y')));
$this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', 'Invalid date given for parameter "start".');
$this->converter->apply($request, $config);
}
public function testApplyOptionalWithEmptyAttribute()
{
$request = new Request(array(), array(), array('start' => null));
$config = $this->createConfiguration('DateTime', 'start');
$config->expects($this->once())
->method('isOptional')
->will($this->returnValue(true));
$this->assertFalse($this->converter->apply($request, $config));
$this->assertNull($request->attributes->get('start'));
}
public function createConfiguration($class = null, $name = null)
{
$config = $this
->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter')
->setMethods(array('getClass', 'getAliasName', 'getOptions', 'getName', 'allowArray', 'isOptional'))
->disableOriginalConstructor()
->getMock();
if ($name !== null) {
$config->expects($this->any())
->method('getName')
->will($this->returnValue($name));
}
if ($class !== null) {
$config->expects($this->any())
->method('getClass')
->will($this->returnValue($class));
}
return $config;
}
}

View file

@ -0,0 +1,468 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter;
use Doctrine\Common\Persistence\ManagerRegistry;
class DoctrineParamConverterTest extends \PHPUnit_Framework_TestCase
{
/**
* @var ManagerRegistry
*/
private $registry;
/**
* @var DoctrineParamConverter
*/
private $converter;
public function setUp()
{
$this->registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')->getMock();
$this->converter = new DoctrineParamConverter($this->registry);
}
public function createConfiguration($class = null, array $options = null, $name = 'arg', $isOptional = false)
{
$methods = array('getClass', 'getAliasName', 'getOptions', 'getName', 'allowArray');
if (null !== $isOptional) {
$methods[] = 'isOptional';
}
$config = $this
->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter')
->setMethods($methods)
->disableOriginalConstructor()
->getMock();
if ($options !== null) {
$config->expects($this->once())
->method('getOptions')
->will($this->returnValue($options));
}
if ($class !== null) {
$config->expects($this->any())
->method('getClass')
->will($this->returnValue($class));
}
$config->expects($this->any())
->method('getName')
->will($this->returnValue($name));
if (null !== $isOptional) {
$config->expects($this->any())
->method('isOptional')
->will($this->returnValue($isOptional));
}
return $config;
}
public function testApplyWithNoIdAndData()
{
$request = new Request();
$config = $this->createConfiguration(null, array());
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$this->setExpectedException('LogicException');
$this->converter->apply($request, $config);
}
public function testApplyWithNoIdAndDataOptional()
{
$request = new Request();
$config = $this->createConfiguration(null, array(), 'arg', true);
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertNull($request->attributes->get('arg'));
}
public function testApplyWithStripNulls()
{
$request = new Request();
$request->attributes->set('arg', null);
$config = $this->createConfiguration('stdClass', array('mapping' => array('arg' => 'arg'), 'strip_null' => true), 'arg', true);
$classMetadata = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')->getMock();
$manager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$manager->expects($this->once())
->method('getClassMetadata')
->with('stdClass')
->will($this->returnValue($classMetadata));
$manager->expects($this->never())
->method('getRepository');
$this->registry->expects($this->once())
->method('getManagerForClass')
->with('stdClass')
->will($this->returnValue($manager));
$classMetadata->expects($this->once())
->method('hasField')
->with($this->equalTo('arg'))
->will($this->returnValue(true));
$this->converter->apply($request, $config);
$this->assertNull($request->attributes->get('arg'));
}
/**
* @dataProvider idsProvider
*/
public function testApplyWithId($id)
{
$request = new Request();
$request->attributes->set('id', $id);
$config = $this->createConfiguration('stdClass', array('id' => 'id'), 'arg');
$manager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$objectRepository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository')->getMock();
$this->registry->expects($this->once())
->method('getManagerForClass')
->with('stdClass')
->will($this->returnValue($manager));
$manager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($objectRepository));
$objectRepository->expects($this->once())
->method('find')
->with($this->equalTo($id))
->will($this->returnValue($object = new \stdClass()));
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertSame($object, $request->attributes->get('arg'));
}
public function testUsedProperIdentifier()
{
$request = new Request();
$request->attributes->set('id', 1);
$request->attributes->set('entity_id', null);
$request->attributes->set('arg', null);
$config = $this->createConfiguration('stdClass', array('id' => 'entity_id'), 'arg', null);
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertNull($request->attributes->get('arg'));
}
public function idsProvider()
{
return array(
array(1),
array(0),
array('foo'),
);
}
public function testApplyGuessOptional()
{
$request = new Request();
$request->attributes->set('arg', null);
$config = $this->createConfiguration('stdClass', array(), 'arg', null);
$classMetadata = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')->getMock();
$manager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$manager->expects($this->once())
->method('getClassMetadata')
->with('stdClass')
->will($this->returnValue($classMetadata));
$objectRepository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository')->getMock();
$this->registry->expects($this->once())
->method('getManagerForClass')
->with('stdClass')
->will($this->returnValue($manager));
$manager->expects($this->never())->method('getRepository');
$objectRepository->expects($this->never())->method('find');
$objectRepository->expects($this->never())->method('findOneBy');
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertNull($request->attributes->get('arg'));
}
public function testApplyWithMappingAndExclude()
{
$request = new Request();
$request->attributes->set('foo', 1);
$request->attributes->set('bar', 2);
$config = $this->createConfiguration(
'stdClass',
array('mapping' => array('foo' => 'Foo'), 'exclude' => array('bar')),
'arg'
);
$manager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$metadata = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')->getMock();
$repository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository')->getMock();
$this->registry->expects($this->once())
->method('getManagerForClass')
->with('stdClass')
->will($this->returnValue($manager));
$manager->expects($this->once())
->method('getClassMetadata')
->with('stdClass')
->will($this->returnValue($metadata));
$manager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($repository));
$metadata->expects($this->once())
->method('hasField')
->with($this->equalTo('Foo'))
->will($this->returnValue(true));
$repository->expects($this->once())
->method('findOneBy')
->with($this->equalTo(array('Foo' => 1)))
->will($this->returnValue($object = new \stdClass()));
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertSame($object, $request->attributes->get('arg'));
}
public function testApplyWithRepositoryMethod()
{
$request = new Request();
$request->attributes->set('id', 1);
$config = $this->createConfiguration(
'stdClass',
array('repository_method' => 'getClassName'),
'arg'
);
$objectRepository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository')->getMock();
$manager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$manager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($objectRepository));
$this->registry->expects($this->once())
->method('getManagerForClass')
->will($this->returnValue($manager));
$objectRepository->expects($this->once())
->method('getClassName')
->will($this->returnValue($className = 'ObjectRepository'));
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertSame($className, $request->attributes->get('arg'));
}
public function testApplyWithRepositoryMethodAndMapping()
{
$request = new Request();
$request->attributes->set('id', 1);
$config = $this->createConfiguration(
'stdClass',
array('repository_method' => 'getClassName', 'mapping' => array('foo' => 'Foo')),
'arg'
);
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$objectRepository = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectRepository')->getMock();
$metadata = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')->getMock();
$objectManager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($objectRepository));
$this->registry->expects($this->once())
->method('getManagerForClass')
->will($this->returnValue($objectManager));
$metadata->expects($this->once())
->method('hasField')
->with($this->equalTo('Foo'))
->will($this->returnValue(true));
$objectManager->expects($this->once())
->method('getClassMetadata')
->will($this->returnValue($metadata));
$objectManager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($objectRepository));
$objectRepository->expects($this->once())
->method('getClassName')
->will($this->returnValue($className = 'ObjectRepository'));
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertSame($className, $request->attributes->get('arg'));
}
public function testApplyWithRepositoryMethodAndMapMethodSignature()
{
$request = new Request();
$request->attributes->set('first_name', 'Fabien');
$request->attributes->set('last_name', 'Potencier');
$config = $this->createConfiguration(
'stdClass',
array(
'repository_method' => 'findByFullName',
'mapping' => array('first_name' => 'firstName', 'last_name' => 'lastName'),
'map_method_signature' => true,
),
'arg'
);
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$objectRepository = new TestUserRepository();
$metadata = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')->getMock();
$objectManager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($objectRepository));
$this->registry->expects($this->once())
->method('getManagerForClass')
->will($this->returnValue($objectManager));
$objectManager->expects($this->once())
->method('getClassMetadata')
->will($this->returnValue($metadata));
$ret = $this->converter->apply($request, $config);
$this->assertTrue($ret);
$this->assertSame('Fabien Potencier', $request->attributes->get('arg'));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Repository method "Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter\TestUserRepository::findByFullName" requires that you provide a value for the "$lastName" argument.
*/
public function testApplyWithRepositoryMethodAndMapMethodSignatureException()
{
$request = new Request();
$request->attributes->set('first_name', 'Fabien');
$request->attributes->set('last_name', 'Potencier');
$config = $this->createConfiguration(
'stdClass',
array(
'repository_method' => 'findByFullName',
'mapping' => array('first_name' => 'firstName', 'last_name' => 'lastNameXxx'),
'map_method_signature' => true,
),
'arg'
);
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$objectRepository = new TestUserRepository();
$metadata = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')->getMock();
$objectManager->expects($this->once())
->method('getRepository')
->with('stdClass')
->will($this->returnValue($objectRepository));
$this->registry->expects($this->once())
->method('getManagerForClass')
->will($this->returnValue($objectManager));
$objectManager->expects($this->once())
->method('getClassMetadata')
->will($this->returnValue($metadata));
$this->converter->apply($request, $config);
}
public function testSupports()
{
$config = $this->createConfiguration('stdClass', array());
$metadataFactory = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadataFactory')->getMock();
$metadataFactory->expects($this->once())
->method('isTransient')
->with($this->equalTo('stdClass'))
->will($this->returnValue(false));
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$objectManager->expects($this->once())
->method('getMetadataFactory')
->will($this->returnValue($metadataFactory));
$this->registry->expects($this->once())
->method('getManagers')
->will($this->returnValue(array($objectManager)));
$this->registry->expects($this->once())
->method('getManagerForClass')
->with('stdClass')
->will($this->returnValue($objectManager));
$ret = $this->converter->supports($config);
$this->assertTrue($ret, 'Should be supported');
}
public function testSupportsWithConfiguredEntityManager()
{
$config = $this->createConfiguration('stdClass', array('entity_manager' => 'foo'));
$metadataFactory = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadataFactory')->getMock();
$metadataFactory->expects($this->once())
->method('isTransient')
->with($this->equalTo('stdClass'))
->will($this->returnValue(false));
$objectManager = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')->getMock();
$objectManager->expects($this->once())
->method('getMetadataFactory')
->will($this->returnValue($metadataFactory));
$this->registry->expects($this->once())
->method('getManagers')
->will($this->returnValue(array($objectManager)));
$this->registry->expects($this->once())
->method('getManager')
->with('foo')
->will($this->returnValue($objectManager));
$ret = $this->converter->supports($config);
$this->assertTrue($ret, 'Should be supported');
}
}

View file

@ -0,0 +1,175 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager;
use Sensio\Bundle\FrameworkExtraBundle\Configuration;
use Symfony\Component\HttpFoundation\Request;
class ParamConverterManagerTest extends \PHPUnit_Framework_TestCase
{
public function testPriorities()
{
$manager = new ParamConverterManager();
$this->assertEquals(array(), $manager->all());
$high = $this->createParamConverterMock();
$low = $this->createParamConverterMock();
$manager->add($low);
$manager->add($high, 10);
$this->assertEquals(array($high, $low), $manager->all());
}
public function testApply()
{
$supported = $this->createParamConverterMock();
$supported
->expects($this->once())
->method('supports')
->will($this->returnValue(true))
;
$supported
->expects($this->once())
->method('apply')
->will($this->returnValue(false))
;
$invalid = $this->createParamConverterMock();
$invalid
->expects($this->once())
->method('supports')
->will($this->returnValue(false))
;
$invalid
->expects($this->never())
->method('apply')
;
$configurations = array(
new Configuration\ParamConverter(array(
'name' => 'var',
)),
);
$manager = new ParamConverterManager();
$manager->add($supported);
$manager->add($invalid);
$manager->apply(new Request(), $configurations);
}
public function testApplyNamedConverter()
{
$converter = $this->createParamConverterMock();
$converter
->expects($this->any())
->method('supports')
->will($this->returnValue(true))
;
$converter
->expects($this->any())
->method('apply')
;
$request = new Request();
$request->attributes->set('param', '1234');
$configuration = new Configuration\ParamConverter(array(
'name' => 'param',
'class' => 'stdClass',
'converter' => 'test',
));
$manager = new ParamConverterManager();
$manager->add($converter, 0, 'test');
$manager->apply($request, array($configuration));
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Converter 'test' does not support conversion of parameter 'param'.
*/
public function testApplyNamedConverterNotSupportsParameter()
{
$converter = $this->createParamConverterMock();
$converter
->expects($this->any())
->method('supports')
->will($this->returnValue(false))
;
$request = new Request();
$request->attributes->set('param', '1234');
$configuration = new Configuration\ParamConverter(array(
'name' => 'param',
'class' => 'stdClass',
'converter' => 'test',
));
$manager = new ParamConverterManager();
$manager->add($converter, 0, 'test');
$manager->apply($request, array($configuration));
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage No converter named 'test' found for conversion of parameter 'param'.
*/
public function testApplyNamedConverterNoConverter()
{
$request = new Request();
$request->attributes->set('param', '1234');
$configuration = new Configuration\ParamConverter(array(
'name' => 'param',
'class' => 'stdClass',
'converter' => 'test',
));
$manager = new ParamConverterManager();
$manager->apply($request, array($configuration));
}
public function testApplyNotCalledOnAlreadyConvertedObjects()
{
$converter = $this->createParamConverterMock();
$converter
->expects($this->never())
->method('supports')
;
$converter
->expects($this->never())
->method('apply')
;
$request = new Request();
$request->attributes->set('converted', new \stdClass());
$configuration = new Configuration\ParamConverter(array(
'name' => 'converted',
'class' => 'stdClass',
));
$manager = new ParamConverterManager();
$manager->add($converter);
$manager->apply($request, array($configuration));
}
protected function createParamConverterMock()
{
return $this->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface')->getMock();
}
}

View file

@ -0,0 +1,84 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\PsrServerRequestParamConverter;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Component\HttpFoundation\Request;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
* @requires PHP 5.4
*/
class PsrServerRequestParamConverterTest extends \PHPUnit_Framework_TestCase
{
public function testSupports()
{
$converter = new PsrServerRequestParamConverter(new DiactorosFactory());
$config = $this->createConfiguration('Psr\Http\Message\ServerRequestInterface');
$this->assertTrue($converter->supports($config));
$config = $this->createConfiguration('Psr\Http\Message\RequestInterface');
$this->assertTrue($converter->supports($config));
$config = $this->createConfiguration('Psr\Http\Message\MessageInterface');
$this->assertTrue($converter->supports($config));
$config = $this->createConfiguration(__CLASS__);
$this->assertFalse($converter->supports($config));
$config = $this->createConfiguration();
$this->assertFalse($converter->supports($config));
}
public function testApply()
{
$converter = new PsrServerRequestParamConverter(new DiactorosFactory());
$request = new Request(
array('foo' => 'bar'),
array(),
array(),
array(),
array(),
array('HTTP_HOST' => 'dunglas.fr')
);
$config = $this->createConfiguration('Psr\Http\Message\ServerRequestInterface', 'request');
$converter->apply($request, $config);
$this->assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $request->attributes->get('request'));
$this->assertEquals('bar', $request->query->get('foo'));
}
private function createConfiguration($class = null, $name = null)
{
$config = $this
->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter')
->setMethods(array('getClass', 'getAliasName', 'getOptions', 'getName', 'allowArray', 'isOptional'))
->disableOriginalConstructor()
->getMock()
;
if (null !== $name) {
$config->expects($this->any())
->method('getName')
->will($this->returnValue($name));
}
if (null !== $class) {
$config->expects($this->any())
->method('getClass')
->will($this->returnValue($class));
}
return $config;
}
}

View file

@ -0,0 +1,23 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Request\ParamConverter;
/*
* This class is a helper Repository for DoctrineParamConverter's map_method_signature functionality
*/
class TestUserRepository
{
public function findByFullName($firstName, $lastName)
{
return $firstName.' '.$lastName;
}
}

View file

@ -0,0 +1,141 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Routing;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader;
class AnnotatedRouteControllerLoaderTest extends \PHPUnit_Framework_TestCase
{
public function testServiceOptionIsAllowedOnClass()
{
$route = $this->getMockBuilder('Symfony\Component\Routing\Route')
->setMethods(array('setDefault'))
->disableOriginalConstructor()
->getMock()
;
$route
->expects($this->once())
->method('setDefault')
->with('_controller', 'service:testServiceOptionIsAllowedOnClass')
;
$annotation = new Route(array());
$annotation->setService('service');
$reader = $this->getMockBuilder('Doctrine\Common\Annotations\Reader')
->setMethods(array('getClassAnnotation', 'getMethodAnnotations'))
->disableOriginalConstructor()
->getMockForAbstractClass()
;
$reader
->expects($this->once())
->method('getClassAnnotation')
->will($this->returnValue($annotation))
;
$reader
->expects($this->once())
->method('getMethodAnnotations')
->will($this->returnValue(array()))
;
$loader = $this->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader')
->setConstructorArgs(array($reader))
->getMock()
;
$r = new \ReflectionMethod($loader, 'configureRoute');
$r->setAccessible(true);
$r->invoke(
$loader,
$route,
new \ReflectionClass($this),
new \ReflectionMethod($this, 'testServiceOptionIsAllowedOnClass'),
null
);
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage The service option can only be specified at class level.
*/
public function testServiceOptionIsNotAllowedOnMethod()
{
$route = $this->getMockBuilder('Symfony\Component\Routing\Route')
->disableOriginalConstructor()
->getMock()
;
$reader = $this->getMockBuilder('Doctrine\Common\Annotations\Reader')
->setMethods(array('getClassAnnotation', 'getMethodAnnotations'))
->disableOriginalConstructor()
->getMockForAbstractClass()
;
$annotation = new Route(array());
$annotation->setService('service');
$reader
->expects($this->once())
->method('getClassAnnotation')
->will($this->returnValue(null))
;
$reader
->expects($this->once())
->method('getMethodAnnotations')
->will($this->returnValue(array($annotation)))
;
$loader = $this->getMockBuilder('Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader')
->setConstructorArgs(array($reader))
->getMock()
;
$r = new \ReflectionMethod($loader, 'configureRoute');
$r->setAccessible(true);
$r->invoke(
$loader,
$route,
new \ReflectionClass($this),
new \ReflectionMethod($this, 'testServiceOptionIsNotAllowedOnMethod'),
null
);
}
public function testLoad()
{
$loader = new AnnotatedRouteControllerLoader(new AnnotationReader());
AnnotationRegistry::registerLoader('class_exists');
$rc = $loader->load('Sensio\Bundle\FrameworkExtraBundle\Tests\Routing\Fixtures\FoobarController');
$this->assertInstanceOf('Symfony\Component\Routing\RouteCollection', $rc);
$this->assertCount(2, $rc);
$this->assertInstanceOf('Symfony\Component\Routing\Route', $rc->get('index'));
// depending on the Symfony version, it can return GET or an empty array (on 2.3)
// which has the same behavior anyway
$methods = $rc->get('index')->getMethods();
$this->assertTrue(empty($methods) || array('GET') == $methods);
$this->assertInstanceOf('Symfony\Component\Routing\Route', $rc->get('new'));
$this->assertEquals(array('POST'), $rc->get('new')->getMethods());
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Routing\Fixtures;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
/**
* @Route("/base")
* @Method("GET")
*/
class FoobarController
{
/**
* @Route("/", name="index")
*/
public function indexAction()
{
}
/**
* @Route("/new", name="new")
* @Method("POST")
*/
public function newAction()
{
}
}

View file

@ -0,0 +1,7 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\BarBundle\Controller;
class BarController
{
}

View file

@ -0,0 +1,7 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\Controller;
class OutOfBundleController
{
}

View file

@ -0,0 +1,7 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\FooBarBundle\Controller;
class FooBarController
{
}

View file

@ -0,0 +1,7 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\FooBundle\Action;
class FooAction
{
}

View file

@ -0,0 +1,7 @@
<?php
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\FooBundle\Controller;
class FooController
{
}

View file

@ -0,0 +1,207 @@
<?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.
*/
namespace Sensio\Bundle\FrameworkExtraBundle\Tests\Templating;
use Sensio\Bundle\FrameworkExtraBundle\Templating\TemplateGuesser;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;
class TemplateGuesserTest extends \PHPUnit_Framework_TestCase
{
/**
* @var KernelInterface
*/
private $kernel;
private $bundles = array();
public function setUp()
{
$this->bundles['FooBundle'] = $this->getBundle('FooBundle', 'Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\FooBundle');
$this->bundles['BarBundle'] = $this->getBundle('BarBundle', 'Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\BarBundle', 'FooBundle');
$this->bundles['FooBarBundle'] = $this->getBundle('FooBarBundle', 'Sensio\Bundle\FrameworkExtraBundle\Tests\Templating\Fixture\FooBarBundle', 'BarBundle');
$this->kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\KernelInterface')->getMock();
$this->kernel
->expects($this->once())
->method('getBundles')
->will($this->returnValue(array_values($this->bundles)));
}
public function testGuessTemplateName()
{
$this->kernel
->expects($this->never())
->method('getBundle');
$templateGuesser = new TemplateGuesser($this->kernel);
$templateReference = $templateGuesser->guessTemplateName(array(
new Fixture\FooBundle\Controller\FooController(),
'indexAction',
), new Request());
$this->assertEquals('FooBundle:Foo:index.html.twig', (string) $templateReference);
}
public function testGuessTemplateNameWithParentBundle()
{
$this->kernel
->expects($this->once())
->method('getBundle')
->with($this->equalTo('FooBundle'), false)
->will($this->returnValue(array($this->bundles['BarBundle'], $this->bundles['FooBundle'])));
$templateGuesser = new TemplateGuesser($this->kernel);
$templateReference = $templateGuesser->guessTemplateName(array(
new Fixture\BarBundle\Controller\BarController(),
'indexAction',
), new Request());
$this->assertEquals('FooBundle:Bar:index.html.twig', (string) $templateReference);
}
public function testGuessTemplateNameWithCascadingParentBundle()
{
$this->kernel
->expects($this->at(1))
->method('getBundle')
->with($this->equalTo('BarBundle'), false)
->will($this->returnValue(array($this->bundles['FooBarBundle'], $this->bundles['BarBundle'])));
$this->kernel
->expects($this->at(2))
->method('getBundle')
->with($this->equalTo('FooBundle'), false)
->will($this->returnValue(array($this->bundles['FooBarBundle'], $this->bundles['BarBundle'], $this->bundles['FooBundle'])));
$templateGuesser = new TemplateGuesser($this->kernel);
$templateReference = $templateGuesser->guessTemplateName(array(
new Fixture\FooBarBundle\Controller\FooBarController(),
'indexAction',
), new Request());
$this->assertEquals('FooBundle:FooBar:index.html.twig', (string) $templateReference);
}
public function testGuessTemplateWithoutBundle()
{
$templateGuesser = new TemplateGuesser($this->kernel);
$templateReference = $templateGuesser->guessTemplateName(array(
new Fixture\Controller\OutOfBundleController(),
'indexAction',
), new Request());
$this->assertEquals(':OutOfBundle:index.html.twig', (string) $templateReference);
}
/**
* @dataProvider controllerProvider
*/
public function testGuessTemplateWithInvokeMagicMethod($controller, $patterns)
{
$templateGuesser = new TemplateGuesser($this->kernel, $patterns);
$templateReference = $templateGuesser->guessTemplateName(array(
$controller,
'__invoke',
), new Request());
$this->assertEquals('FooBundle::Foo.html.twig', (string) $templateReference);
}
/**
* @dataProvider controllerProvider
*/
public function testGuessTemplateWithACustomPattern($controller, $patterns)
{
$templateGuesser = new TemplateGuesser($this->kernel, $patterns);
$templateReference = $templateGuesser->guessTemplateName(array(
$controller,
'indexAction',
), new Request());
$this->assertEquals('FooBundle:Foo:index.html.twig', (string) $templateReference);
}
/**
* @dataProvider controllerProvider
*/
public function testGuessTemplateWithNotStandardMethodName($controller, $patterns)
{
$templateGuesser = new TemplateGuesser($this->kernel, $patterns);
$templateReference = $templateGuesser->guessTemplateName(array(
$controller,
'fooBar',
), new Request());
$this->assertEquals('FooBundle:Foo:fooBar.html.twig', (string) $templateReference);
}
public function controllerProvider()
{
return array(
array(new Fixture\FooBundle\Controller\FooController(), array()),
array(new Fixture\FooBundle\Action\FooAction(), array('/foobar/', '/FooBundle\\\Action\\\(.+)Action/')),
);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage The "stdClass" class does not look like a controller class (its FQN must match one of the following regexps: "/foo/", "/bar/"
*/
public function testGuessTemplateWhenControllerFQNDoesNotMatchAPattern()
{
$this->kernel->getBundles();
$templateGuesser = new TemplateGuesser($this->kernel, array('/foo/', '/bar/'));
$templateReference = $templateGuesser->guessTemplateName(array(
new \stdClass(),
'indexAction',
), new Request());
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage must be an array callable or an object defining the magic method __invoke. "object" given.
*/
public function testInvalidController()
{
$this->kernel->getBundles();
$templateGuesser = new TemplateGuesser($this->kernel);
$templateReference = $templateGuesser->guessTemplateName(
new Fixture\FooBundle\Controller\FooController(),
new Request()
);
}
protected function getBundle($name, $namespace, $parent = null)
{
$bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\BundleInterface')->getMock();
$bundle
->expects($this->any())
->method('getName')
->will($this->returnValue($name));
$bundle
->expects($this->any())
->method('getNamespace')
->will($this->returnValue($namespace));
$bundle
->expects($this->any())
->method('getParent')
->will($this->returnValue($parent));
return $bundle;
}
}