diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6e4dba22..91a55874 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,21 +10,23 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['7.4', '8.0', '8.1', '8.2'] + # Symfony 6.3 requires PHP >= 8.0, it will be installed on PHP >= 8.0 + # Symfony 7.0 requires PHP >= 8.2, it will be installed on PHP >= 8.2 + php-version: ['8.1', '8.2'] composer-flags: [''] - symfony-version: ['^5.4'] + symfony-version: ['^6.4'] include: - php-version: 7.4 - symfony-version: "^4.4" + symfony-version: "^5.4" composer-flags: "--prefer-lowest" - - php-version: 7.4 - symfony-version: "^4.4" - - php-version: 8.0 - symfony-version: "^4.4" - php-version: 8.1 - symfony-version: "^6.2" + symfony-version: "^5.4" + - php-version: 8.1 + symfony-version: "^6.4" + - php-version: 8.2 + symfony-version: "^6.4" - php-version: 8.2 - symfony-version: "^6.2" + symfony-version: "^7.0" steps: - name: Checkout diff --git a/composer.json b/composer.json index 702a679a..5b5fff92 100644 --- a/composer.json +++ b/composer.json @@ -17,25 +17,25 @@ "require": { "php": "^7.4 || ^8.0", "phpunit/phpunit": "^9.6 || ^10.0", - "symfony/browser-kit": "^4.4 || ^5.1 || ^6.0", - "symfony/framework-bundle": "^4.4 || ^5.1 || ^6.0" + "symfony/browser-kit": "^5.4 || ^6.4 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.0" }, "require-dev": { "ext-json": "*", "doctrine/annotations": "^1.3 || ^2.0", - "doctrine/doctrine-bundle": "^2.1", + "doctrine/doctrine-bundle": "^2.11", "doctrine/orm": "^2.7", - "monolog/monolog": "~1.11", - "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", + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "symfony/css-selector": "^5.4 || ^6.4 || ^7.0", + "symfony/doctrine-bridge": "^5.4 || ^6.4 || ^7.0", + "symfony/form": "^5.4 || ^6.4 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.4 || ^7.0", "symfony/monolog-bundle": "^3.4", - "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" + "symfony/security-bundle": "^5.4 || ^6.4 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.0", + "symfony/validator": "^5.4 || ^6.4 || ^7.0", + "symfony/yaml": "^5.4 || ^6.4 || ^7.0", + "twig/twig": "^2.0 || ^3.8" }, "conflict": { "symfony/framework-bundle": "4.3.0" diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 43301fbb..eaef84fd 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -43,7 +43,7 @@ public function setException(GetResponseForExceptionEvent $event): void public function clearLastException(GetResponseEvent $event): void { - if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { + if (HttpKernelInterface::MAIN_REQUEST === $event->getRequestType()) { $this->lastException = null; } } diff --git a/src/QueryCounter.php b/src/QueryCounter.php index 3fdef26c..132357e4 100644 --- a/src/QueryCounter.php +++ b/src/QueryCounter.php @@ -19,13 +19,10 @@ final class QueryCounter { - /** @var int */ - private $defaultMaxCount; + private ?int $defaultMaxCount; + private ?Reader $annotationReader; - /** @var Reader */ - private $annotationReader; - - public function __construct(?int $defaultMaxCount, Reader $annotationReader) + public function __construct(?int $defaultMaxCount, ?Reader $annotationReader) { $this->defaultMaxCount = $defaultMaxCount; $this->annotationReader = $annotationReader; @@ -57,6 +54,10 @@ private function getMaxQueryCount(): ?int private function getMaxQueryAnnotation(): ?int { + if (null === $this->annotationReader) { + @trigger_error('The annotationReader is not available', \E_USER_ERROR); + } + foreach (debug_backtrace() as $step) { if ('test' === substr($step['function'], 0, 4)) { //TODO: handle tests with the @test annotation $annotations = $this->annotationReader->getMethodAnnotations( diff --git a/src/Resources/config/functional_test.xml b/src/Resources/config/functional_test.xml index 0007255c..2b990fb6 100644 --- a/src/Resources/config/functional_test.xml +++ b/src/Resources/config/functional_test.xml @@ -21,7 +21,7 @@ %liip_functional_test.query.max_query_count% - + diff --git a/tests/App/AppKernel.php b/tests/App/AppKernel.php index 64128a60..273538a6 100644 --- a/tests/App/AppKernel.php +++ b/tests/App/AppKernel.php @@ -37,13 +37,8 @@ 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'); - } + $loader->load(__DIR__.'/security_5.yml'); + $loader->load(__DIR__.'/session_5.yml'); } public function getCacheDir(): string diff --git a/tests/App/Command/TestCommand.php b/tests/App/Command/TestCommand.php index cf9b239b..22f130ab 100644 --- a/tests/App/Command/TestCommand.php +++ b/tests/App/Command/TestCommand.php @@ -37,7 +37,7 @@ protected function configure(): void ->setDescription('Test command'); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // Symfony version check $version = Kernel::VERSION_ID; diff --git a/tests/App/Command/TestInteractiveCommand.php b/tests/App/Command/TestInteractiveCommand.php index 42a5759a..8d2f4b03 100644 --- a/tests/App/Command/TestInteractiveCommand.php +++ b/tests/App/Command/TestInteractiveCommand.php @@ -30,7 +30,7 @@ protected function configure(): void ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $helper = $this->getHelper('question'); $question = new Question('Please enter the input', 'AcmeDemoBundle'); diff --git a/tests/App/Controller/DefaultController.php b/tests/App/Controller/DefaultController.php index ed4364c9..44791cd3 100644 --- a/tests/App/Controller/DefaultController.php +++ b/tests/App/Controller/DefaultController.php @@ -107,4 +107,9 @@ public function embeddedAction(): Response { return new Response('Embedded Content', Response::HTTP_OK); } + + public function exceptionAction(): Response + { + throw new \Exception('foo'); + } } diff --git a/tests/App/Entity/User.php b/tests/App/Entity/User.php index 9b67826f..7b81711b 100644 --- a/tests/App/Entity/User.php +++ b/tests/App/Entity/User.php @@ -13,75 +13,18 @@ namespace Liip\Acme\Tests\App\Entity; -use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; -/** - * User. - * - * @ORM\Entity() - * @ORM\Table("liip_user") - */ class User implements UserInterface { - // Properties which will be serialized have to be "protected" - // @see http://stackoverflow.com/questions/9384836/symfony2-serialize-entity-object-to-session/10014802#10014802 - - /** - * @var int - * @ORM\Id() - * @ORM\Column(type="integer") - */ - protected $id; - - /** - * @var string - * @ORM\Column(type="string", length=255) - */ - protected $name; - - /** - * @var string - * @ORM\Column(type="string", length=255) - */ - private $email; - - /** - * @var string - * @ORM\Column(type="string", length=255) - */ - protected $password; - - /** - * @var string - * @ORM\Column(type="string", length=255) - */ - protected $salt; - - /** - * @var string - * @ORM\Column(type="string", length=255) - */ - private $algorithm; - - /** - * @var bool - * @ORM\Column(type="boolean") - */ - private $enabled; - - /** - * @var string - * @ORM\Column(type="string", length=255, nullable=true) - */ - private $confirmationToken; + private ?int $id = null; + private string $name; + private string $email; + private string $salt; public function __construct() { - $this->salt = sha1( - // http://php.net/manual/fr/function.openssl-random-pseudo-bytes.php - bin2hex(openssl_random_pseudo_bytes(100)) - ); + $this->salt = sha1(bin2hex('Liip')); } public function __toString(): string @@ -89,207 +32,53 @@ public function __toString(): string return $this->getUserIdentifier(); } - /** - * Set id. - * - * @param int $id - * - * @return User - */ - public function setId($id) + public function setId(int $id): self { $this->id = $id; return $this; } - /** - * Get id. - * - * @return int - */ - public function getId() + public function getId(): ?int { return $this->id; } - /** - * Set name. - * - * @param string $name - * - * @return User - */ - public function setName($name) + public function setName(string $name): self { $this->name = $name; return $this; } - /** - * Get name. - * - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } - /** - * Set email. - * - * @param string $email - * - * @return User - */ - public function setEmail($email) + public function setEmail(string $email): self { $this->email = $email; return $this; } - /** - * Get email. - * - * @return string - */ - public function getEmail() + public function getEmail(): string { return $this->email; } - /** - * Set password. - * - * @param string $password - * - * @return User - */ - public function setPassword($password) - { - $this->password = $password; - - return $this; - } - - /** - * Get password. - * - * @return string - */ - public function getPassword() - { - return $this->password; - } - - /** - * Set salt. - * - * @param string $salt - * - * @return User - */ - public function setSalt($salt) - { - $this->salt = $salt; - - return $this; - } - - /** - * Get salt. - * - * @return string - */ - public function getSalt() + public function getSalt(): string { return $this->salt; } - /** - * Set algorithm. - * - * @param string $algorithm - * - * @return User - */ - public function setAlgorithm($algorithm) - { - $this->algorithm = $algorithm; - - return $this; - } - - /** - * Get algorithm. - * - * @return string - */ - public function getAlgorithm() - { - return $this->algorithm; - } - - /** - * Set enabled. - * - * @param bool $enabled - * - * @return User - */ - public function setEnabled($enabled) - { - $this->enabled = $enabled; - - return $this; - } - - /** - * Get enabled. - * - * @return bool - */ - public function getEnabled() - { - return $this->enabled; - } - - /** - * Set confirmationToken. - * - * @param string $confirmationToken - * - * @return User - */ - public function setConfirmationToken($confirmationToken) - { - $this->confirmationToken = $confirmationToken; - - return $this; - } - - /** - * Get confirmationToken. - * - * @return string - */ - public function getConfirmationToken() - { - return $this->confirmationToken; - } - - // Functions required for compatibility with UserInterface - // @see http://symfony.com/doc/2.3/cookbook/security/custom_provider.html - public function getRoles(): array { return ['ROLE_ADMIN']; } - public function getUsername() + public function getUsername(): string { return $this->getName(); } @@ -303,33 +92,8 @@ public function eraseCredentials(): void { } - public function isEqualTo(UserInterface $user) - { - if (!$user instanceof self) { - return false; - } - - if ($this->id !== $user->getId()) { - return false; - } - - if ($this->password !== $user->getPassword()) { - return false; - } - - if ($this->salt !== $user->getSalt()) { - return false; - } - - return true; - } - - // @see http://stackoverflow.com/questions/9384836/symfony2-serialize-entity-object-to-session/19133985#19133985 - - public function __sleep() + public function getPassword(): string { - // these are field names to be serialized, others will be excluded - // but note that you have to fill other field values by your own - return ['id', 'name', 'password', 'salt']; + return $this->getSalt(); } } diff --git a/tests/App/Resources/config/doctrine/User.orm.yml b/tests/App/Resources/config/doctrine/User.orm.yml new file mode 100644 index 00000000..85f9ea43 --- /dev/null +++ b/tests/App/Resources/config/doctrine/User.orm.yml @@ -0,0 +1,19 @@ +Liip\Acme\Tests\App\Entity\User: + type: entity + table: 'liip_user' + id: + id: + type: integer + id: true + generator: + strategy: AUTO + fields: + name: + type: string + length: '255' + email: + type: string + length: '255' + salt: + type: string + length: '255' diff --git a/tests/App/config.yml b/tests/App/config.yml index f05e7009..82ec684f 100644 --- a/tests/App/config.yml +++ b/tests/App/config.yml @@ -36,9 +36,10 @@ doctrine: connection: default mappings: LiipFunctionalTestBundle: - type: annotation - dir: "%kernel.project_dir%/Entity" + type: "yml" + dir: "%kernel.project_dir%/Resources/config/doctrine" prefix: 'Liip\Acme\Tests\App\Entity' + is_bundle: false security: providers: diff --git a/tests/App/routing.yml b/tests/App/routing.yml index bfb4952a..3610bc7b 100644 --- a/tests/App/routing.yml +++ b/tests/App/routing.yml @@ -25,3 +25,7 @@ liipfunctionaltestbundle_json: defaults: { _controller: 'Liip\Acme\Tests\App\Controller\DefaultController::jsonAction' } requirements: userId: \d+ + +liipfunctionaltestbundle_exception: + path: /exception + defaults: { _controller: 'Liip\Acme\Tests\App\Controller\DefaultController::exceptionAction' } diff --git a/tests/App/security_4.yml b/tests/App/security_4.yml deleted file mode 100644 index 142c7ed3..00000000 --- a/tests/App/security_4.yml +++ /dev/null @@ -1,6 +0,0 @@ -security: - encoders: - # in_memory users - Symfony\Component\Security\Core\User\User: plaintext - # User entity - Liip\Acme\Tests\App\Entity\User: plaintext diff --git a/tests/App/session_4.yml b/tests/App/session_4.yml deleted file mode 100644 index 19258079..00000000 --- a/tests/App/session_4.yml +++ /dev/null @@ -1,6 +0,0 @@ -imports: - - session.yml - -framework: - session: - storage_id: session.storage.mock_file diff --git a/tests/Test/WebTestCaseConfigTest.php b/tests/Test/WebTestCaseConfigTest.php index ed3d8d44..408cdcb0 100644 --- a/tests/Test/WebTestCaseConfigTest.php +++ b/tests/Test/WebTestCaseConfigTest.php @@ -19,6 +19,7 @@ use Liip\Acme\Tests\Traits\LiipAcmeFixturesTrait; use Liip\FunctionalTestBundle\Annotations\QueryCount; use Liip\FunctionalTestBundle\Test\WebTestCase; +use Symfony\Component\HttpKernel\Kernel; /** * Tests that configuration has been loaded and users can be logged in. @@ -52,6 +53,8 @@ protected static function getKernelClass(): string */ public function testIndexClientWithCredentials(): void { + $this->skipTestIfSymfonyHasVersion7(); + $this->client = static::makeClientWithCredentials('foobar', '12341234'); $path = '/admin'; @@ -83,6 +86,8 @@ public function testIndexClientWithCredentials(): void */ public function testIndexAuthenticatedClient(): void { + $this->skipTestIfSymfonyHasVersion7(); + $this->client = static::makeAuthenticatedClient(); $path = '/admin'; @@ -114,6 +119,8 @@ public function testIndexAuthenticatedClient(): void */ public function testIndexAuthenticationLoginAs(): void { + $this->skipTestIfSymfonyHasVersion7(); + $user = $this->loadTestFixtures(); $loginAs = $this->loginAs($user, 'secured_area'); @@ -152,6 +159,8 @@ public function testIndexAuthenticationLoginAs(): void */ public function testIndexAuthenticationLoginClient(): void { + $this->skipTestIfSymfonyHasVersion7(); + $user = $this->loadTestFixtures(); $this->client = static::makeClient(); @@ -192,6 +201,8 @@ public function testIndexAuthenticationLoginClient(): void */ public function testAllowedQueriesExceededException(): void { + $this->skipTestIfSymfonyHasVersion7(); + $user = $this->loadTestFixtures(); $this->assertInstanceOf( @@ -239,7 +250,9 @@ public function testAllowedQueriesExceededException(): void */ public function testAnnotationAndException(): void { - $user = $this->loadTestFixtures(); + $this->skipTestIfSymfonyHasVersion7(); + + $this->loadTestFixtures(); $this->client = static::makeClient(); @@ -251,4 +264,11 @@ public function testAnnotationAndException(): void $this->client->request('GET', $path); $this->assertStatusCode(200, $this->client); } + + private function skipTestIfSymfonyHasVersion7(): void + { + if (Kernel::MAJOR_VERSION >= 7) { + $this->markTestSkipped('The QueryCount is not compatible with Symfony 7+'); + } + } } diff --git a/tests/Test/WebTestCaseTest.php b/tests/Test/WebTestCaseTest.php index c9361901..c73d3799 100644 --- a/tests/Test/WebTestCaseTest.php +++ b/tests/Test/WebTestCaseTest.php @@ -16,7 +16,6 @@ use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation; use Liip\Acme\Tests\App\AppKernel; use Liip\FunctionalTestBundle\Test\WebTestCase; -use function method_exists; use PHPUnit\Framework\AssertionFailedError; /** @@ -243,25 +242,16 @@ public function test404Error(): void */ public function testIsSuccessfulException(): void { - $mockBuilder = $this->getMockBuilder('Symfony\Component\HttpFoundation\Response') - ->disableOriginalConstructor(); - if (method_exists($mockBuilder, 'setMethods')) { - $mockBuilder->setMethods(['getContent']); - } else { // phpunit 10 - $mockBuilder->onlyMethods(['getContent']); - } - $response = $mockBuilder - ->getMock(); + $path = '/exception'; - $response->expects($this->any()) - ->method('getContent') - ->will($this->throwException(new \Exception('foo'))); + $client = static::makeClient(); + $client->request('GET', $path); try { - $this->isSuccessful($response); + $this->isSuccessful($client->getResponse()); } catch (AssertionFailedError $e) { $string = <<<'EOF' -The Response was not successful: foo +The Response was not successful: foo (500 Internal Server Error) Failed asserting that false is true. EOF; $this->assertSame($string, $e->getMessage()); diff --git a/tests/Traits/LiipAcmeFixturesTrait.php b/tests/Traits/LiipAcmeFixturesTrait.php index 69c34fa7..9eb562db 100644 --- a/tests/Traits/LiipAcmeFixturesTrait.php +++ b/tests/Traits/LiipAcmeFixturesTrait.php @@ -27,10 +27,6 @@ public function loadTestFixtures(): User $user1->setId(1); $user1->setName('foo bar'); $user1->setEmail('foo@example'); - $user1->setPassword('12341234'); - $user1->setAlgorithm('plaintext'); - $user1->setEnabled(true); - $user1->setConfirmationToken(null); $manager = $this->getContainer()->get('doctrine')->getManager(); $manager->persist($user1);