diff --git a/composer.json b/composer.json index 8fd8a598..1488f3a2 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "require": { "php": ">=7.0.8 <8.0", "codeception/lib-innerbrowser": "^1.3", - "codeception/codeception": "^4.0" + "codeception/codeception": "^4.0", + "ext-json": "*" }, "require-dev": { "codeception/module-asserts": "^1.3", diff --git a/src/Codeception/Lib/Connector/Symfony.php b/src/Codeception/Lib/Connector/Symfony.php index 887a5b3e..fe81afce 100644 --- a/src/Codeception/Lib/Connector/Symfony.php +++ b/src/Codeception/Lib/Connector/Symfony.php @@ -1,5 +1,7 @@ followRedirects(true); - $this->rebootable = (boolean)$rebootable; + $this->rebootable = $rebootable; $this->persistentServices = $services; $this->container = $this->kernel->getContainer(); $this->rebootKernel(); @@ -56,7 +58,7 @@ public function __construct(Kernel $kernel, array $services = [], $rebootable = * @param Request $request * @return Response */ - protected function doRequest($request) + protected function doRequest($request): Response { if ($this->rebootable) { if ($this->hasPerformedRequest) { @@ -78,7 +80,7 @@ protected function doRequest($request) public function rebootKernel() { if ($this->container) { - foreach ($this->persistentServices as $serviceName => $service) { + foreach (array_keys($this->persistentServices) as $serviceName) { if ($this->container->has($serviceName)) { $this->persistentServices[$serviceName] = $this->container->get($serviceName); } @@ -87,6 +89,7 @@ public function rebootKernel() $this->kernel->shutdown(); $this->kernel->boot(); + $this->container = $this->kernel->getContainer(); foreach ($this->persistentServices as $serviceName => $service) { diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index d47ad839..44cfce87 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -1,7 +1,10 @@ initializeSymfonyCache(); $this->kernelClass = $this->getKernelClass(); $maxNestingLevel = 200; // Symfony may have very long nesting level $xdebugMaxLevelKey = 'xdebug.max_nesting_level'; if (ini_get($xdebugMaxLevelKey) < $maxNestingLevel) { - ini_set($xdebugMaxLevelKey, $maxNestingLevel); + ini_set($xdebugMaxLevelKey, (string) $maxNestingLevel); } $this->kernel = new $this->kernelClass($this->config['environment'], $this->config['debug']); @@ -177,7 +188,7 @@ public function _initialize() } /** - * Require Symfonys bootstrap.php.cache only for PHP Version < 7 + * Require Symfony's bootstrap.php.cache (only for PHP Version < 7) * * @throws ModuleRequireException */ @@ -186,7 +197,7 @@ private function initializeSymfonyCache() $cache = Configuration::projectDir() . $this->config['var_path'] . DIRECTORY_SEPARATOR . 'bootstrap.php.cache'; if (PHP_VERSION_ID < 70000 && !file_exists($cache)) { throw new ModuleRequireException( - __CLASS__, + self::class, "Symfony bootstrap file not found in $cache\n \n" . "Please specify path to bootstrap file using `var_path` config option\n \n" . "If you are trying to load bootstrap from a Bundle provide path like:\n \n" . @@ -203,8 +214,10 @@ private function initializeSymfonyCache() /** * Initialize new client instance before each test + * + * @param TestInterface $test */ - public function _before(\Codeception\TestInterface $test) + public function _before(TestInterface $test) { $this->persistentServices = array_merge($this->persistentServices, $this->permanentServices); $this->client = new SymfonyConnector($this->kernel, $this->persistentServices, $this->config['rebootable_client']); @@ -212,10 +225,12 @@ public function _before(\Codeception\TestInterface $test) /** * Update permanent services after each test + * + * @param TestInterface $test */ - public function _after(\Codeception\TestInterface $test) + public function _after(TestInterface $test) { - foreach ($this->permanentServices as $serviceName => $service) { + foreach (array_keys($this->permanentServices) as $serviceName) { $this->permanentServices[$serviceName] = $this->grabService($serviceName); } parent::_after($test); @@ -258,7 +273,7 @@ public function _getEntityManager() /** * Return container. * - * @return ContainerInterface + * @return ContainerInterface|mixed */ public function _getContainer() { @@ -281,13 +296,14 @@ public function _getContainer() * When the Kernel is located, the file is required. * * @return string The Kernel class name + * @throws ModuleRequireException|ReflectionException|ModuleException */ protected function getKernelClass() { $path = codecept_root_dir() . $this->config['app_path']; if (!file_exists(codecept_root_dir() . $this->config['app_path'])) { throw new ModuleRequireException( - __CLASS__, + self::class, "Can't load Kernel from $path.\n" . "Directory does not exists. Use `app_path` parameter to provide valid application path" ); @@ -296,9 +312,9 @@ protected function getKernelClass() $finder = new Finder(); $finder->name('*Kernel.php')->depth('0')->in($path); $results = iterator_to_array($finder); - if (!count($results)) { + if (count($results) === 0) { throw new ModuleRequireException( - __CLASS__, + self::class, "File with Kernel class was not found at $path. " . "Specify directory where file with Kernel class for your application is located with `app_path` parameter." ); @@ -318,7 +334,7 @@ protected function getKernelClass() foreach ($possibleKernelClasses as $class) { if (class_exists($class)) { - $refClass = new \ReflectionClass($class); + $refClass = new ReflectionClass($class); if ($file = array_search($refClass->getFileName(), $filesRealPath)) { return $class; } @@ -326,7 +342,7 @@ protected function getKernelClass() } throw new ModuleRequireException( - __CLASS__, + self::class, "Kernel class was not found in $file. " . "Specify directory where file with Kernel class for your application is located with `app_path` parameter." ); @@ -339,7 +355,7 @@ protected function getKernelClass() * @param string $serviceName * @param boolean $isPermanent */ - public function persistService($serviceName, $isPermanent = false) + public function persistService(string $serviceName, bool $isPermanent = false) { $service = $this->grabService($serviceName); $this->persistentServices[$serviceName] = $service; @@ -356,7 +372,7 @@ public function persistService($serviceName, $isPermanent = false) * * @param string $serviceName */ - public function unpersistService($serviceName) + public function unpersistService(string $serviceName) { if (isset($this->persistentServices[$serviceName])) { unset($this->persistentServices[$serviceName]); @@ -384,13 +400,12 @@ public function invalidateCachedRouter() * amOnRoute('posts.create'); * $I->amOnRoute('posts.show', array('id' => 34)); - * ?> * ``` * - * @param $routeName + * @param string $routeName * @param array $params */ - public function amOnRoute($routeName, array $params = []) + public function amOnRoute(string $routeName, array $params = []) { $router = $this->grabService('router'); if (!$router->getRouteCollection()->get($routeName)) { @@ -407,13 +422,12 @@ public function amOnRoute($routeName, array $params = []) * seeCurrentRouteIs('posts.index'); * $I->seeCurrentRouteIs('posts.show', array('id' => 8)); - * ?> * ``` * - * @param $routeName + * @param string $routeName * @param array $params */ - public function seeCurrentRouteIs($routeName, array $params = []) + public function seeCurrentRouteIs(string $routeName, array $params = []) { $router = $this->grabService('router'); if (!$router->getRouteCollection()->get($routeName)) { @@ -423,7 +437,7 @@ public function seeCurrentRouteIs($routeName, array $params = []) $uri = explode('?', $this->grabFromCurrentUrl())[0]; try { $match = $router->match($uri); - } catch (\Symfony\Component\Routing\Exception\ResourceNotFoundException $e) { + } catch (ResourceNotFoundException $e) { $this->fail(sprintf('The "%s" url does not match with any route', $uri)); } $expected = array_merge(['_route' => $routeName], $params); @@ -438,13 +452,12 @@ public function seeCurrentRouteIs($routeName, array $params = []) * * ``` php * seeCurrentRouteMatches('my_blog_pages'); - * ?> + * $I->seeInCurrentRoute('my_blog_pages'); * ``` * - * @param $routeName + * @param string $routeName */ - public function seeInCurrentRoute($routeName) + public function seeInCurrentRoute(string $routeName) { $router = $this->grabService('router'); if (!$router->getRouteCollection()->get($routeName)) { @@ -454,7 +467,7 @@ public function seeInCurrentRoute($routeName) $uri = explode('?', $this->grabFromCurrentUrl())[0]; try { $matchedRouteName = $router->match($uri)['_route']; - } catch (\Symfony\Component\Routing\Exception\ResourceNotFoundException $e) { + } catch (ResourceNotFoundException $e) { $this->fail(sprintf('The "%s" url does not match with any route', $uri)); } @@ -471,7 +484,7 @@ public function seeInCurrentRoute($routeName) * * @param string $url */ - public function seePageIsAvailable($url) + public function seePageIsAvailable(string $url) { $this->amOnPage($url); $this->seeResponseCodeIsSuccessful(); @@ -489,7 +502,7 @@ public function seePageIsAvailable($url) * @param string $page * @param string $redirectsTo */ - public function seePageRedirectsTo($page, $redirectsTo) + public function seePageRedirectsTo(string $page, string $redirectsTo) { $this->client->followRedirects(false); $this->amOnPage($page); @@ -518,7 +531,6 @@ public function seeEmailIsSent($expectedCount = null) { if (!$profile = $this->getProfile()) { $this->fail("Emails can't be tested without Profiler"); - return; } $mailer = $this->config['mailer']; @@ -532,7 +544,6 @@ public function seeEmailIsSent($expectedCount = null) Set your mailer service in `functional.suite.yml`: `mailer: swiftmailer` (Or `mailer: symfony_mailer` for Symfony Mailer)." ); - return; } if (!is_int($expectedCount) && !is_null($expectedCount)) { @@ -540,7 +551,6 @@ public function seeEmailIsSent($expectedCount = null) 'The required number of emails must be either an integer or null. "%s" was provided.', print_r($expectedCount, true) )); - return; } $mailCollector = $profile->getCollector($mailer); @@ -578,14 +588,13 @@ public function dontSeeEmailIsSent() * ``` php * grabService('doctrine'); - * ?> * ``` * - * @param $service + * @param string $service * @return mixed * @part services */ - public function grabService($service) + public function grabService(string $service) { $container = $this->_getContainer(); if (!$container->has($service)) { @@ -603,7 +612,6 @@ public function grabService($service) * ``` php * runSymfonyConsoleCommand('hello:world', ['arg' => 'argValue', 'opt1' => 'optValue'], ['input']); - * ?> * ``` * * @param string $command The console command to execute @@ -613,7 +621,7 @@ public function grabService($service) * * @return string Returns the console output of the command */ - public function runSymfonyConsoleCommand($command, $parameters = [], $consoleInputs = [], $expectedExitCode = 0) + public function runSymfonyConsoleCommand(string $command, array $parameters = [], array $consoleInputs = [], int $expectedExitCode = 0): string { $kernel = $this->grabService('kernel'); $application = new Application($kernel); @@ -636,7 +644,7 @@ public function runSymfonyConsoleCommand($command, $parameters = [], $consoleInp } /** - * @return \Symfony\Component\HttpKernel\Profiler\Profile + * @return Profile|null */ protected function getProfile() { @@ -649,9 +657,9 @@ protected function getProfile() try { $response = $this->client->getResponse(); return $profiler->loadProfileFromResponse($response); - } catch (\BadMethodCallException $e) { + } catch (BadMethodCallException $e) { $this->fail('You must perform a request before using this method.'); - } catch (\Exception $e) { + } catch (Exception $e) { $this->fail($e->getMessage()); } return null; @@ -703,7 +711,7 @@ protected function debugResponse($url) * @param Data $data * @return array */ - private function extractRawRoles(Data $data) + private function extractRawRoles(Data $data): array { if ($this->dataRevealsValue($data)) { $roles = $data->getValue(); @@ -718,14 +726,14 @@ private function extractRawRoles(Data $data) /** * Returns a list of recognized domain names. * - * @return array + * @return mixed[] */ - protected function getInternalDomains() + protected function getInternalDomains(): array { $internalDomains = []; $routes = $this->grabService('router')->getRouteCollection(); - /* @var \Symfony\Component\Routing\Route $route */ + /* @var Route $route */ foreach ($routes as $route) { if (!is_null($route->getHost())) { $compiled = $route->compile(); @@ -744,15 +752,13 @@ protected function getInternalDomains() * * ``` php * rebootClientKernel(); - * ... - * perform other requests - * ... * - * ?> + * // Perform other requests + * * ``` * */ @@ -766,11 +772,11 @@ public function rebootClientKernel() /** * Public API from Data changed from Symfony 3.2 to 3.3. * - * @param \Symfony\Component\VarDumper\Cloner\Data $data + * @param Data $data * * @return bool */ - private function dataRevealsValue(Data $data) + private function dataRevealsValue(Data $data): bool { return method_exists($data, 'getValue'); } @@ -779,6 +785,7 @@ private function dataRevealsValue(Data $data) * Returns list of the possible kernel classes based on the module configuration * * @return array + * @throws ModuleException */ private function getPossibleKernelClasses() { @@ -788,7 +795,7 @@ private function getPossibleKernelClasses() if (!is_string($this->config['kernel_class'])) { throw new ModuleException( - __CLASS__, + self::class, "Parameter 'kernel_class' must have 'string' type.\n" ); } @@ -810,7 +817,7 @@ private function getPossibleKernelClasses() * @param string $className A doctrine entity * @param array $criteria Optional query criteria */ - public function seeNumRecords($expectedNum, $className, $criteria = []) + public function seeNumRecords(int $expectedNum, string $className, array $criteria = []) { $em = $this->_getEntityManager(); $repository = $em->getRepository($className); @@ -884,7 +891,7 @@ public function logout() * @param mixed|null $value * @return void */ - public function seeInSession($attrib, $value = null) + public function seeInSession(string $attrib, $value = null) { $container = $this->_getContainer(); @@ -916,7 +923,7 @@ public function seeInSession($attrib, $value = null) * @param string $action * @param array $params */ - public function amOnAction($action, $params = []) + public function amOnAction(string $action, array $params = []) { $container = $this->_getContainer(); @@ -955,7 +962,7 @@ public function amOnAction($action, $params = []) * * @param bool $remembered */ - public function seeAuthentication($remembered = false) + public function seeAuthentication(bool $remembered = false) { $container = $this->_getContainer(); @@ -971,11 +978,7 @@ public function seeAuthentication($remembered = false) $this->fail('There is no user in session'); } - if ($remembered) { - $role = 'IS_AUTHENTICATED_REMEMBERED'; - } else { - $role = 'IS_AUTHENTICATED_FULLY'; - } + $role = $remembered ? 'IS_AUTHENTICATED_REMEMBERED' : 'IS_AUTHENTICATED_FULLY'; $this->assertTrue($security->isGranted($role), 'There is no authenticated user'); } @@ -997,7 +1000,7 @@ public function seeAuthentication($remembered = false) * @param string $name * @param string[] $fields */ - public function submitSymfonyForm($name, $fields) + public function submitSymfonyForm(string $name, array $fields) { $selector = sprintf('form[name=%s]', $name); @@ -1021,7 +1024,7 @@ public function submitSymfonyForm($name, $fields) * * @param string $role */ - public function seeUserHasRole($role) + public function seeUserHasRole(string $role) { $container = $this->_getContainer(); @@ -1058,7 +1061,7 @@ public function seeUserHasRole($role) * * @param bool $remembered */ - public function dontSeeAuthentication($remembered = true) + public function dontSeeAuthentication(bool $remembered = true) { $container = $this->_getContainer(); @@ -1068,11 +1071,7 @@ public function dontSeeAuthentication($remembered = true) $security = $this->grabService('security.helper'); - if ($remembered) { - $role = 'IS_AUTHENTICATED_REMEMBERED'; - } else { - $role = 'IS_AUTHENTICATED_FULLY'; - } + $role = $remembered ? 'IS_AUTHENTICATED_REMEMBERED' : 'IS_AUTHENTICATED_FULLY'; $this->assertFalse( $security->isGranted($role), @@ -1091,7 +1090,7 @@ public function dontSeeAuthentication($remembered = true) * @param string $name * @return mixed|null */ - public function grabParameter($name) + public function grabParameter(string $name) { $container = $this->_getContainer(); @@ -1114,7 +1113,7 @@ public function grabParameter($name) * * @param string $action */ - public function seeCurrentActionIs($action) + public function seeCurrentActionIs(string $action) { $container = $this->_getContainer(); @@ -1157,7 +1156,7 @@ public function seeUserPasswordDoesNotNeedRehash(UserInterface $user = null) { $container = $this->_getContainer(); - if (!$user) { + if ($user === null) { if (!$container->has('security.helper')) { $this->fail("Symfony container doesn't have 'security.helper' service"); } @@ -1177,7 +1176,7 @@ public function seeUserPasswordDoesNotNeedRehash(UserInterface $user = null) $this->assertFalse($encoder->needsRehash($user), 'User password needs rehash'); } - public function amLoggedInAs(UserInterface $user, $firewallName = 'main', $firewallContext = null) + public function amLoggedInAs(UserInterface $user, string $firewallName = 'main', $firewallContext = null) { $container = $this->_getContainer(); if (!$container->has('session')) {