From 5ac21861a45e76c2f2a5a53997dd320874c74052 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Thu, 10 Sep 2020 11:00:23 -0500 Subject: [PATCH 1/7] Added logout function --- documentation.md | 9 ++++++ src/Codeception/Module/Symfony.php | 46 +++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/documentation.md b/documentation.md index a9d3f016..6b739087 100644 --- a/documentation.md +++ b/documentation.md @@ -747,6 +747,15 @@ $I->haveHttpHeader('Client_Id', 'Codeception'); Invalidate previously cached routes. +### logout + +Invalidate the current session. +```php +logout(); +``` + + ### makeHtmlSnapshot Saves current page's HTML into a temprary file. diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index 1a0c6a9f..b3de67b1 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -787,15 +787,14 @@ private function getPossibleKernelClasses() */ public function seeNumRecords($expectedNum, $className, $criteria = []) { - $em = $this->_getEntityManager(); + $em = $this->_getEntityManager(); $repository = $em->getRepository($className); if (empty($criteria)) { - $currentNum = (int) $repository->createQueryBuilder('a') + $currentNum = (int)$repository->createQueryBuilder('a') ->select('count(a.id)') ->getQuery() - ->getSingleScalarResult() - ; + ->getSingleScalarResult(); } else { $currentNum = $repository->count($criteria); } @@ -809,4 +808,43 @@ public function seeNumRecords($expectedNum, $className, $criteria = []) ) ); } + + /** + * Invalidate the current session. + * ```php + * logout(); + * ``` + */ + public function logout() + { + $container = $this->_getContainer(); + + if ($container->has('security.token_storage')) { + $tokenStorage = $this->grabService('security.token_storage'); + $tokenStorage->setToken(null); + } + + if (!$container->has('session')) { + $this->fail("Symfony container doesn't have 'session' service"); + return; + } + $session = $this->grabService('session'); + + $sessionName = $session->getName(); + $session->invalidate(); + + $cookieJar = $this->client->getCookieJar(); + foreach ($cookieJar->all() as $cookie) { + $cookieName = $cookie->getName(); + if ($cookieName === 'MOCKSESSID' || + $cookieName === 'REMEMBERME' || + $cookieName === $sessionName + ) { + $cookieJar->expire($cookieName); + } + } + $cookieJar->flushExpiredCookies(); + + } } From 1504e65ea67b2cf56e3385300d1f0da423ce287a Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Thu, 10 Sep 2020 20:03:36 -0500 Subject: [PATCH 2/7] Added seeInSession function --- documentation.md | 15 ++++++++++++++ src/Codeception/Module/Symfony.php | 32 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/documentation.md b/documentation.md index 6b739087..560a83bf 100644 --- a/documentation.md +++ b/documentation.md @@ -1101,6 +1101,21 @@ $I->seeInFormFields('//form[@id=my-form]', $form); * `param` $params +### seeInSession + +Assert that a session attribute exists. + +```php +seeInSession('attrib'); +$I->seeInSession('attrib', 'value'); +``` + + * `param string` $attrib + * `param mixed|null` $value + * `return` void + + ### seeInSource Checks that the current page contains the given string in its diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index b3de67b1..0bfe503d 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -845,6 +845,38 @@ public function logout() } } $cookieJar->flushExpiredCookies(); + } + + /** + * Assert that a session attribute exists. + * + * ```php + * seeInSession('attrib'); + * $I->seeInSession('attrib', 'value'); + * ``` + * + * @param string $attrib + * @param mixed|null $value + * @return void + */ + public function seeInSession($attrib, $value = null) + { + $container = $this->_getContainer(); + if (!$container->has('session')) { + $this->fail("Symfony container doesn't have 'session' service"); + return; + } + + $session = $this->grabService('session'); + + if (! $session->has($attrib)) { + $this->fail("No session attribute with name '$attrib'"); + } + + if (null !== $value) { + $this->assertEquals($value, $session->get($attrib)); + } } } From b24e2b61c14a5573f6111ac55d7750d88b5eb044 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Fri, 11 Sep 2020 15:39:23 -0500 Subject: [PATCH 3/7] Added amOnAction function --- documentation.md | 15 ++++++++++ src/Codeception/Module/Symfony.php | 44 +++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/documentation.md b/documentation.md index 560a83bf..dc4d911b 100644 --- a/documentation.md +++ b/documentation.md @@ -220,6 +220,21 @@ Authenticates user for HTTP_AUTH * `param` $password +### amOnAction + +Opens web page by action name + +``` php +amOnAction('PostController::index'); +$I->amOnAction('HomeController'); +$I->amOnAction('ArticleController', ['slug' => 'lorem-ipsum']); +``` + + * `param string` $action + * `param array` $params + + ### amOnPage Opens the page for the given relative URI. diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index 0bfe503d..a317ad5f 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -13,6 +13,7 @@ use Symfony\Component\Finder\Finder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Finder\SplFileInfo; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArrayInput; @@ -871,7 +872,7 @@ public function seeInSession($attrib, $value = null) $session = $this->grabService('session'); - if (! $session->has($attrib)) { + if (!$session->has($attrib)) { $this->fail("No session attribute with name '$attrib'"); } @@ -879,4 +880,45 @@ public function seeInSession($attrib, $value = null) $this->assertEquals($value, $session->get($attrib)); } } + + /** + * Opens web page by action name + * + * ``` php + * amOnAction('PostController::index'); + * $I->amOnAction('HomeController'); + * $I->amOnAction('ArticleController', ['slug' => 'lorem-ipsum']); + * ``` + * + * @param string $action + * @param array $params + */ + public function amOnAction($action, $params = []) + { + $container = $this->_getContainer(); + + if (!$container->has('router')) { + $this->fail("Symfony container doesn't have 'router' service"); + return; + } + + $router = $this->grabService('router'); + + $routes = $router->getRouteCollection()->getIterator(); + + foreach ($routes as $route) { + $controller = basename($route->getDefault('_controller')); + if ($controller === $action) { + $resource = $router->match($route->getPath()); + $url = $router->generate( + $resource['_route'], + $params, + UrlGeneratorInterface::ABSOLUTE_PATH + ); + $this->amOnPage($url); + return; + } + } + } } From 1d3020f0c886666a7384ac840a530819f3996dd6 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Fri, 11 Sep 2020 21:17:14 -0500 Subject: [PATCH 4/7] Added seeAuthentication function --- documentation.md | 14 ++++++++++ src/Codeception/Module/Symfony.php | 41 +++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/documentation.md b/documentation.md index dc4d911b..802616a6 100644 --- a/documentation.md +++ b/documentation.md @@ -890,6 +890,20 @@ For checking the raw source code, use `seeInSource()`. * `param array|string` $selector optional +### seeAuthentication + +Checks that a user is authenticated. +You can check users logged in with the option 'remember me' passing true as parameter. + +```php +seeAuthentication(); +$I->seeAuthentication(true); +``` + + * `param bool` $remembered + + ### seeCheckboxIsChecked Checks that the specified checkbox is checked. diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index a317ad5f..73967b9f 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -911,7 +911,7 @@ public function amOnAction($action, $params = []) $controller = basename($route->getDefault('_controller')); if ($controller === $action) { $resource = $router->match($route->getPath()); - $url = $router->generate( + $url = $router->generate( $resource['_route'], $params, UrlGeneratorInterface::ABSOLUTE_PATH @@ -921,4 +921,43 @@ public function amOnAction($action, $params = []) } } } + + /** + * Checks that a user is authenticated. + * You can check users logged in with the option 'remember me' passing true as parameter. + * + * ```php + * seeAuthentication(); + * $I->seeAuthentication(true); + * ``` + * + * @param bool $remembered + */ + public function seeAuthentication($remembered = false) + { + $container = $this->_getContainer(); + + if (!$container->has('security.helper')) { + $this->fail("Symfony container doesn't have 'security.helper' service"); + return; + } + + $security = $this->grabService('security.helper'); + + $user = $security->getUser(); + + if (!$user) { + $this->fail('There is no user in session'); + return; + } + + if ($remembered) { + $role = 'IS_AUTHENTICATED_REMEMBERED'; + } else { + $role = 'IS_AUTHENTICATED_FULLY'; + } + + $this->assertTrue($security->isGranted($role), 'There is no authenticated user'); + } } From 3c652473509119fa4a5be8a1f92f6fb128cc7a59 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Fri, 11 Sep 2020 21:37:50 -0500 Subject: [PATCH 5/7] Added seeUserHasRole function --- documentation.md | 12 ++++++++++ src/Codeception/Module/Symfony.php | 38 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/documentation.md b/documentation.md index 802616a6..addb0222 100644 --- a/documentation.md +++ b/documentation.md @@ -1281,6 +1281,18 @@ Checks that the response code is 5xx Checks that the response code 2xx +### seeUserHasRole + +Check that the current user has a role + +```php +seeUserHasRole('ROLE_ADMIN'); +``` + + * `param string` $role + + ### selectOption Selects an option in a select tag or in radio button group. diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index 73967b9f..15024a18 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -960,4 +960,42 @@ public function seeAuthentication($remembered = false) $this->assertTrue($security->isGranted($role), 'There is no authenticated user'); } + + /** + * Check that the current user has a role + * + * ```php + * seeUserHasRole('ROLE_ADMIN'); + * ``` + * + * @param string $role + */ + public function seeUserHasRole($role) + { + $container = $this->_getContainer(); + + if (!$container->has('security.helper')) { + $this->fail("Symfony container doesn't have 'security.helper' service"); + return; + } + + $security = $this->grabService('security.helper'); + + $user = $security->getUser(); + + if (!$user) { + $this->fail('There is no user in session'); + return; + } + + $this->assertTrue( + $security->isGranted($role), + sprintf( + "User %s has no role %s", + $user->getUsername(), + $role + ) + ); + } } From 321ef5e9241443bc225a85079acaea3db1a6ea10 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Fri, 11 Sep 2020 23:15:14 -0500 Subject: [PATCH 6/7] Added dontSeeAuthentication function --- documentation.md | 14 ++++++++++++ src/Codeception/Module/Symfony.php | 34 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/documentation.md b/documentation.md index addb0222..c153bf76 100644 --- a/documentation.md +++ b/documentation.md @@ -376,6 +376,20 @@ For checking the raw source code, use `seeInSource()`. * `param array|string` $selector optional +### dontSeeAuthentication + +Check that user is not authenticated. +You can specify whether users logged in with the 'remember me' option should be ignored by passing 'false' as a parameter. + +```php +dontSeeAuthentication(); +$I->dontSeeAuthentication(false); +``` + + * `param bool` $remembered + + ### dontSeeCheckboxIsChecked Check that the specified checkbox is unchecked. diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index 15024a18..88ad0530 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -998,4 +998,38 @@ public function seeUserHasRole($role) ) ); } + + /** + * Check that user is not authenticated. + * You can specify whether users logged in with the 'remember me' option should be ignored by passing 'false' as a parameter. + * + * ```php + * dontSeeAuthentication(); + * ``` + * + * @param bool $remembered + */ + public function dontSeeAuthentication($remembered = true) + { + $container = $this->_getContainer(); + + if (!$container->has('security.helper')) { + $this->fail("Symfony container doesn't have 'security.helper' service"); + return; + } + + $security = $this->grabService('security.helper'); + + if ($remembered) { + $role = 'IS_AUTHENTICATED_REMEMBERED'; + } else { + $role = 'IS_AUTHENTICATED_FULLY'; + } + + $this->assertFalse( + $security->isGranted($role), + 'There is an user authenticated' + ); + } } From f7449fb613bbc7854fa13c9dfb51d100311c4284 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J Date: Sat, 12 Sep 2020 10:20:36 -0500 Subject: [PATCH 7/7] Added seeCurrentActionIs function --- documentation.md | 13 +++++++++++ src/Codeception/Module/Symfony.php | 37 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/documentation.md b/documentation.md index c153bf76..6c554be5 100644 --- a/documentation.md +++ b/documentation.md @@ -948,6 +948,19 @@ $I->seeCookie('PHPSESSID'); * `param array` $params +### seeCurrentActionIs + +Checks that current page matches action + +``` php +seeCurrentActionIs('PostController::index'); +$I->seeCurrentActionIs('HomeController'); +``` + + * `param string` $action + + ### seeCurrentRouteIs Checks that current url matches route. diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index 88ad0530..e54a36b4 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -1032,4 +1032,41 @@ public function dontSeeAuthentication($remembered = true) 'There is an user authenticated' ); } + + /** + * Checks that current page matches action + * + * ``` php + * seeCurrentActionIs('PostController::index'); + * $I->seeCurrentActionIs('HomeController'); + * ``` + * + * @param string $action + */ + public function seeCurrentActionIs($action) + { + $container = $this->_getContainer(); + + if (!$container->has('router')) { + $this->fail("Symfony container doesn't have 'router' service"); + return; + } + + $router = $this->grabService('router'); + + $routes = $router->getRouteCollection()->getIterator(); + + foreach ($routes as $route) { + $controller = basename($route->getDefault('_controller')); + if ($controller === $action) { + $request = $this->client->getRequest(); + $currentAction = basename($request->attributes->get('_controller')); + + $this->assertEquals($currentAction, $action, "Current action is '$currentAction'."); + return; + } + } + $this->fail("Action '$action' does not exist"); + } }