Skip to content

Commit

Permalink
Merge pull request #603 from alexislefebvre/sf6-from-magnetik
Browse files Browse the repository at this point in the history
Support Symfony 6
  • Loading branch information
alexislefebvre authored Jun 21, 2022
2 parents b1e96cb + 86c2e2b commit 377353a
Show file tree
Hide file tree
Showing 17 changed files with 217 additions and 44 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
symfony-version: "^4.4"
- php-version: 8.0
symfony-version: "^4.4"
- php-version: 8.1
symfony-version: "^6.0"

steps:
- name: Checkout
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 5.0

Removed features deprecated in [4.6](#4.6) and [4.0](#4.0)

## 4.7

Deprecations from [4.6](#4.6) will now trigger an `E_USER_DEPRECATED` deprecation

## 4.6

Deprecated the following methods, use [loginUser() from Symfony 5.1+](https://symfony.com/doc/5.4/testing.html#logging-in-users-authentication) instead of:
- `makeClient`
- `makeAuthenticatedClient`
- `makeClientWithCredentials`
- `loginAs`
- `loginClient`
- `createClientWithParams`

## 4.0

### Removed
Expand Down
22 changes: 11 additions & 11 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@
"php": "^7.2 || ^8.0",
"doctrine/annotations": "^1.3",
"phpunit/phpunit": "^7.5.0 || ^8.0 || ^9.0",
"symfony/browser-kit": "^4.4 || ^5.1",
"symfony/framework-bundle": "^4.4 || ^5.1"
"symfony/browser-kit": "^4.4 || ^5.1 || ^6.0",
"symfony/framework-bundle": "^4.4 || ^5.1 || ^6.0"
},
"require-dev": {
"ext-json": "*",
"doctrine/doctrine-bundle": "^2.1",
"doctrine/orm": "^2.7",
"monolog/monolog": "~1.11",
"symfony/css-selector": "^4.4 || ^5.1",
"symfony/doctrine-bridge": "^4.4 || ^5.1",
"symfony/form": "^4.4 || ^5.1",
"symfony/http-kernel": "^4.4 || ^5.1",
"symfony/css-selector": "^4.4 || ^5.1 || ^6.0",
"symfony/doctrine-bridge": "^4.4 || ^5.1 || ^6.0",
"symfony/form": "^4.4 || ^5.1 || ^6.0",
"symfony/http-kernel": "^4.4 || ^5.1 || ^6.0",
"symfony/monolog-bundle": "^3.4",
"symfony/phpunit-bridge": "^4.4 || ^5.1",
"symfony/security-bundle": "^4.4 || ^5.1",
"symfony/twig-bundle": "^4.4 || ^5.1",
"symfony/validator": "^4.4 || ^5.1",
"symfony/yaml": "^4.4 || ^5.1",
"symfony/phpunit-bridge": "^4.4 || ^5.1 || ^6.0",
"symfony/security-bundle": "^4.4 || ^5.1 || ^6.0",
"symfony/twig-bundle": "^4.4 || ^5.1 || ^6.0",
"symfony/validator": "^4.4 || ^5.1 || ^6.0",
"symfony/yaml": "^4.4 || ^5.1 || ^6.0",
"twig/twig": "^2.0 || ^3.0"
},
"conflict": {
Expand Down
4 changes: 3 additions & 1 deletion src/QueryCountClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

namespace Liip\FunctionalTestBundle;

use Symfony\Component\DomCrawler\Crawler;

/**
* @author Sullivan Senechal <[email protected]>
*
Expand All @@ -28,7 +30,7 @@ public function request(
array $server = [],
string $content = null,
bool $changeHistory = true
) {
): Crawler {
$crawler = parent::request($method, $uri, $parameters, $files, $server, $content, $changeHistory);
$this->checkQueryCount();

Expand Down
118 changes: 114 additions & 4 deletions src/Test/WebTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
Expand Down Expand Up @@ -248,6 +253,9 @@ public function __call(string $name, $arguments)
throw new \Exception("Method {$name} is not supported.");
}

/**
* @deprecated
*/
public function __set($name, $value): void
{
if ('environment' !== $name) {
Expand All @@ -259,6 +267,9 @@ public function __set($name, $value): void
static::$env = $value;
}

/**
* @deprecated
*/
public function __isset($name)
{
if ('environment' !== $name) {
Expand All @@ -270,6 +281,9 @@ public function __isset($name)
return true;
}

/**
* @deprecated
*/
public function __get($name)
{
if ('environment' !== $name) {
Expand All @@ -287,6 +301,8 @@ public function __get($name)
* $params can be used to pass headers to the client, note that they have
* to follow the naming format used in $_SERVER.
* Example: 'HTTP_X_REQUESTED_WITH' instead of 'X-Requested-With'
*
* @deprecated
*/
protected function makeClient(array $params = []): Client
{
Expand All @@ -299,6 +315,8 @@ protected function makeClient(array $params = []): Client
* $params can be used to pass headers to the client, note that they have
* to follow the naming format used in $_SERVER.
* Example: 'HTTP_X_REQUESTED_WITH' instead of 'X-Requested-With'
*
* @deprecated
*/
protected function makeAuthenticatedClient(array $params = []): Client
{
Expand All @@ -317,6 +335,8 @@ protected function makeAuthenticatedClient(array $params = []): Client
* $params can be used to pass headers to the client, note that they have
* to follow the naming format used in $_SERVER.
* Example: 'HTTP_X_REQUESTED_WITH' instead of 'X-Requested-With'
*
* @deprecated
*/
protected function makeClientWithCredentials(string $username, string $password, array $params = []): Client
{
Expand All @@ -338,6 +358,17 @@ protected function makeClientWithCredentials(string $username, string $password,
*/
protected function createUserToken(UserInterface $user, string $firewallName): TokenInterface
{
// Since Symfony 6.0, UsernamePasswordToken only has 3 arguments
$usernamePasswordTokenClass = new \ReflectionClass(UsernamePasswordToken::class);

if (3 === $usernamePasswordTokenClass->getConstructor()->getNumberOfParameters()) {
return new UsernamePasswordToken(
$user,
$firewallName,
$user->getRoles()
);
}

return new UsernamePasswordToken(
$user,
null,
Expand Down Expand Up @@ -413,6 +444,8 @@ public function fetchCrawler(string $path, string $method = 'GET', bool $authent
}

/**
* @deprecated
*
* @return WebTestCase
*/
public function loginAs(UserInterface $user, string $firewallName): self
Expand All @@ -424,17 +457,36 @@ public function loginAs(UserInterface $user, string $firewallName): self
return $this;
}

/**
* @deprecated
*/
public function loginClient(KernelBrowser $client, UserInterface $user, string $firewallName): void
{
// Available since Symfony 5.1
if (method_exists($client, 'loginUser')) {
// TODO: enable this on the next minor release
// @trigger_error(
// sprintf(
// '"%s()" is deprecated, use loginUser() from Symfony 5.1+ instead %s',
// __METHOD__,
// 'https://symfony.com/doc/5.4/testing.html#logging-in-users-authentication'
// ),
// \E_USER_DEPRECATED
// );

$client->loginUser($user);

return;
}

// has to be set otherwise "hasPreviousSession" in Request returns false.
$options = $client->getContainer()->getParameter('session.storage.options');

if (!$options || !isset($options['name'])) {
throw new \InvalidArgumentException('Missing session.storage.options#name');
}

$session = $client->getContainer()->get('session');
$session->setId(uniqid());
$session = $this->getSession($client);

$client->getCookieJar()->set(new Cookie($options['name'], $session->getId()));

Expand Down Expand Up @@ -484,6 +536,9 @@ protected function tearDown(): void
parent::tearDown();
}

/**
* @deprecated
*/
protected function createClientWithParams(array $params, ?string $username = null, ?string $password = null): Client
{
if ($username && $password) {
Expand All @@ -507,15 +562,31 @@ protected function createClientWithParams(array $params, ?string $username = nul
throw new \InvalidArgumentException('Missing session.storage.options#name');
}

$session = $client->getContainer()->get('session');
$session->setId(uniqid());
$session = $this->getSession($client);

$client->getCookieJar()->set(new Cookie($options['name'], $session->getId()));

/** @var $user UserInterface */
foreach ($this->firewallLogins as $firewallName => $user) {
$token = $this->createUserToken($user, $firewallName);

// Available since Symfony 5.1
if (method_exists($client, 'loginUser')) {
// TODO: enable this on the next minor release
// @trigger_error(
// sprintf(
// '"%s()" is deprecated, use loginUser() from Symfony 5.1+ instead %s',
// __METHOD__,
// 'https://symfony.com/doc/5.4/testing.html#logging-in-users-authentication'
// ),
// \E_USER_DEPRECATED
// );

$client->loginUser($user);

continue;
}

$tokenStorage = $client->getContainer()->get('security.token_storage');

$tokenStorage->setToken($token);
Expand All @@ -527,4 +598,43 @@ protected function createClientWithParams(array $params, ?string $username = nul

return $client;
}

/**
* Compatibility layer.
*/
private function getSession(KernelBrowser $client): SessionInterface
{
$container = $client->getContainer();

// Preferred since Symfony 5.4
if ($container->has(RequestStack::class)) {
/** @var RequestStack $requestStack */
$requestStack = $container->get(RequestStack::class);

// see https://github.com/symfony/symfony-docs/pull/14898/files#diff-29ab32502d95be802fed1001850b76c9624912cf4c299101d3ecaf17b0352562R37
try {
$session = $requestStack->getSession();
} catch (SessionNotFoundException $e) {
$requestStack->push(new Request());
$session = new Session();
$session->start();
}

return $session;
}
// Available before Symfony 6
if ($container->has(SessionInterface::class)) {
/** @var SessionInterface $session */
$session = $container->get(SessionInterface::class);
}
// Fallback for Symfony 4.4
else {
/** @var \Symfony\Component\HttpFoundation\Session\Session $session */
$session = $container->get('session');
}

$session->start();

return $session;
}
}
16 changes: 12 additions & 4 deletions tests/App/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,32 @@ public function registerBundles(): array
public function registerContainerConfiguration(LoaderInterface $loader): void
{
$loader->load(__DIR__.'/config.yml');

if (Kernel::MAJOR_VERSION >= 5) {
$loader->load(__DIR__.'/security_5.yml');
$loader->load(__DIR__.'/session_5.yml');
} else {
$loader->load(__DIR__.'/security_4.yml');
$loader->load(__DIR__.'/session_4.yml');
}
}

public function getCacheDir()
public function getCacheDir(): string
{
return $this->getBaseDir().'cache';
}

public function getLogDir()
public function getLogDir(): string
{
return $this->getBaseDir().'log';
}

protected function getBaseDir()
protected function getBaseDir(): string
{
return sys_get_temp_dir().'/LiipFunctionalTestBundle/'.(new \ReflectionClass($this))->getShortName().'/var/';
}

public function getProjectDir()
public function getProjectDir(): string
{
return __DIR__;
}
Expand Down
16 changes: 9 additions & 7 deletions tests/App/Controller/DefaultController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Liip\Acme\Tests\App\Controller;

use Doctrine\ORM\EntityManagerInterface;
use Liip\Acme\Tests\App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
Expand All @@ -30,10 +31,10 @@ public function indexAction(): Response
);
}

public function userAction(int $userId): Response
public function userAction(EntityManagerInterface $entityManager, int $userId): Response
{
/** @var \Liip\Acme\Tests\App\Entity\User $user */
$user = $this->getDoctrine()
$user = $entityManager
->getRepository(User::class)
->find($userId);

Expand Down Expand Up @@ -74,16 +75,17 @@ private function form(Request $request, string $template): Response

$form->handleRequest($request);

$flashMessage = null;
if ($form->isSubmitted() && $form->isValid()) {
$this->get('session')->getFlashBag()->add(
'notice',
'Name submitted.'
);
$flashMessage = 'Name submitted.';
}

return $this->render(
$template,
['form' => $form->createView()]
[
'form' => $form->createView(),
'flash_message' => $flashMessage,
]
);
}

Expand Down
Loading

0 comments on commit 377353a

Please sign in to comment.