From fd1566aaf92560139c70e237128e42224972b79d Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Dec 2015 16:04:08 +0100 Subject: [PATCH] Transform abstract Controller class into traits. --- .../FrameworkBundle/Controller/Controller.php | 394 +----------- .../Controller/ControllerTrait.php | 141 +++++ .../Exception/LogicException.php | 21 + .../FrameworkBundle/Form/FormHelperTrait.php | 75 +++ .../Kernel/KernelHelperTrait.php | 85 +++ .../Routing/RouterHelperTrait.php | 76 +++ .../Security/SecurityHelperTrait.php | 167 ++++++ .../Serializer/SerializerHelperTrait.php | 56 ++ .../Templating/RenderHelperTrait.php | 138 +++++ .../Tests/Controller/ControllerTest.php | 561 ------------------ .../Tests/Controller/ControllerTraitTest.php | 86 +++ .../Tests/Form/FormHelperTraitTest.php | 120 ++++ .../Tests/Kernel/KernelHelperTraitTest.php | 100 ++++ .../Tests/Routing/RouterHelperTraitTest.php | 108 ++++ .../Security/SecurityHelperTraitTest.php | 281 +++++++++ .../Serializer/SerializerHelperTraitTest.php | 107 ++++ .../Templating/RenderHelperTraitTest.php | 248 ++++++++ 17 files changed, 1810 insertions(+), 954 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Exception/LogicException.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Form/FormHelperTrait.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Kernel/KernelHelperTrait.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Routing/RouterHelperTrait.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Security/SecurityHelperTrait.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Serializer/SerializerHelperTrait.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Templating/RenderHelperTrait.php delete mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Form/FormHelperTraitTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/KernelHelperTraitTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterHelperTraitTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Security/SecurityHelperTraitTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Serializer/SerializerHelperTraitTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Templating/RenderHelperTraitTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php index a0c3e6e19d4bf..6ed69b30115db 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php @@ -12,20 +12,6 @@ namespace Symfony\Bundle\FrameworkBundle\Controller; use Symfony\Component\DependencyInjection\ContainerAwareInterface; -use Symfony\Component\DependencyInjection\ContainerAwareTrait; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\StreamedResponse; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Exception\AccessDeniedException; -use Symfony\Component\Security\Csrf\CsrfToken; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\Form; -use Symfony\Component\Form\FormBuilder; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Doctrine\Bundle\DoctrineBundle\Registry; /** * Controller is a simple implementation of a Controller. @@ -36,383 +22,5 @@ */ abstract class Controller implements ContainerAwareInterface { - use ContainerAwareTrait; - - /** - * Generates a URL from the given parameters. - * - * @param string $route The name of the route - * @param mixed $parameters An array of parameters - * @param int $referenceType The type of reference (one of the constants in UrlGeneratorInterface) - * - * @return string The generated URL - * - * @see UrlGeneratorInterface - */ - protected function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) - { - return $this->container->get('router')->generate($route, $parameters, $referenceType); - } - - /** - * Forwards the request to another controller. - * - * @param string $controller The controller name (a string like BlogBundle:Post:index) - * @param array $path An array of path parameters - * @param array $query An array of query parameters - * - * @return Response A Response instance - */ - protected function forward($controller, array $path = array(), array $query = array()) - { - $path['_controller'] = $controller; - $subRequest = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, null, $path); - - return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST); - } - - /** - * Returns a RedirectResponse to the given URL. - * - * @param string $url The URL to redirect to - * @param int $status The status code to use for the Response - * - * @return RedirectResponse - */ - protected function redirect($url, $status = 302) - { - return new RedirectResponse($url, $status); - } - - /** - * Returns a RedirectResponse to the given route with the given parameters. - * - * @param string $route The name of the route - * @param array $parameters An array of parameters - * @param int $status The status code to use for the Response - * - * @return RedirectResponse - */ - protected function redirectToRoute($route, array $parameters = array(), $status = 302) - { - return $this->redirect($this->generateUrl($route, $parameters), $status); - } - - /** - * Returns a JsonResponse that uses the serializer component if enabled, or json_encode. - * - * @param mixed $data The response data - * @param int $status The status code to use for the Response - * @param array $headers Array of extra headers to add - * @param array $context Context to pass to serializer when using serializer component - * - * @return JsonResponse - */ - protected function json($data, $status = 200, $headers = array(), $context = array()) - { - if ($this->container->has('serializer')) { - $json = $this->container->get('serializer')->serialize($data, 'json', array_merge(array( - 'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS, - ), $context)); - - return new JsonResponse($json, $status, $headers, true); - } - - return new JsonResponse($data, $status, $headers); - } - - /** - * Adds a flash message to the current session for type. - * - * @param string $type The type - * @param string $message The message - * - * @throws \LogicException - */ - protected function addFlash($type, $message) - { - if (!$this->container->has('session')) { - throw new \LogicException('You can not use the addFlash method if sessions are disabled.'); - } - - $this->container->get('session')->getFlashBag()->add($type, $message); - } - - /** - * Checks if the attributes are granted against the current authentication token and optionally supplied object. - * - * @param mixed $attributes The attributes - * @param mixed $object The object - * - * @return bool - * - * @throws \LogicException - */ - protected function isGranted($attributes, $object = null) - { - if (!$this->container->has('security.authorization_checker')) { - throw new \LogicException('The SecurityBundle is not registered in your application.'); - } - - return $this->container->get('security.authorization_checker')->isGranted($attributes, $object); - } - - /** - * Throws an exception unless the attributes are granted against the current authentication token and optionally - * supplied object. - * - * @param mixed $attributes The attributes - * @param mixed $object The object - * @param string $message The message passed to the exception - * - * @throws AccessDeniedException - */ - protected function denyAccessUnlessGranted($attributes, $object = null, $message = 'Access Denied.') - { - if (!$this->isGranted($attributes, $object)) { - throw $this->createAccessDeniedException($message); - } - } - - /** - * Returns a rendered view. - * - * @param string $view The view name - * @param array $parameters An array of parameters to pass to the view - * - * @return string The rendered view - */ - protected function renderView($view, array $parameters = array()) - { - if ($this->container->has('templating')) { - return $this->container->get('templating')->render($view, $parameters); - } - - if (!$this->container->has('twig')) { - throw new \LogicException('You can not use the "renderView" method if the Templating Component or the Twig Bundle are not available.'); - } - - return $this->container->get('twig')->render($view, $parameters); - } - - /** - * Renders a view. - * - * @param string $view The view name - * @param array $parameters An array of parameters to pass to the view - * @param Response $response A response instance - * - * @return Response A Response instance - */ - protected function render($view, array $parameters = array(), Response $response = null) - { - if ($this->container->has('templating')) { - return $this->container->get('templating')->renderResponse($view, $parameters, $response); - } - - if (!$this->container->has('twig')) { - throw new \LogicException('You can not use the "render" method if the Templating Component or the Twig Bundle are not available.'); - } - - if (null === $response) { - $response = new Response(); - } - - $response->setContent($this->container->get('twig')->render($view, $parameters)); - - return $response; - } - - /** - * Streams a view. - * - * @param string $view The view name - * @param array $parameters An array of parameters to pass to the view - * @param StreamedResponse $response A response instance - * - * @return StreamedResponse A StreamedResponse instance - */ - protected function stream($view, array $parameters = array(), StreamedResponse $response = null) - { - if ($this->container->has('templating')) { - $templating = $this->container->get('templating'); - - $callback = function () use ($templating, $view, $parameters) { - $templating->stream($view, $parameters); - }; - } elseif ($this->container->has('twig')) { - $twig = $this->container->get('twig'); - - $callback = function () use ($twig, $view, $parameters) { - $twig->display($view, $parameters); - }; - } else { - throw new \LogicException('You can not use the "stream" method if the Templating Component or the Twig Bundle are not available.'); - } - - if (null === $response) { - return new StreamedResponse($callback); - } - - $response->setCallback($callback); - - return $response; - } - - /** - * Returns a NotFoundHttpException. - * - * This will result in a 404 response code. Usage example: - * - * throw $this->createNotFoundException('Page not found!'); - * - * @param string $message A message - * @param \Exception|null $previous The previous exception - * - * @return NotFoundHttpException - */ - protected function createNotFoundException($message = 'Not Found', \Exception $previous = null) - { - return new NotFoundHttpException($message, $previous); - } - - /** - * Returns an AccessDeniedException. - * - * This will result in a 403 response code. Usage example: - * - * throw $this->createAccessDeniedException('Unable to access this page!'); - * - * @param string $message A message - * @param \Exception|null $previous The previous exception - * - * @return AccessDeniedException - */ - protected function createAccessDeniedException($message = 'Access Denied.', \Exception $previous = null) - { - return new AccessDeniedException($message, $previous); - } - - /** - * Creates and returns a Form instance from the type of the form. - * - * @param string $type The fully qualified class name of the form type - * @param mixed $data The initial data for the form - * @param array $options Options for the form - * - * @return Form - */ - protected function createForm($type, $data = null, array $options = array()) - { - return $this->container->get('form.factory')->create($type, $data, $options); - } - - /** - * Creates and returns a form builder instance. - * - * @param mixed $data The initial data for the form - * @param array $options Options for the form - * - * @return FormBuilder - */ - protected function createFormBuilder($data = null, array $options = array()) - { - return $this->container->get('form.factory')->createBuilder(FormType::class, $data, $options); - } - - /** - * Shortcut to return the Doctrine Registry service. - * - * @return Registry - * - * @throws \LogicException If DoctrineBundle is not available - */ - protected function getDoctrine() - { - if (!$this->container->has('doctrine')) { - throw new \LogicException('The DoctrineBundle is not registered in your application.'); - } - - return $this->container->get('doctrine'); - } - - /** - * Get a user from the Security Token Storage. - * - * @return mixed - * - * @throws \LogicException If SecurityBundle is not available - * - * @see TokenInterface::getUser() - */ - protected function getUser() - { - if (!$this->container->has('security.token_storage')) { - throw new \LogicException('The SecurityBundle is not registered in your application.'); - } - - if (null === $token = $this->container->get('security.token_storage')->getToken()) { - return; - } - - if (!is_object($user = $token->getUser())) { - // e.g. anonymous authentication - return; - } - - return $user; - } - - /** - * Returns true if the service id is defined. - * - * @param string $id The service id - * - * @return bool true if the service id is defined, false otherwise - */ - protected function has($id) - { - return $this->container->has($id); - } - - /** - * Gets a container service by its id. - * - * @param string $id The service id - * - * @return object The service - */ - protected function get($id) - { - return $this->container->get($id); - } - - /** - * Gets a container configuration parameter by its name. - * - * @param string $name The parameter name - * - * @return mixed - */ - protected function getParameter($name) - { - return $this->container->getParameter($name); - } - - /** - * Checks the validity of a CSRF token. - * - * @param string $id The id used when generating the token - * @param string $token The actual token sent with the request that should be validated - * - * @return bool - */ - protected function isCsrfTokenValid($id, $token) - { - if (!$this->container->has('security.csrf.token_manager')) { - throw new \LogicException('CSRF protection is not enabled in your application.'); - } - - return $this->container->get('security.csrf.token_manager')->isTokenValid(new CsrfToken($id, $token)); - } + use ControllerTrait; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php new file mode 100644 index 0000000000000..d983e12a9b4b7 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Controller; + +use Doctrine\Bundle\DoctrineBundle\Registry; +use Symfony\Bundle\FrameworkBundle\Form\FormHelperTrait; +use Symfony\Bundle\FrameworkBundle\Kernel\KernelHelperTrait; +use Symfony\Bundle\FrameworkBundle\Routing\RouterHelperTrait; +use Symfony\Bundle\FrameworkBundle\Security\SecurityHelperTrait; +use Symfony\Bundle\FrameworkBundle\Serializer\SerializerHelperTrait; +use Symfony\Bundle\FrameworkBundle\Templating\RenderHelperTrait; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + +/** + * ControllerTrait is a simple implementation of a Controller. + * + * It provides methods to common features needed in controllers. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait ControllerTrait +{ + use ContainerAwareTrait; + use KernelHelperTrait; + use RouterHelperTrait; + use FormHelperTrait; + use RenderHelperTrait; + use SerializerHelperTrait; + use SecurityHelperTrait; + + /** + * Returns a RedirectResponse to the given URL. + * + * @param string $url The URL to redirect to + * @param int $status The status code to use for the Response + * + * @return RedirectResponse + */ + protected function redirect($url, $status = 302) + { + return new RedirectResponse($url, $status); + } + + /** + * Adds a flash message to the current session for type. + * + * @param string $type The type + * @param string $message The message + * + * @throws \LogicException + */ + protected function addFlash($type, $message) + { + if (!$this->container->has('session')) { + throw new \LogicException('You can not use the addFlash method if sessions are disabled.'); + } + + $this->container->get('session')->getFlashBag()->add($type, $message); + } + + /** + * Returns a NotFoundHttpException. + * + * This will result in a 404 response code. Usage example: + * + * throw $this->createNotFoundException('Page not found!'); + * + * @param string $message A message + * @param \Exception|null $previous The previous exception + * + * @return NotFoundHttpException + */ + protected function createNotFoundException($message = 'Not Found', \Exception $previous = null) + { + return new NotFoundHttpException($message, $previous); + } + + /** + * Shortcut to return the Doctrine Registry service. + * + * @return Registry + * + * @throws \LogicException If DoctrineBundle is not available + */ + protected function getDoctrine() + { + if (!$this->container->has('doctrine')) { + throw new \LogicException('The DoctrineBundle is not registered in your application.'); + } + + return $this->container->get('doctrine'); + } + + /** + * Returns true if the service id is defined. + * + * @param string $id The service id + * + * @return bool true if the service id is defined, false otherwise + */ + protected function has($id) + { + return $this->container->has($id); + } + + /** + * Gets a container service by its id. + * + * @param string $id The service id + * + * @return object The service + */ + protected function get($id) + { + return $this->container->get($id); + } + + /** + * Gets a container configuration parameter by its name. + * + * @param string $name The parameter name + * + * @return mixed + */ + protected function getParameter($name) + { + return $this->container->getParameter($name); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Exception/LogicException.php b/src/Symfony/Bundle/FrameworkBundle/Exception/LogicException.php new file mode 100644 index 0000000000000..027ead354347c --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Exception/LogicException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Exception; + +/** + * Base LogicException for the FrameworkBundle. + * + * @author Alexander M. Turek + */ +class LogicException extends \LogicException +{ +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Form/FormHelperTrait.php b/src/Symfony/Bundle/FrameworkBundle/Form/FormHelperTrait.php new file mode 100644 index 0000000000000..e4802b3f26e68 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Form/FormHelperTrait.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Form; + +use Symfony\Bundle\FrameworkBundle\Exception\LogicException; +use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormFactoryInterface; + +/** + * Form integration for controller classes. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait FormHelperTrait +{ + /** + * @var FormFactoryInterface + */ + protected $formFactory; + + /** + * @return FormFactoryInterface + */ + protected function getFormFactory() + { + if ($this->formFactory === null) { + if (!isset($this->container)) { + throw new LogicException('Unable to load the form factory. Please either set the $formFactory property or make'.__CLASS__.' container-aware.'); + } + + $this->formFactory = $this->container->get('form.factory'); + } + + return $this->formFactory; + } + + /** + * Creates and returns a Form instance from the type of the form. + * + * @param string $type The fully qualified class name of the form type + * @param mixed $data The initial data for the form + * @param array $options Options for the form + * + * @return Form + */ + protected function createForm($type, $data = null, array $options = array()) + { + return $this->getFormFactory()->create($type, $data, $options); + } + + /** + * Creates and returns a form builder instance. + * + * @param mixed $data The initial data for the form + * @param array $options Options for the form + * + * @return FormBuilder + */ + protected function createFormBuilder($data = null, array $options = array()) + { + return $this->getFormFactory()->createBuilder(FormType::class, $data, $options); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Kernel/KernelHelperTrait.php b/src/Symfony/Bundle/FrameworkBundle/Kernel/KernelHelperTrait.php new file mode 100644 index 0000000000000..8fbbb43ea1860 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Kernel/KernelHelperTrait.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Kernel; + +use Symfony\Bundle\FrameworkBundle\Exception\LogicException; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * HttpKernel integration for controller classes. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait KernelHelperTrait +{ + /** + * @var RequestStack + */ + protected $requestStack; + + /** + * @var HttpKernelInterface + */ + protected $httpKernel; + + /** + * @return RequestStack + */ + protected function getRequestStack() + { + if ($this->requestStack === null) { + if (!isset($this->container)) { + throw new LogicException('Unable to retrieve the request stack. Please either set the $requestStack property or make'.__CLASS__.' container-aware.'); + } + + $this->requestStack = $this->container->get('request_stack'); + } + + return $this->requestStack; + } + + /** + * @return HttpKernelInterface + */ + protected function getHttpKernel() + { + if ($this->httpKernel === null) { + if (!isset($this->container)) { + throw new LogicException('Unable to retrieve the HTTP kernel. Please either set the $httpKernel property or make'.__CLASS__.' container-aware.'); + } + + $this->httpKernel = $this->container->get('http_kernel'); + } + + return $this->httpKernel; + } + + /** + * Forwards the request to another controller. + * + * @param string $controller The controller name (a string like BlogBundle:Post:index) + * @param array $path An array of path parameters + * @param array $query An array of query parameters + * + * @return Response A Response instance + */ + protected function forward($controller, array $path = array(), array $query = array()) + { + $path['_controller'] = $controller; + $subRequest = $this->getRequestStack()->getCurrentRequest()->duplicate($query, null, $path); + + return $this->getHttpKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/RouterHelperTrait.php b/src/Symfony/Bundle/FrameworkBundle/Routing/RouterHelperTrait.php new file mode 100644 index 0000000000000..07b6cb431a75b --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/RouterHelperTrait.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Routing; + +use Symfony\Bundle\FrameworkBundle\Exception\LogicException; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * A collection of helper functions for classes using the router. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait RouterHelperTrait +{ + /** + * @var UrlGeneratorInterface + */ + protected $router; + + /** + * @return UrlGeneratorInterface + */ + protected function getRouter() + { + if ($this->router === null) { + if (!isset($this->container)) { + throw new LogicException('Unable to retrieve the router.'); + } + + $this->router = $this->container->get('router'); + } + + return $this->router; + } + + /** + * Generates a URL from the given parameters. + * + * @param string $route The name of the route + * @param mixed $parameters An array of parameters + * @param int $referenceType The type of reference (one of the constants in UrlGeneratorInterface) + * + * @return string The generated URL + * + * @see UrlGeneratorInterface + */ + protected function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) + { + return $this->getRouter()->generate($route, $parameters, $referenceType); + } + + /** + * Returns a RedirectResponse to the given route with the given parameters. + * + * @param string $route The name of the route + * @param array $parameters An array of parameters + * @param int $status The status code to use for the Response + * + * @return RedirectResponse + */ + protected function redirectToRoute($route, array $parameters = array(), $status = 302) + { + return new RedirectResponse($this->generateUrl($route, $parameters), $status); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Security/SecurityHelperTrait.php b/src/Symfony/Bundle/FrameworkBundle/Security/SecurityHelperTrait.php new file mode 100644 index 0000000000000..2ef2360cdd150 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Security/SecurityHelperTrait.php @@ -0,0 +1,167 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Security; + +use Symfony\Bundle\FrameworkBundle\Exception\LogicException; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\Security\Csrf\CsrfToken; +use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; + +/** + * A collection of utility methods to ease the integration of SecurityBundle services. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait SecurityHelperTrait +{ + /** + * @var AuthorizationCheckerInterface + */ + protected $authorizationChecker; + + /** + * @var TokenStorageInterface + */ + protected $tokenStorage; + + /** + * @var CsrfTokenManagerInterface + */ + protected $csrfTokenManager; + + /** + * Checks if the attributes are granted against the current authentication token and optionally supplied object. + * + * @param mixed $attributes The attributes + * @param mixed $object The object + * + * @return bool + */ + protected function isGranted($attributes, $object = null) + { + if ($this->authorizationChecker === null) { + if (!isset($this->container)) { + throw new LogicException( + 'Unable to load the authorization checker. Please set the $authorizationChecker property or make ' + .__CLASS__.' container-aware.' + ); + } + if (!$this->container->has('security.authorization_checker')) { + throw new LogicException('The SecurityBundle is not registered in your application.'); + } + + $this->authorizationChecker = $this->container->get('security.authorization_checker'); + } + + return $this->authorizationChecker->isGranted($attributes, $object); + } + + /** + * Throws an exception unless the attributes are granted against the current authentication token and optionally + * supplied object. + * + * @param mixed $attributes The attributes + * @param mixed $object The object + * @param string $message The message passed to the exception + * + * @throws AccessDeniedException + */ + protected function denyAccessUnlessGranted($attributes, $object = null, $message = 'Access Denied.') + { + if (!$this->isGranted($attributes, $object)) { + throw $this->createAccessDeniedException($message); + } + } + + /** + * Returns an AccessDeniedException. + * + * This will result in a 403 response code. Usage example: + * + * throw $this->createAccessDeniedException('Unable to access this page!'); + * + * @param string $message A message + * @param \Exception|null $previous The previous exception + * + * @return AccessDeniedException + */ + protected function createAccessDeniedException($message = 'Access Denied.', \Exception $previous = null) + { + return new AccessDeniedException($message, $previous); + } + + /** + * Get a user from the Security Token Storage. + * + * @return mixed + * + * @see TokenInterface::getUser() + */ + protected function getUser() + { + if ($this->tokenStorage === null) { + if (!isset($this->container)) { + throw new LogicException( + 'Unable to load the token storage. Please set the $tokenStorage property or make ' + .__CLASS__.' container-aware.' + ); + } + if (!$this->container->has('security.token_storage')) { + throw new LogicException('The SecurityBundle is not registered in your application.'); + } + + $this->tokenStorage = $this->container->get('security.token_storage'); + } + + if (null === $token = $this->tokenStorage->getToken()) { + return; + } + + if (!is_object($user = $token->getUser())) { + // e.g. anonymous authentication + return; + } + + return $user; + } + + /** + * Checks the validity of a CSRF token. + * + * @param string $id The id used when generating the token + * @param string $token The actual token sent with the request that should be validated + * + * @return bool + */ + protected function isCsrfTokenValid($id, $token) + { + if ($this->csrfTokenManager === null) { + if (!isset($this->container)) { + throw new LogicException( + 'Unable to load the CSRF token manager. Please set the $csrfTokenManager property or make ' + .__CLASS__.' container-aware.' + ); + } + if (!$this->container->has('security.csrf.token_manager')) { + throw new LogicException('CSRF protection is not enabled in your application.'); + } + + $this->csrfTokenManager = $this->container->get('security.csrf.token_manager'); + } + + return $this->csrfTokenManager->isTokenValid(new CsrfToken($id, $token)); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Serializer/SerializerHelperTrait.php b/src/Symfony/Bundle/FrameworkBundle/Serializer/SerializerHelperTrait.php new file mode 100644 index 0000000000000..af7554bd03d5e --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Serializer/SerializerHelperTrait.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Serializer; + +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\Serializer\SerializerInterface; + +/** + * Serializer integration for controller classes. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait SerializerHelperTrait +{ + /** + * @var SerializerInterface + */ + protected $serializer; + + /** + * Returns a JsonResponse that uses the serializer component if enabled, or json_encode. + * + * @param mixed $data The response data + * @param int $status The status code to use for the Response + * @param array $headers Array of extra headers to add + * @param array $context Context to pass to serializer when using serializer component + * + * @return JsonResponse + */ + protected function json($data, $status = 200, $headers = array(), $context = array()) + { + if ($this->serializer === null && isset($this->container) && $this->container->has('serializer')) { + $this->serializer = $this->container->get('serializer'); + } + + if ($this->serializer !== null) { + $json = $this->serializer->serialize($data, 'json', array_merge(array( + 'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS, + ), $context)); + + return new JsonResponse($json, $status, $headers, true); + } + + return new JsonResponse($data, $status, $headers); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/RenderHelperTrait.php b/src/Symfony/Bundle/FrameworkBundle/Templating/RenderHelperTrait.php new file mode 100644 index 0000000000000..4e54367184c80 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/RenderHelperTrait.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Templating; + +use Symfony\Bundle\FrameworkBundle\Exception\LogicException; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\Templating\StreamingEngineInterface; + +/** + * A collection of utility functions for rendering views. + * + * @author Fabien Potencier + * @author Alexander M. Turek + */ +trait RenderHelperTrait +{ + /** + * @var \Twig_Environment + */ + protected $twig; + + /** + * @var EngineInterface|StreamingEngineInterface + */ + protected $templating; + + protected function ensureRenderer() + { + if ($this->twig !== null || $this->templating !== null) { + return; + } + + if (!isset($this->container)) { + throw new LogicException('Unable to load a renderer. Please either set the $twig or $templating property or make'.__CLASS__.' container-aware.'); + } + + if ($this->container->has('templating')) { + $this->templating = $this->container->get('templating'); + + return; + } + + if ($this->container->has('twig')) { + $this->twig = $this->container->get('twig'); + + return; + } + + throw new LogicException('You can not use '.__TRAIT__.' if the Templating Component or the Twig Bundle are not available.'); + } + + /** + * Returns a rendered view. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * + * @return string The rendered view + */ + protected function renderView($view, array $parameters = array()) + { + $this->ensureRenderer(); + + if ($this->templating !== null) { + return $this->templating->render($view, $parameters); + } + + return $this->twig->render($view, $parameters); + } + + /** + * Renders a view. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param Response $response A response instance + * + * @return Response A Response instance + */ + protected function render($view, array $parameters = array(), Response $response = null) + { + $this->ensureRenderer(); + + if ($this->templating !== null) { + return $this->templating->renderResponse($view, $parameters, $response); + } + + if (null === $response) { + $response = new Response(); + } + + $response->setContent($this->twig->render($view, $parameters)); + + return $response; + } + + /** + * Streams a view. + * + * @param string $view The view name + * @param array $parameters An array of parameters to pass to the view + * @param StreamedResponse $response A response instance + * + * @return StreamedResponse A StreamedResponse instance + */ + protected function stream($view, array $parameters = array(), StreamedResponse $response = null) + { + $this->ensureRenderer(); + + if ($this->templating !== null) { + $callback = function () use ($view, $parameters) { + $this->templating->stream($view, $parameters); + }; + } else { + $callback = function () use ($view, $parameters) { + $this->twig->display($view, $parameters); + }; + } + + if (null === $response) { + return new StreamedResponse($callback); + } + + $response->setCallback($callback); + + return $response; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php deleted file mode 100644 index 4063a00ab7fec..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php +++ /dev/null @@ -1,561 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Tests\Controller; - -use Symfony\Bundle\FrameworkBundle\Tests\TestCase; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; -use Symfony\Component\HttpFoundation\StreamedResponse; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\User\User; -use Symfony\Component\Serializer\SerializerInterface; - -class ControllerTest extends TestCase -{ - public function testForward() - { - $request = Request::create('/'); - $request->setLocale('fr'); - $request->setRequestFormat('xml'); - - $requestStack = new RequestStack(); - $requestStack->push($request); - - $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); - $kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) { - return new Response($request->getRequestFormat().'--'.$request->getLocale()); - })); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('get')->will($this->returnValue($requestStack)); - $container->expects($this->at(1))->method('get')->will($this->returnValue($kernel)); - - $controller = new TestController(); - $controller->setContainer($container); - - $response = $controller->forward('a_controller'); - $this->assertEquals('xml--fr', $response->getContent()); - } - - public function testGetUser() - { - $user = new User('user', 'pass'); - $token = new UsernamePasswordToken($user, 'pass', 'default', array('ROLE_USER')); - - $controller = new TestController(); - $controller->setContainer($this->getContainerWithTokenStorage($token)); - - $this->assertSame($controller->getUser(), $user); - } - - public function testGetUserAnonymousUserConvertedToNull() - { - $token = new AnonymousToken('default', 'anon.'); - - $controller = new TestController(); - $controller->setContainer($this->getContainerWithTokenStorage($token)); - - $this->assertNull($controller->getUser()); - } - - public function testGetUserWithEmptyTokenStorage() - { - $controller = new TestController(); - $controller->setContainer($this->getContainerWithTokenStorage(null)); - - $this->assertNull($controller->getUser()); - } - - /** - * @expectedException \LogicException - * @expectedExceptionMessage The SecurityBundle is not registered in your application. - */ - public function testGetUserWithEmptyContainer() - { - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container - ->expects($this->once()) - ->method('has') - ->with('security.token_storage') - ->will($this->returnValue(false)); - - $controller = new TestController(); - $controller->setContainer($container); - - $controller->getUser(); - } - - /** - * @param $token - * - * @return ContainerInterface - */ - private function getContainerWithTokenStorage($token = null) - { - $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage'); - $tokenStorage - ->expects($this->once()) - ->method('getToken') - ->will($this->returnValue($token)); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container - ->expects($this->once()) - ->method('has') - ->with('security.token_storage') - ->will($this->returnValue(true)); - - $container - ->expects($this->once()) - ->method('get') - ->with('security.token_storage') - ->will($this->returnValue($tokenStorage)); - - return $container; - } - - public function testJson() - { - $container = $this->getMock(ContainerInterface::class); - $container - ->expects($this->once()) - ->method('has') - ->with('serializer') - ->will($this->returnValue(false)); - - $controller = new TestController(); - $controller->setContainer($container); - - $response = $controller->json(array()); - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertEquals('[]', $response->getContent()); - } - - public function testJsonWithSerializer() - { - $container = $this->getMock(ContainerInterface::class); - $container - ->expects($this->once()) - ->method('has') - ->with('serializer') - ->will($this->returnValue(true)); - - $serializer = $this->getMock(SerializerInterface::class); - $serializer - ->expects($this->once()) - ->method('serialize') - ->with(array(), 'json', array('json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS)) - ->will($this->returnValue('[]')); - - $container - ->expects($this->once()) - ->method('get') - ->with('serializer') - ->will($this->returnValue($serializer)); - - $controller = new TestController(); - $controller->setContainer($container); - - $response = $controller->json(array()); - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertEquals('[]', $response->getContent()); - } - - public function testJsonWithSerializerContextOverride() - { - $container = $this->getMock(ContainerInterface::class); - $container - ->expects($this->once()) - ->method('has') - ->with('serializer') - ->will($this->returnValue(true)); - - $serializer = $this->getMock(SerializerInterface::class); - $serializer - ->expects($this->once()) - ->method('serialize') - ->with(array(), 'json', array('json_encode_options' => 0, 'other' => 'context')) - ->will($this->returnValue('[]')); - - $container - ->expects($this->once()) - ->method('get') - ->with('serializer') - ->will($this->returnValue($serializer)); - - $controller = new TestController(); - $controller->setContainer($container); - - $response = $controller->json(array(), 200, array(), array('json_encode_options' => 0, 'other' => 'context')); - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertEquals('[]', $response->getContent()); - $response->setEncodingOptions(JSON_FORCE_OBJECT); - $this->assertEquals('{}', $response->getContent()); - } - - public function testIsGranted() - { - $authorizationChecker = $this->getMock('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'); - $authorizationChecker->expects($this->once())->method('isGranted')->willReturn(true); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(1))->method('get')->will($this->returnValue($authorizationChecker)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertTrue($controller->isGranted('foo')); - } - - /** - * @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException - */ - public function testdenyAccessUnlessGranted() - { - $authorizationChecker = $this->getMock('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'); - $authorizationChecker->expects($this->once())->method('isGranted')->willReturn(false); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(1))->method('get')->will($this->returnValue($authorizationChecker)); - - $controller = new TestController(); - $controller->setContainer($container); - - $controller->denyAccessUnlessGranted('foo'); - } - - public function testRenderViewTwig() - { - $twig = $this->getMockBuilder('\Twig_Environment')->disableOriginalConstructor()->getMock(); - $twig->expects($this->once())->method('render')->willReturn('bar'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(false)); - $container->expects($this->at(1))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(2))->method('get')->will($this->returnValue($twig)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals('bar', $controller->renderView('foo')); - } - - public function testRenderTwig() - { - $twig = $this->getMockBuilder('\Twig_Environment')->disableOriginalConstructor()->getMock(); - $twig->expects($this->once())->method('render')->willReturn('bar'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(false)); - $container->expects($this->at(1))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(2))->method('get')->will($this->returnValue($twig)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals('bar', $controller->render('foo')->getContent()); - } - - public function testStreamTwig() - { - $twig = $this->getMockBuilder('\Twig_Environment')->disableOriginalConstructor()->getMock(); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(false)); - $container->expects($this->at(1))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(2))->method('get')->will($this->returnValue($twig)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $controller->stream('foo')); - } - - public function testRedirectToRoute() - { - $router = $this->getMock('Symfony\Component\Routing\RouterInterface'); - $router->expects($this->once())->method('generate')->willReturn('/foo'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('get')->will($this->returnValue($router)); - - $controller = new TestController(); - $controller->setContainer($container); - $response = $controller->redirectToRoute('foo'); - - $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response); - $this->assertSame('/foo', $response->getTargetUrl()); - $this->assertSame(302, $response->getStatusCode()); - } - - public function testAddFlash() - { - $flashBag = new FlashBag(); - $session = $this->getMock('Symfony\Component\HttpFoundation\Session\Session'); - $session->expects($this->once())->method('getFlashBag')->willReturn($flashBag); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(1))->method('get')->will($this->returnValue($session)); - - $controller = new TestController(); - $controller->setContainer($container); - $controller->addFlash('foo', 'bar'); - - $this->assertSame(array('bar'), $flashBag->get('foo')); - } - - public function testCreateAccessDeniedException() - { - $controller = new TestController(); - - $this->assertInstanceOf('Symfony\Component\Security\Core\Exception\AccessDeniedException', $controller->createAccessDeniedException()); - } - - public function testIsCsrfTokenValid() - { - $tokenManager = $this->getMock('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface'); - $tokenManager->expects($this->once())->method('isTokenValid')->willReturn(true); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(1))->method('get')->will($this->returnValue($tokenManager)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertTrue($controller->isCsrfTokenValid('foo', 'bar')); - } - - public function testGenerateUrl() - { - $router = $this->getMock('Symfony\Component\Routing\RouterInterface'); - $router->expects($this->once())->method('generate')->willReturn('/foo'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('get')->will($this->returnValue($router)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals('/foo', $controller->generateUrl('foo')); - } - - public function testRedirect() - { - $controller = new TestController(); - $response = $controller->redirect('http://dunglas.fr', 301); - - $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response); - $this->assertSame('http://dunglas.fr', $response->getTargetUrl()); - $this->assertSame(301, $response->getStatusCode()); - } - - public function testRenderViewTemplating() - { - $templating = $this->getMock('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface'); - $templating->expects($this->once())->method('render')->willReturn('bar'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->willReturn(true); - $container->expects($this->at(1))->method('get')->will($this->returnValue($templating)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals('bar', $controller->renderView('foo')); - } - - public function testRenderTemplating() - { - $templating = $this->getMock('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface'); - $templating->expects($this->once())->method('renderResponse')->willReturn(new Response('bar')); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->willReturn(true); - $container->expects($this->at(1))->method('get')->will($this->returnValue($templating)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals('bar', $controller->render('foo')->getContent()); - } - - public function testStreamTemplating() - { - $templating = $this->getMock('Symfony\Component\Routing\RouterInterface'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->willReturn(true); - $container->expects($this->at(1))->method('get')->will($this->returnValue($templating)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $controller->stream('foo')); - } - - public function testCreateNotFoundException() - { - $controller = new TestController(); - - $this->assertInstanceOf('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', $controller->createNotFoundException()); - } - - public function testCreateForm() - { - $form = $this->getMock('Symfony\Component\Form\FormInterface'); - - $formFactory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); - $formFactory->expects($this->once())->method('create')->willReturn($form); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('get')->will($this->returnValue($formFactory)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals($form, $controller->createForm('foo')); - } - - public function testCreateFormBuilder() - { - $formBuilder = $this->getMock('Symfony\Component\Form\FormBuilderInterface'); - - $formFactory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); - $formFactory->expects($this->once())->method('createBuilder')->willReturn($formBuilder); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('get')->will($this->returnValue($formFactory)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals($formBuilder, $controller->createFormBuilder('foo')); - } - - public function testGetDoctrine() - { - $doctrine = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); - - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); - $container->expects($this->at(1))->method('get')->will($this->returnValue($doctrine)); - - $controller = new TestController(); - $controller->setContainer($container); - - $this->assertEquals($doctrine, $controller->getDoctrine()); - } -} - -class TestController extends Controller -{ - public function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) - { - return parent::generateUrl($route, $parameters, $referenceType); - } - - public function redirect($url, $status = 302) - { - return parent::redirect($url, $status); - } - - public function forward($controller, array $path = array(), array $query = array()) - { - return parent::forward($controller, $path, $query); - } - - public function getUser() - { - return parent::getUser(); - } - - public function json($data, $status = 200, $headers = array(), $context = array()) - { - return parent::json($data, $status, $headers, $context); - } - - public function isGranted($attributes, $object = null) - { - return parent::isGranted($attributes, $object); - } - - public function denyAccessUnlessGranted($attributes, $object = null, $message = 'Access Denied.') - { - parent::denyAccessUnlessGranted($attributes, $object, $message); - } - - public function redirectToRoute($route, array $parameters = array(), $status = 302) - { - return parent::redirectToRoute($route, $parameters, $status); - } - - public function addFlash($type, $message) - { - parent::addFlash($type, $message); - } - - public function isCsrfTokenValid($id, $token) - { - return parent::isCsrfTokenValid($id, $token); - } - - public function renderView($view, array $parameters = array()) - { - return parent::renderView($view, $parameters); - } - - public function render($view, array $parameters = array(), Response $response = null) - { - return parent::render($view, $parameters, $response); - } - - public function stream($view, array $parameters = array(), StreamedResponse $response = null) - { - return parent::stream($view, $parameters, $response); - } - - public function createNotFoundException($message = 'Not Found', \Exception $previous = null) - { - return parent::createNotFoundException($message, $previous); - } - - public function createAccessDeniedException($message = 'Access Denied.', \Exception $previous = null) - { - return parent::createAccessDeniedException($message, $previous); - } - - public function createForm($type, $data = null, array $options = array()) - { - return parent::createForm($type, $data, $options); - } - - public function createFormBuilder($data = null, array $options = array()) - { - return parent::createFormBuilder($data, $options); - } - - public function getDoctrine() - { - return parent::getDoctrine(); - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php new file mode 100644 index 0000000000000..664bec11497dd --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Controller; + +use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; + +class ControllerTraitTest extends TestCase +{ + public function testAddFlash() + { + $flashBag = new FlashBag(); + $session = $this->getMock('Symfony\Component\HttpFoundation\Session\Session'); + $session->expects($this->once())->method('getFlashBag')->willReturn($flashBag); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); + $container->expects($this->at(1))->method('get')->will($this->returnValue($session)); + + $controller = new TestController(); + $controller->setContainer($container); + $controller->addFlash('foo', 'bar'); + + $this->assertSame(array('bar'), $flashBag->get('foo')); + } + + public function testCreateAccessDeniedException() + { + $controller = new TestController(); + + $this->assertInstanceOf('Symfony\Component\Security\Core\Exception\AccessDeniedException', $controller->createAccessDeniedException()); + } + + public function testRedirect() + { + $controller = new TestController(); + $response = $controller->redirect('http://dunglas.fr', 301); + + $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response); + $this->assertSame('http://dunglas.fr', $response->getTargetUrl()); + $this->assertSame(301, $response->getStatusCode()); + } + + public function testCreateNotFoundException() + { + $controller = new TestController(); + + $this->assertInstanceOf('Symfony\Component\HttpKernel\Exception\NotFoundHttpException', $controller->createNotFoundException()); + } + + public function testGetDoctrine() + { + $doctrine = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container->expects($this->at(0))->method('has')->will($this->returnValue(true)); + $container->expects($this->at(1))->method('get')->will($this->returnValue($doctrine)); + + $controller = new TestController(); + $controller->setContainer($container); + + $this->assertEquals($doctrine, $controller->getDoctrine()); + } +} + +class TestController implements ContainerAwareInterface +{ + use ControllerTrait { + redirect as public; + addFlash as public; + createNotFoundException as public; + createAccessDeniedException as public; + getDoctrine as public; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Form/FormHelperTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Form/FormHelperTraitTest.php new file mode 100644 index 0000000000000..c47d76bd3f0b0 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Form/FormHelperTraitTest.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Form; + +use Symfony\Bundle\FrameworkBundle\Form\FormHelperTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormFactoryInterface; +use Symfony\Component\Form\FormInterface; + +class FormHelperTraitTest extends TestCase +{ + public function testCreateForm() + { + $form = $this->getMock(FormInterface::class); + + $formFactory = $this->getMock(FormFactoryInterface::class); + $formFactory->expects($this->once())->method('create')->willReturn($form); + + $helper = new DummyFormHelper($formFactory); + + $this->assertSame($form, $helper->createForm('foo')); + } + + public function testCreateFormWithContainer() + { + $form = $this->getMock(FormInterface::class); + + $formFactory = $this->getMock(FormFactoryInterface::class); + $formFactory->expects($this->once())->method('create')->willReturn($form); + + $container = new Container(); + $container->set('form.factory', $formFactory); + + $helper = new DummyFormHelperWithContainer(); + $helper->setContainer($container); + + $this->assertSame($form, $helper->createForm('foo')); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testCreateFormWithMissingDependencies() + { + $helper = new DummyFormHelperWithContainer(); + $helper->createForm('foo'); + } + + public function testCreateFormBuilder() + { + $formBuilder = $this->getMock(FormBuilderInterface::class); + + $formFactory = $this->getMock(FormFactoryInterface::class); + $formFactory->expects($this->once())->method('createBuilder')->willReturn($formBuilder); + + $helper = new DummyFormHelper($formFactory); + + $this->assertEquals($formBuilder, $helper->createFormBuilder('foo')); + } + + public function testCreateFormBuilderWithContainer() + { + $formBuilder = $this->getMock(FormBuilderInterface::class); + + $formFactory = $this->getMock(FormFactoryInterface::class); + $formFactory->expects($this->once())->method('createBuilder')->willReturn($formBuilder); + + $container = new Container(); + $container->set('form.factory', $formFactory); + + $helper = new DummyFormHelperWithContainer(); + $helper->setContainer($container); + + $this->assertEquals($formBuilder, $helper->createFormBuilder('foo')); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testCreateFormBuilderWithMissingDependencies() + { + $helper = new DummyFormHelperWithContainer(); + $helper->createFormBuilder('foo'); + } +} + +class DummyFormHelper +{ + use FormHelperTrait { + createForm as public; + createFormBuilder as public; + } + + public function __construct(FormFactoryInterface $formFactory) + { + $this->formFactory = $formFactory; + } +} + +class DummyFormHelperWithContainer implements ContainerAwareInterface +{ + use ContainerAwareTrait; + use FormHelperTrait { + createForm as public; + createFormBuilder as public; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/KernelHelperTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/KernelHelperTraitTest.php new file mode 100644 index 0000000000000..61462580b50ab --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/KernelHelperTraitTest.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Kernel; + +use Symfony\Bundle\FrameworkBundle\Kernel\KernelHelperTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +class KernelHelperTraitTest extends TestCase +{ + public function testForward() + { + $request = Request::create('/'); + $request->setLocale('fr'); + $request->setRequestFormat('xml'); + + $requestStack = new RequestStack(); + $requestStack->push($request); + + $kernel = $this->getMock(HttpKernelInterface::class); + $kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) { + return new Response($request->getRequestFormat().'--'.$request->getLocale()); + })); + + $helper = new DummyKernelHelper($kernel, $requestStack); + + $response = $helper->forward('a_controller'); + $this->assertEquals('xml--fr', $response->getContent()); + } + + public function testForwardWithContainer() + { + $request = Request::create('/'); + $request->setLocale('fr'); + $request->setRequestFormat('xml'); + + $requestStack = new RequestStack(); + $requestStack->push($request); + + $kernel = $this->getMock(HttpKernelInterface::class); + $kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) { + return new Response($request->getRequestFormat().'--'.$request->getLocale()); + })); + + $container = new Container(); + $container->set('request_stack', $requestStack); + $container->set('http_kernel', $kernel); + + $helper = new DummyKernelHelperWithContainer(); + $helper->setContainer($container); + + $response = $helper->forward('a_controller'); + $this->assertEquals('xml--fr', $response->getContent()); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testForwardWithMissingDependencies() + { + $helper = new DummyKernelHelperWithContainer(); + $helper->forward('a_controller'); + } +} + +class DummyKernelHelper +{ + use KernelHelperTrait { + forward as public; + } + + public function __construct(HttpKernelInterface $httpKernel, RequestStack $requestStack) + { + $this->httpKernel = $httpKernel; + $this->requestStack = $requestStack; + } +} + +class DummyKernelHelperWithContainer implements ContainerAwareInterface +{ + use ContainerAwareTrait; + use KernelHelperTrait { + forward as public; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterHelperTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterHelperTraitTest.php new file mode 100644 index 0000000000000..fcbd773ce0403 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterHelperTraitTest.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Routing; + +use Symfony\Bundle\FrameworkBundle\Routing\RouterHelperTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +class RouterHelperTraitTest extends TestCase +{ + public function testGenerateUrl() + { + $router = $this->getMock(UrlGeneratorInterface::class); + $router->expects($this->once())->method('generate')->willReturn('/foo'); + + $helper = new DummyRouterHelper($router); + + $this->assertEquals('/foo', $helper->generateUrl('foo')); + } + + public function testGenerateUrlWithContainer() + { + $router = $this->getMock(UrlGeneratorInterface::class); + $router->expects($this->once())->method('generate')->willReturn('/foo'); + + $container = new Container(); + $container->set('router', $router); + + $helper = new DummyRouterHelperWithContainer(); + $helper->setContainer($container); + + $this->assertEquals('/foo', $helper->generateUrl('foo')); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testGenerateUrlWithMissingDependencies() + { + $helper = new DummyRouterHelperWithContainer(); + $helper->generateUrl('acme.my_route'); + } + + public function testRedirectToRoute() + { + $router = $this->getMock(UrlGeneratorInterface::class); + $router->expects($this->once())->method('generate')->willReturn('/foo'); + + $helper = new DummyRouterHelper($router); + $response = $helper->redirectToRoute('foo'); + + $this->assertInstanceOf(RedirectResponse::class, $response); + $this->assertSame('/foo', $response->getTargetUrl()); + $this->assertSame(302, $response->getStatusCode()); + } + + public function testRedirectToRouteWithContainer() + { + $router = $this->getMock(UrlGeneratorInterface::class); + $router->expects($this->once())->method('generate')->willReturn('/foo'); + + $container = new Container(); + $container->set('router', $router); + + $helper = new DummyRouterHelperWithContainer(); + $helper->setContainer($container); + $response = $helper->redirectToRoute('foo'); + + $this->assertInstanceOf(RedirectResponse::class, $response); + $this->assertSame('/foo', $response->getTargetUrl()); + $this->assertSame(302, $response->getStatusCode()); + } +} + +class DummyRouterHelper +{ + use RouterHelperTrait { + generateUrl as public; + redirectToRoute as public; + } + + public function __construct(UrlGeneratorInterface $router) + { + $this->router = $router; + } +} + +class DummyRouterHelperWithContainer implements ContainerAwareInterface +{ + use ContainerAwareTrait; + use RouterHelperTrait { + generateUrl as public; + redirectToRoute as public; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Security/SecurityHelperTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Security/SecurityHelperTraitTest.php new file mode 100644 index 0000000000000..0ad4cd318d4d3 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Security/SecurityHelperTraitTest.php @@ -0,0 +1,281 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Security; + +use Symfony\Bundle\FrameworkBundle\Security\SecurityHelperTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\User\User; +use Symfony\Component\Security\Csrf\CsrfToken; +use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; + +class SecurityHelperTraitTest extends TestCase +{ + public function testDenyAccessUnlessGranted() + { + $dummyObject = new \stdClass(); + $authorizationCheckerMock = $this->getMock(AuthorizationCheckerInterface::class); + $authorizationCheckerMock->expects($this->once()) + ->method('isGranted') + ->with(array('foo' => 'bar'), $this->identicalTo($dummyObject)) + ->will($this->returnValue(true)); + + $securityHelper = new DummySecurityHelper( + $authorizationCheckerMock, + $this->getMock(TokenStorageInterface::class), + $this->getMock(CsrfTokenManagerInterface::class) + ); + + $securityHelper->denyAccessUnlessGranted(array('foo' => 'bar'), $dummyObject, 'Nice try, buddy!'); + } + + public function testDenyAccessUnlessGrantedWithContainer() + { + $dummyObject = new \stdClass(); + $authorizationCheckerMock = $this->getMock(AuthorizationCheckerInterface::class); + $authorizationCheckerMock->expects($this->once()) + ->method('isGranted') + ->with(array('foo' => 'bar'), $this->identicalTo($dummyObject)) + ->will($this->returnValue(true)); + + $container = new Container(); + $container->set('security.authorization_checker', $authorizationCheckerMock); + + $securityHelper = new DummySecurityHelperWithContainer(); + $securityHelper->setContainer($container); + + $securityHelper->denyAccessUnlessGranted(array('foo' => 'bar'), $dummyObject, 'Nice try, buddy!'); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException + * @expectedExceptionMessage Nice try, buddy! + */ + public function testDenyAccessUnlessGrantedThrowsException() + { + $dummyObject = new \stdClass(); + $authorizationCheckerMock = $this->getMock(AuthorizationCheckerInterface::class); + $authorizationCheckerMock->expects($this->once()) + ->method('isGranted') + ->with(array('foo' => 'bar'), $this->identicalTo($dummyObject)) + ->will($this->returnValue(false)); + + $securityHelper = new DummySecurityHelper( + $authorizationCheckerMock, + $this->getMock(TokenStorageInterface::class), + $this->getMock(CsrfTokenManagerInterface::class) + ); + + $securityHelper->denyAccessUnlessGranted(array('foo' => 'bar'), $dummyObject, 'Nice try, buddy!'); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testDenyAccessUnlessGrantedWithMissingDependencies() + { + $securityHelper = new DummySecurityHelperWithContainer(); + $securityHelper->setContainer(new Container()); + + $securityHelper->denyAccessUnlessGranted(array('foo' => 'bar'), new \stdClass(), 'Nice try, buddy!'); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testDenyAccessUnlessGrantedWithoutContainer() + { + $securityHelper = new DummySecurityHelperWithContainer(); + + $securityHelper->denyAccessUnlessGranted(array('foo' => 'bar'), new \stdClass(), 'Nice try, buddy!'); + } + + public function testGetUser() + { + $user = new User('user', 'pass'); + $token = new UsernamePasswordToken($user, 'pass', 'default', array('ROLE_USER')); + + $securityHelper = new DummySecurityHelper( + $this->getMock(AuthorizationCheckerInterface::class), + $this->getAuthenticationTokenStorageMock($token), + $this->getMock(CsrfTokenManagerInterface::class) + ); + + $this->assertSame($securityHelper->getUser(), $user); + } + + public function testGetUserWithContainer() + { + $user = new User('user', 'pass'); + $token = new UsernamePasswordToken($user, 'pass', 'default', array('ROLE_USER')); + $container = new Container(); + $container->set('security.token_storage', $this->getAuthenticationTokenStorageMock($token)); + + $securityHelper = new DummySecurityHelperWithContainer(); + $securityHelper->setContainer($container); + + $this->assertSame($securityHelper->getUser(), $user); + } + + public function testGetUserAnonymousUserConvertedToNull() + { + $token = new AnonymousToken('default', 'anon.'); + + $securityHelper = new DummySecurityHelper( + $this->getMock(AuthorizationCheckerInterface::class), + $this->getAuthenticationTokenStorageMock($token), + $this->getMock(CsrfTokenManagerInterface::class) + ); + + $this->assertNull($securityHelper->getUser()); + } + + public function testGetUserWithEmptyTokenStorage() + { + $securityHelper = new DummySecurityHelper( + $this->getMock(AuthorizationCheckerInterface::class), + $this->getAuthenticationTokenStorageMock(null), + $this->getMock(CsrfTokenManagerInterface::class) + ); + + $this->assertNull($securityHelper->getUser()); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + * @expectedExceptionMessage The SecurityBundle is not registered in your application. + */ + public function testGetUserWithEmptyContainer() + { + $securityHelper = new DummySecurityHelperWithContainer(); + $securityHelper->setContainer(new Container()); + + $securityHelper->getUser(); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testGetUserWithMissingDependencies() + { + $securityHelper = new DummySecurityHelperWithContainer(); + + $securityHelper->getUser(); + } + + /** + * @param TokenInterface|null $token + * + * @return \PHPUnit_Framework_MockObject_MockObject|TokenStorageInterface + */ + private function getAuthenticationTokenStorageMock(TokenInterface $token = null) + { + $tokenStorage = $this->getMock(TokenStorageInterface::class); + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue($token)); + + return $tokenStorage; + } + + public function testIsCsrfTokenValid() + { + $csrfTokenManagerMock = $this->getMock(CsrfTokenManagerInterface::class); + $csrfTokenManagerMock->expects($this->once()) + ->method('isTokenValid') + ->with(new CsrfToken('some_id', 'some_token')) + ->will($this->returnValue(true)); + + $securityHelper = new DummySecurityHelper( + $this->getMock(AuthorizationCheckerInterface::class), + $this->getMock(TokenStorageInterface::class), + $csrfTokenManagerMock + ); + + $this->assertTrue($securityHelper->isCsrfTokenValid('some_id', 'some_token')); + } + + public function testIsCsrfTokenValidWithContainer() + { + $csrfTokenManagerMock = $this->getMock(CsrfTokenManagerInterface::class); + $csrfTokenManagerMock->expects($this->once()) + ->method('isTokenValid') + ->with(new CsrfToken('some_id', 'some_token')) + ->will($this->returnValue(true)); + + $container = new Container(); + $container->set('security.csrf.token_manager', $csrfTokenManagerMock); + + $securityHelper = new DummySecurityHelperWithContainer(); + $securityHelper->setContainer($container); + + $this->assertTrue($securityHelper->isCsrfTokenValid('some_id', 'some_token')); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testIsCsrfTokenValidWithEmptyContainer() + { + $securityHelper = new DummySecurityHelperWithContainer(); + $securityHelper->setContainer(new Container()); + + $securityHelper->isCsrfTokenValid('some_id', 'some_token'); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testIsCsrfTokenValidWithMissingDependencies() + { + $securityHelper = new DummySecurityHelperWithContainer(); + + $securityHelper->isCsrfTokenValid('some_id', 'some_token'); + } +} + +class DummySecurityHelper +{ + use SecurityHelperTrait { + denyAccessUnlessGranted as public; + getUser as public; + isCsrfTokenValid as public; + } + + public function __construct( + AuthorizationCheckerInterface $authorizationChecker, + TokenStorageInterface $authenticationTokenStorage, + CsrfTokenManagerInterface $csrfTokenManager + ) { + $this->authorizationChecker = $authorizationChecker; + $this->tokenStorage = $authenticationTokenStorage; + $this->csrfTokenManager = $csrfTokenManager; + } +} + +class DummySecurityHelperWithContainer implements ContainerAwareInterface +{ + use ContainerAwareTrait; + use SecurityHelperTrait { + denyAccessUnlessGranted as public; + getUser as public; + isCsrfTokenValid as public; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Serializer/SerializerHelperTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Serializer/SerializerHelperTraitTest.php new file mode 100644 index 0000000000000..46dd0e895d363 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Serializer/SerializerHelperTraitTest.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Serializer; + +use Symfony\Bundle\FrameworkBundle\Serializer\SerializerHelperTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\Serializer\SerializerInterface; + +class SerializerHelperTraitTest extends TestCase +{ + public function testJsonWithoutSerializer() + { + $helper = new DummySerializerHelperWithContainer(); + $helper->setContainer(new Container()); + + $response = $helper->json(array()); + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('[]', $response->getContent()); + } + + public function testJsonWithSerializer() + { + $serializer = $this->getMock(SerializerInterface::class); + $serializer + ->expects($this->once()) + ->method('serialize') + ->with(array(), 'json', array('json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS)) + ->will($this->returnValue('[]')); + + $helper = new DummySerializerHelper($serializer); + + $response = $helper->json(array()); + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('[]', $response->getContent()); + } + + public function testJsonWithSerializerFromContainer() + { + $serializer = $this->getMock(SerializerInterface::class); + $serializer + ->expects($this->once()) + ->method('serialize') + ->with(array(), 'json', array('json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS)) + ->will($this->returnValue('[]')); + + $container = new Container(); + $container->set('serializer', $serializer); + + $helper = new DummySerializerHelperWithContainer(); + $helper->setContainer($container); + + $response = $helper->json(array()); + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('[]', $response->getContent()); + } + + public function testJsonWithSerializerContextOverride() + { + $serializer = $this->getMock(SerializerInterface::class); + $serializer + ->expects($this->once()) + ->method('serialize') + ->with(array(), 'json', array('json_encode_options' => 0, 'other' => 'context')) + ->will($this->returnValue('[]')); + + $helper = new DummySerializerHelper($serializer); + + $response = $helper->json(array(), 200, array(), array('json_encode_options' => 0, 'other' => 'context')); + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('[]', $response->getContent()); + $response->setEncodingOptions(JSON_FORCE_OBJECT); + $this->assertEquals('{}', $response->getContent()); + } +} + +class DummySerializerHelper +{ + use SerializerHelperTrait { + json as public; + } + + public function __construct(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } +} + +class DummySerializerHelperWithContainer implements ContainerAwareInterface +{ + use ContainerAwareTrait; + use SerializerHelperTrait { + json as public; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/RenderHelperTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/RenderHelperTraitTest.php new file mode 100644 index 0000000000000..6872224eb7477 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/RenderHelperTraitTest.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Templating; + +use Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine; +use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use Symfony\Bundle\FrameworkBundle\Templating\RenderHelperTrait; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; + +class RenderHelperTraitTest extends TestCase +{ + public function testRenderWithTemplating() + { + $response = new Response(); + + $templatingMock = $this->getMock(EngineInterface::class); + $templatingMock->expects($this->once()) + ->method('renderResponse') + ->with('some_view', array('foo' => 'bar'), $this->identicalTo($response)) + ->will($this->returnValue($response)); + + $renderHelper = new DummyRenderHelperWithTemplating($templatingMock); + + $this->assertSame( + $response, + $renderHelper->render('some_view', array('foo' => 'bar'), $response) + ); + } + + public function testRenderWithTemplatingFromContainer() + { + $response = new Response(); + + $templatingMock = $this->getMock(EngineInterface::class); + $templatingMock->expects($this->once()) + ->method('renderResponse') + ->with('some_view', array('foo' => 'bar'), $this->identicalTo($response)) + ->will($this->returnValue($response)); + + $container = new Container(); + $container->set('templating', $templatingMock); + $renderHelper = new DummyRenderHelperWithContainer(); + $renderHelper->setContainer($container); + + $this->assertSame( + $response, + $renderHelper->render('some_view', array('foo' => 'bar'), $response) + ); + } + + public function testRenderWithTwig() + { + $response = new Response(); + + $twigMock = $this->getMockBuilder(\Twig_Environment::class) + ->disableOriginalConstructor() + ->getMock(); + $twigMock->expects($this->once()) + ->method('render') + ->with('some_view', array('foo' => 'bar')) + ->will($this->returnValue('some_content')); + + $renderHelper = new DummyRenderHelperWithTwig($twigMock); + + $this->assertSame( + $response, + $renderHelper->render('some_view', array('foo' => 'bar'), $response) + ); + $this->assertEquals( + 'some_content', + $response->getContent() + ); + } + + public function testRenderWithTwigFromContainer() + { + $response = new Response(); + + $twigMock = $this->getMockBuilder(\Twig_Environment::class) + ->disableOriginalConstructor() + ->getMock(); + $twigMock->expects($this->once()) + ->method('render') + ->with('some_view', array('foo' => 'bar')) + ->will($this->returnValue('some_content')); + + $container = new Container(); + $container->set('twig', $twigMock); + $renderHelper = new DummyRenderHelperWithContainer(); + $renderHelper->setContainer($container); + + $this->assertSame( + $response, + $renderHelper->render('some_view', array('foo' => 'bar'), $response) + ); + $this->assertEquals( + 'some_content', + $response->getContent() + ); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testRenderWithMissingDependencies() + { + $helper = new DummyRenderHelperWithContainer(); + $helper->render('some_view'); + } + + /** + * @expectedException \Symfony\Bundle\FrameworkBundle\Exception\LogicException + */ + public function testRenderWitEmptyContainer() + { + $helper = new DummyRenderHelperWithContainer(); + $helper->setContainer(new Container()); + $helper->render('some_view'); + } + + public function testRenderViewWithTemplating() + { + $templatingMock = $this->getMock(EngineInterface::class); + $templatingMock->expects($this->once()) + ->method('render') + ->with('some_view', array('foo' => 'bar')) + ->will($this->returnValue('some_content')); + + $renderHelper = new DummyRenderHelperWithTemplating($templatingMock); + + $this->assertEquals( + 'some_content', + $renderHelper->renderView('some_view', array('foo' => 'bar')) + ); + } + + public function testRenderViewWithTwig() + { + $twigMock = $this->getMockBuilder(\Twig_Environment::class) + ->disableOriginalConstructor() + ->getMock(); + $twigMock->expects($this->once()) + ->method('render') + ->with('some_view', array('foo' => 'bar')) + ->will($this->returnValue('some_content')); + + $renderHelper = new DummyRenderHelperWithTwig($twigMock); + + $this->assertEquals( + 'some_content', + $renderHelper->renderView('some_view', array('foo' => 'bar')) + ); + } + + public function testStreamWithTemplating() + { + $response = new StreamedResponse(); + + $templatingMock = $this->getMockBuilder(DelegatingEngine::class) + ->disableOriginalConstructor() + ->getMock(); + $templatingMock->expects($this->once()) + ->method('stream') + ->with('some_view', array('foo' => 'bar')); + + $renderHelper = new DummyRenderHelperWithTemplating($templatingMock); + + $this->assertSame( + $response, + $renderHelper->stream('some_view', array('foo' => 'bar'), $response) + ); + + $response->sendContent(); + } + + public function testStreamWithTwig() + { + $response = new StreamedResponse(); + + $twigMock = $this->getMockBuilder(\Twig_Environment::class) + ->disableOriginalConstructor() + ->getMock(); + $twigMock->expects($this->once()) + ->method('display') + ->with('some_view', array('foo' => 'bar')); + + $renderHelper = new DummyRenderHelperWithTwig($twigMock); + + $this->assertSame( + $response, + $renderHelper->stream('some_view', array('foo' => 'bar'), $response) + ); + + $response->sendContent(); + } +} + +class DummyRenderHelperWithTemplating +{ + public function __construct(EngineInterface $templating) + { + $this->templating = $templating; + } + + use RenderHelperTrait { + renderView as public; + render as public; + stream as public; + } +} + +class DummyRenderHelperWithTwig +{ + public function __construct(\Twig_Environment $twig) + { + $this->twig = $twig; + } + + use RenderHelperTrait { + renderView as public; + render as public; + stream as public; + } +} + +class DummyRenderHelperWithContainer implements ContainerAwareInterface +{ + use ContainerAwareTrait; + use RenderHelperTrait { + renderView as public; + render as public; + stream as public; + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy