diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 86ccccb3..ea64d141 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,13 +17,10 @@ jobs: symfony-version: ['^6.4'] phpunit-version: ['^9.6'] include: - - php-version: 8.0 - symfony-version: "^5.4" + - php-version: 8.1 + symfony-version: "^6.4" phpunit-version: '^9.6' composer-flags: "--prefer-lowest" - - php-version: 8.1 - symfony-version: "^5.4" - phpunit-version: "^10.0" - php-version: 8.1 symfony-version: "^6.4" phpunit-version: "^10.0" @@ -98,11 +95,6 @@ jobs: symfony/yaml=${{ matrix.symfony-version }} phpunit/phpunit=${{ matrix.phpunit-version }} - # This is needed to fix builds where the `annotation_reader` service may not be set up if - # the doctrine/annotations package is not in the production dependencies - - name: Move doctrine/annotations v1/v2 to require (non-dev) for PHP 8+ - run: composer require --no-update "doctrine/annotations:^1.8.0|^2.0" - - name: Install Composer dependencies if: matrix.composer-flags == '' run: composer install diff --git a/README.md b/README.md index 9aa9da05..97493a3e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ Documentation * [Basic usage](doc/basic.md) * [Command test](doc/command.md) * [Logged client](doc/logged.md) -* [Query counter](doc/query.md) * [Examples](doc/examples.md) * [Caveats](doc/caveats.md) * [Contributing](doc/contributing.md) diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md new file mode 100644 index 00000000..1884d06d --- /dev/null +++ b/UPGRADE-5.0.md @@ -0,0 +1,6 @@ +# Upgrade guide from 3.x to 4.x + +## Needed actions +This is the list of actions that you need to take when upgrading this bundle from the 3.x to the 4.x version: + + * … diff --git a/composer.json b/composer.json index 75c92d0d..49ca50c8 100644 --- a/composer.json +++ b/composer.json @@ -17,31 +17,30 @@ "require": { "php": "^8.0", "phpunit/phpunit": "^9.6 || ^10.0 || ^11.0 || ^12.0", - "symfony/browser-kit": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.0 || ^8.0" + "symfony/browser-kit": "^6.4 || ^7.0 || ^8.0", + "symfony/framework-bundle": "^6.4 || ^7.0 || ^8.0" }, "require-dev": { "ext-json": "*", - "doctrine/annotations": "^1.3 || ^2.0", + "ext-sqlite3": "*", "doctrine/doctrine-bundle": "^2.11 || ^3.1.0", "doctrine/orm": "^2.7 || ^3.0", "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", - "symfony/css-selector": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/doctrine-bridge": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/form": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/http-kernel": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/css-selector": "^6.4 || ^7.0 || ^8.0", + "symfony/doctrine-bridge": "^6.4 || ^7.0 || ^8.0", + "symfony/form": "^6.4 || ^7.0 || ^8.0", + "symfony/http-kernel": "^6.4 || ^7.0 || ^8.0", "symfony/monolog-bundle": "^3.4 || ^4.0", - "symfony/security-bundle": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/validator": "^5.4 || ^6.4 || ^7.0 || ^8.0", - "symfony/yaml": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/security-bundle": "^6.4 || ^7.0 || ^8.0", + "symfony/twig-bundle": "^6.4 || ^7.0 || ^8.0", + "symfony/validator": "^6.4 || ^7.0 || ^8.0", + "symfony/yaml": "^6.4 || ^7.0 || ^8.0", "twig/twig": "^2.0 || ^3.8" }, "conflict": { "symfony/framework-bundle": "4.3.0" }, "suggest": { - "doctrine/annotations": "Required to use the @QueryCount(…) annotation", "liip/test-fixtures-bundle": "Efficient loading of Doctrine fixtures in functional test-cases for Symfony applications" }, "autoload": { @@ -59,7 +58,7 @@ }, "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "scripts": { diff --git a/doc/basic.md b/doc/basic.md index 05fda28c..65d2d56f 100644 --- a/doc/basic.md +++ b/doc/basic.md @@ -4,15 +4,11 @@ Basic usage > [!TIP] > Some methods provided by this bundle have been [implemented in Symfony](https://symfony.com/doc/current/testing.html#application-tests). Alternative ways will be shown below. -Use `$this->makeClient` to create a Client object. Client is a Symfony class +Use `$this->createClientWithParams()` to create a Client object. Client is a Symfony class that can simulate HTTP requests to your controllers and then inspect the results. It is covered by the [functional tests](http://symfony.com/doc/current/book/testing.html#functional-tests) section of the Symfony documentation. -After making a request, use `assertStatusCode` to verify the HTTP status code. -If it fails it will display the last exception message or validation errors -encountered by the Client object. - If you are expecting validation errors, test them with `assertValidationErrors`. ```php @@ -22,120 +18,28 @@ class MyControllerTest extends WebTestCase { public function testContact() { - $client = $this->makeClient(); + $client = $this->createClient(); $crawler = $client->request('GET', '/contact'); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $form = $crawler->selectButton('Submit')->form(); $crawler = $client->submit($form); // We should get a validation error for the empty fields. - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $this->assertValidationErrors(['data.email', 'data.message'], $client->getContainer()); // Try again with with the fields filled out. $form = $crawler->selectButton('Submit')->form(); $form->setValues(['contact[email]' => 'nobody@example.com', 'contact[message]' => 'Hello']); $client->submit($form); - $this->assertStatusCode(302, $client); - } -} -``` - -> [!TIP] -> Instead of calling `$this->makeClient`, consider calling `createClient()` from Symfony's `WebTestCase`: - -```php -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; - -class MyControllerTest extends WebTestCase -{ - public function testContact() - { - $client = static::createClient(); - $client->request('GET', '/contact'); - - // … + self::assertResponseStatusCodeSame(302); } } ``` ### Methods -#### Check HTTP status codes - -##### isSuccessful() - -Check that the request succeeded: - -```php -$client = $this->makeClient(); -$client->request('GET', '/contact'); - -// Successful HTTP request -$this->isSuccessful($client->getResponse()); -``` - -> [!TIP] -> Call `assertResponseIsSuccessful()` from Symfony's `WebTestCase` ([documentation](https://symfony.com/doc/current/testing.html#response-assertions)): - -```php -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; - -class MyControllerTest extends WebTestCase -{ - public function testContact() - { - $client = static::createClient(); - $client->request('GET', '/contact'); - - self::assertResponseIsSuccessful(); - } -} -``` - -Add `false` as the second argument in order to check that the request failed: - -```php -$client = $this->makeClient(); -$client->request('GET', '/error'); - -// Request returned an error -$this->isSuccessful($client->getResponse(), false); -``` - -In order to test more specific status codes, use `assertStatusCode()`: - -##### assertStatusCode() - -Check the HTTP status code from the request: - -```php -$client = $this->makeClient(); -$client->request('GET', '/contact'); - -// Standard response for successful HTTP request -$this->assertStatusCode(302, $client); -``` - -> [!TIP] -> Call `assertResponseStatusCodeSame()` from Symfony's `WebTestCase` ([documentation](https://symfony.com/doc/current/testing.html#response-assertions)): - -```php -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; - -class MyControllerTest extends WebTestCase -{ - public function testContact() - { - $client = static::createClient(); - $client->request('GET', '/contact'); - - self::assertResponseStatusCodeSame(302); - } -} -``` - #### Get Crawler or content ##### fetchCrawler() @@ -181,44 +85,6 @@ class MyControllerTest extends WebTestCase } ``` -##### fetchContent() - -Get the content of a URL: - -```php -$content = $this->fetchContent('/contact'); - -// `filter()` can't be used since the output is HTML code, check the content directly -$this->assertStringContainsString( - '

LiipFunctionalTestBundle

', - $content -); -``` - -> [!TIP] -> Call `getResponse()->getContent()` or use `assertSelectorText*()` from Symfony's `WebTestCase` ([documentation](https://symfony.com/doc/current/testing.html#crawler-assertions)): - -```php -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; - -class MyControllerTest extends WebTestCase -{ - public function testContact() - { - $client = static::createClient(); - $client->request('GET', '/contact'); - - $this->assertStringContainsString( - '

LiipFunctionalTestBundle

', - $client->getResponse()->getContent() - ); - - //or - self::assertSelectorTextContains('h1', 'LiipFunctionalTestBundle'); - } -} -``` - #### Routing ##### getURL() diff --git a/doc/examples.md b/doc/examples.md index 273bcfd3..41a2c809 100644 --- a/doc/examples.md +++ b/doc/examples.md @@ -93,7 +93,7 @@ class ExampleFunctionalTest extends WebTestCase public function testValidationErrors(): void { - $client = $this->makeClient(true); + $client = $this->createClientWithParams(); $crawler = $client->request('GET', '/users/1/edit'); $client->submit($crawler->selectButton('Save')->form()); @@ -103,4 +103,4 @@ class ExampleFunctionalTest extends WebTestCase } ``` -← [Query counter](./query.md) • [Caveats](./caveats.md) → +← [Examples](./examples.md) • [Caveats](./caveats.md) → diff --git a/doc/installation.md b/doc/installation.md index 99ab71fd..b85f6545 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -1,7 +1,9 @@ Upgrade from previous version ======================== -See [Upgrade guide from 1.x to 2.0](../UPGRADE-2.0.md) and [Upgrade guide from 2.x to 3.x](../UPGRADE-3.0.md). +See [Upgrade guide from 1.x to 2.0](../UPGRADE-2.0.md), +[Upgrade guide from 2.x to 3.x](../UPGRADE-3.0.md) and +[Upgrade guide from 4.x to 5.x](../UPGRADE-5.0.md). Installation ============ @@ -12,7 +14,7 @@ Installation following command to download the latest stable version of this bundle: ```bash - $ composer require --dev liip/functional-test-bundle:^4.0.0 + $ composer require --dev liip/functional-test-bundle:^5.0.0 ``` This command requires you to have Composer installed globally, as explained diff --git a/doc/logged.md b/doc/logged.md index cf87bcc3..c337abb6 100644 --- a/doc/logged.md +++ b/doc/logged.md @@ -1,20 +1,10 @@ Create an already logged client =============================== -> [!TIP] -> Some methods provided by this bundle have been implemented in Symfony. Alternative ways will be shown below. - -The `WebTestCase` provides a convenience method to create an already logged in client using the first parameter of -`WebTestCase::makeClient()`. - -You have three alternatives to create an already logged in client: +You have two alternatives to create an already logged in client: 1. Use the `liip_functional_test.authentication` key in the `config_test.yml` file; 2. Pass an array with login parameters directly when you call the method; -3. Use the method `WebTestCase::loginClient()`; - -> [!TIP] -> Since Symfony 5.1, [`loginUser()`](https://symfony.com/doc/5.x/testing.html#logging-in-users-authentication) can be used. ### Logging in a user from the `config_test.yml` file @@ -95,4 +85,4 @@ security: For more details, you can check the implementation of `WebTestCase` in that bundle. -← [Command test](./command.md) • [Query counter](./query.md) → +← [Command test](./command.md) • [Examples](./examples.md) → diff --git a/doc/query.md b/doc/query.md deleted file mode 100644 index 1f85be21..00000000 --- a/doc/query.md +++ /dev/null @@ -1,92 +0,0 @@ -Query Counter -============= - -> [!IMPORTANT] -> The Query Counter is not compatible with Symfony 7+. - -To catch pages that use way too many database queries, you can enable the query -counter for tests. This will check the profiler for each request made in the -test using the client, and fail the test if the number of queries executed is -larger than the number of queries allowed in the configuration. To enable the -query counter, adjust the `config_test.yml` file like this: - -```yaml -framework: - # ... - profiler: - enabled: true - collect: true - -doctrine: - # ... - dbal: - connections: - default: - # ... - profiling: true - -liip_functional_test: - query: - max_query_count: 50 -``` - -That will limit each request executed within a functional test to 50 queries. - -Maximum Query Count per Test ----------------------------- - -The default value set in the config file should be reasonable to catch pages -with high query counts which are obviously mistakes. There will be cases where -you know and accept that the request will cause a large number of queries, or -where you want to specifically require the page to execute less than x queries, -regardless of the amount set in the configuration. For those cases you can set -an annotation on the test method that will override the default maximum for any -requests made in that test. - -To do that, include the Liip\FunctionalTestBundle\Annotations\QueryCount -namespace and add the `@QueryCount(100)` annotation, where 100 is the maximum -amount of queries allowed for each request, like this: - -```php -use Liip\FunctionalTestBundle\Annotations\QueryCount; - -class DemoTest extends WebTestCase -{ - /** - * @QueryCount(100) - */ - public function testDoDemoStuff() - { - $client = $this->createClient(); - $crawler = $client->request('GET', '/demoPage'); - - $this->assertTrue($crawler->filter('html:contains("Demo")')->count() > 0); - } -} -``` - -Caveats -------- - - * QueryCount annotations currently only work for tests that have a method name - of `testFooBla()` (with a test prefix). The `@test` annotation isn't - supported at the moment. - * Enabling the Query Counter currently breaks PHPUnit's built-in annotations, - e.g. `@dataProvider`, `@depends` etc. To fix this, you need to hide the - appropriate PHPUnit annotation from Doctrine's annotation reader using the - `@IgnoreAnnotation` annotation: - - ```php - use Liip\FunctionalTestBundle\Test\WebTestCase; - - /** - * @IgnoreAnnotation("dataProvider") - * @IgnoreAnnotation("depends") - */ - class DemoTest extends WebTestCase - { - // ... - } - ``` - -← [Logged client](./logged.md) • [Examples](./examples.md) → diff --git a/src/Annotations/QueryCount.php b/src/Annotations/QueryCount.php deleted file mode 100644 index 57a75a54..00000000 --- a/src/Annotations/QueryCount.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\FunctionalTestBundle\Annotations; - -/** - * @Annotation - * @Target({"METHOD"}) - */ -final class QueryCount -{ - /** @var int */ - public $maxQueries; - - public function __construct(array $values) - { - if (isset($values['value'])) { - $this->maxQueries = $values['value']; - } - } -} diff --git a/src/DependencyInjection/Compiler/SetTestClientPass.php b/src/DependencyInjection/Compiler/SetTestClientPass.php deleted file mode 100644 index 50d5ece7..00000000 --- a/src/DependencyInjection/Compiler/SetTestClientPass.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\FunctionalTestBundle\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Alias; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -class SetTestClientPass implements CompilerPassInterface -{ - public function process(ContainerBuilder $container): void - { - if (null === $container->getParameter('liip_functional_test.query.max_query_count')) { - $container->removeDefinition('liip_functional_test.query.count_client'); - - return; - } - - if ($container->hasDefinition('test.client')) { - // test.client is a definition. - // Register it again as a private service to inject it as the parent - $definition = $container->getDefinition('test.client'); - $definition->setPublic(false); - $container->setDefinition('liip_functional_test.query.count_client.parent', $definition); - } else { - throw new \Exception('The LiipFunctionalTestBundle\'s Query Counter can only be used in the test environment.'.\PHP_EOL.'See https://github.com/liip/LiipFunctionalTestBundle#only-in-test-environment'); - } - - $container->setAlias('test.client', new Alias('liip_functional_test.query.count_client', true)); - } -} diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 06a94475..fd5606db 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -36,14 +36,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->children() ->scalarNode('command_verbosity')->defaultValue('normal')->end() ->booleanNode('command_decoration')->defaultTrue()->end() - ->arrayNode('query') - ->addDefaultsIfNotSet() - ->children() - ->scalarNode('max_query_count') - ->defaultNull() - ->end() - ->end() - ->end() ->arrayNode('authentication') ->addDefaultsIfNotSet() ->children() diff --git a/src/DependencyInjection/LiipFunctionalTestExtension.php b/src/DependencyInjection/LiipFunctionalTestExtension.php index d0f9af95..dbc933a3 100644 --- a/src/DependencyInjection/LiipFunctionalTestExtension.php +++ b/src/DependencyInjection/LiipFunctionalTestExtension.php @@ -35,6 +35,7 @@ public function load(array $configs, ContainerBuilder $container): void } foreach ($config as $key => $value) { + // TODO: cleanup // If the node is an array, // e.g. "liip_functional_test.query.max_query_count", // set the value as @@ -50,8 +51,5 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter($this->getAlias().'.'.$key, $value); } } - - $definition = $container->getDefinition('liip_functional_test.query.count_client'); - $definition->setShared(false); } } diff --git a/src/LiipFunctionalTestBundle.php b/src/LiipFunctionalTestBundle.php index 36a92984..18d5e1ff 100644 --- a/src/LiipFunctionalTestBundle.php +++ b/src/LiipFunctionalTestBundle.php @@ -14,7 +14,6 @@ namespace Liip\FunctionalTestBundle; use Liip\FunctionalTestBundle\DependencyInjection\Compiler\OptionalValidatorPass; -use Liip\FunctionalTestBundle\DependencyInjection\Compiler\SetTestClientPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -22,7 +21,6 @@ class LiipFunctionalTestBundle extends Bundle { public function build(ContainerBuilder $container): void { - $container->addCompilerPass(new SetTestClientPass()); $container->addCompilerPass(new OptionalValidatorPass()); } } diff --git a/src/QueryCountClient.php b/src/QueryCountClient.php deleted file mode 100644 index 06bec015..00000000 --- a/src/QueryCountClient.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\FunctionalTestBundle; - -use Symfony\Bundle\FrameworkBundle\Client; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass; -use Symfony\Bundle\FrameworkBundle\KernelBrowser; - -// Symfony <4 BC -if (class_exists(CompilerDebugDumpPass::class)) { - class_alias(QueryCountClientSymfony3Trait::class, QueryCountClientTrait::class); -} - -// Symfony <4.3.1 BC -if (!class_exists(KernelBrowser::class)) { - class_alias(Client::class, KernelBrowser::class); -} - -if (!class_exists(Client::class)) { - class_alias(KernelBrowser::class, Client::class); -} - -class QueryCountClient extends KernelBrowser -{ - /* - * We use trait only because of Client::request signature strict type mismatch between Symfony 3 and 4. - */ - use QueryCountClientTrait; - - /** @var QueryCounter */ - private $queryCounter; - - public function setQueryCounter(QueryCounter $queryCounter): void - { - $this->queryCounter = $queryCounter; - } - - private function checkQueryCount(): void - { - if ($this->getProfile()) { - $this->queryCounter->checkQueryCount( - $this->getProfile()->getCollector('db')->getQueryCount() - ); - } else { - // @codeCoverageIgnoreStart - echo "\n". - 'Profiler is disabled, it must be enabled for the '. - 'Query Counter. '. - 'See https://github.com/liip/LiipFunctionalTestBundle#query-counter'. - "\n"; - // @codeCoverageIgnoreEnd - } - } -} diff --git a/src/QueryCountClientSymfony3Trait.php b/src/QueryCountClientSymfony3Trait.php deleted file mode 100644 index 25f9818f..00000000 --- a/src/QueryCountClientSymfony3Trait.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\FunctionalTestBundle; - -/** - * @author Sullivan Senechal - * - * @internal - */ -trait QueryCountClientSymfony3Trait -{ - public function request( - $method, - $uri, - array $parameters = [], - array $files = [], - array $server = [], - $content = null, - $changeHistory = true - ) { - $crawler = parent::request($method, $uri, $parameters, $files, $server, $content, $changeHistory); - $this->checkQueryCount(); - - return $crawler; - } -} diff --git a/src/QueryCountClientTrait.php b/src/QueryCountClientTrait.php deleted file mode 100644 index 611aa537..00000000 --- a/src/QueryCountClientTrait.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\FunctionalTestBundle; - -use Symfony\Component\DomCrawler\Crawler; - -/** - * @author Sullivan Senechal - * - * @internal - */ -trait QueryCountClientTrait -{ - public function request( - string $method, - string $uri, - array $parameters = [], - array $files = [], - array $server = [], - ?string $content = null, - bool $changeHistory = true - ): Crawler { - $crawler = parent::request($method, $uri, $parameters, $files, $server, $content, $changeHistory); - $this->checkQueryCount(); - - return $crawler; - } -} diff --git a/src/QueryCounter.php b/src/QueryCounter.php deleted file mode 100644 index b9b2347f..00000000 --- a/src/QueryCounter.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\FunctionalTestBundle; - -use Doctrine\Common\Annotations\Reader; -use Liip\FunctionalTestBundle\Annotations\QueryCount; -use Liip\FunctionalTestBundle\Exception\AllowedQueriesExceededException; - -final class QueryCounter -{ - private ?int $defaultMaxCount; - private ?Reader $annotationReader; - - public function __construct(?int $defaultMaxCount, ?Reader $annotationReader) - { - $this->defaultMaxCount = $defaultMaxCount; - $this->annotationReader = $annotationReader; - } - - public function checkQueryCount(int $actualQueryCount): void - { - $maxQueryCount = $this->getMaxQueryCount(); - - if (null === $maxQueryCount) { - return; - } - - if ($actualQueryCount > $maxQueryCount) { - throw new AllowedQueriesExceededException("Allowed amount of queries ($maxQueryCount) exceeded (actual: $actualQueryCount)."); - } - } - - private function getMaxQueryCount(): ?int - { - $maxQueryCount = $this->getMaxQueryAnnotation(); - - return $maxQueryCount ?? $this->defaultMaxCount; - } - - private function getMaxQueryAnnotation(): ?int - { - if (null === $this->annotationReader) { - @trigger_error('The annotationReader is not available', \E_USER_ERROR); - } - - foreach (debug_backtrace() as $step) { - if (str_starts_with($step['function'], 'test')) { // TODO: handle tests with the @test annotation - $annotations = $this->annotationReader->getMethodAnnotations( - new \ReflectionMethod($step['class'], $step['function']) - ); - - foreach ($annotations as $annotationClass) { - if ($annotationClass instanceof QueryCount && isset($annotationClass->maxQueries)) { - /* @var $annotations \Liip\FunctionalTestBundle\Annotations\QueryCount */ - - return $annotationClass->maxQueries; - } - } - } - } - - return null; - } -} diff --git a/src/Resources/config/functional_test.php b/src/Resources/config/functional_test.php index 2ba1b9a7..05b24cd8 100644 --- a/src/Resources/config/functional_test.php +++ b/src/Resources/config/functional_test.php @@ -17,19 +17,4 @@ $services->set('liip_functional_test.exception_listener', \Liip\FunctionalTestBundle\EventListener\ExceptionListener::class) ->public() ->tag('kernel.event_subscriber'); - - $services->set('liip_functional_test.query.count_client', \Liip\FunctionalTestBundle\QueryCountClient::class) - ->args([ - service('kernel'), - '%test.client.parameters%', - service('test.client.history'), - service('test.client.cookiejar'), - ]) - ->call('setQueryCounter', [service('liip_functional_test.query.counter')]); - - $services->set('liip_functional_test.query.counter', \Liip\FunctionalTestBundle\QueryCounter::class) - ->args([ - '%liip_functional_test.query.max_query_count%', - service('annotation_reader')->nullOnInvalid(), - ]); }; diff --git a/src/Test/WebTestCase.php b/src/Test/WebTestCase.php index 16025579..c0219aac 100644 --- a/src/Test/WebTestCase.php +++ b/src/Test/WebTestCase.php @@ -23,11 +23,9 @@ use Symfony\Component\Console\Tester\CommandTester; 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; @@ -55,9 +53,6 @@ abstract class WebTestCase extends BaseWebTestCase protected $containers; - // 5 * 1024 * 1024 KB - protected $maxMemory = 5242880; - // RUN COMMAND protected $verbosityLevel; @@ -258,82 +253,12 @@ protected static function createKernel(array $options = []): KernelInterface return parent::createKernel($options); } - /** - * Keep support of Symfony < 5.3. - */ - public function __call(string $name, $arguments) - { - if ('getContainer' === $name) { - return $this->getDependencyInjectionContainer(); - } - - throw new \Exception("Method {$name} is not supported."); - } - - /** - * @deprecated - */ - public function __set($name, $value): void - { - if ('environment' !== $name) { - throw new \Exception(\sprintf('There is no property with name "%s"', $name)); - } - - @trigger_error('Setting "environment" property is deprecated, please use static::$env.', \E_USER_DEPRECATED); - - static::$env = $value; - } - - /** - * @deprecated - */ - public function __isset($name) - { - if ('environment' !== $name) { - throw new \Exception(\sprintf('There is no property with name "%s"', $name)); - } - - @trigger_error('Checking "environment" property is deprecated, please use static::$env.', \E_USER_DEPRECATED); - - return true; - } - - /** - * @deprecated - */ - public function __get($name) - { - if ('environment' !== $name) { - throw new \Exception(\sprintf('There is no property with name "%s"', $name)); - } - - @trigger_error('Getting "environment" property is deprecated, please use static::$env.', \E_USER_DEPRECATED); - - return static::$env; - } - - /** - * Creates an instance of a lightweight Http 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 makeClient(array $params = []): Client - { - return $this->createClientWithParams($params); - } - /** * Creates an instance of a lightweight Http 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 { @@ -345,21 +270,6 @@ protected function makeAuthenticatedClient(array $params = []): Client return $this->createClientWithParams($params, $username, $password); } - /** - * Creates an instance of a lightweight Http client and log in user with - * username and password params. - * - * $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 - { - return $this->createClientWithParams($params, $username, $password); - } - /** * Create User Token. * @@ -405,125 +315,6 @@ protected function getUrl(string $route, array $params = [], int $absolute = Url return $this->getContainer()->get('router')->generate($route, $params, $absolute); } - /** - * Checks the success state of a response. - * - * @param Response $response Response object - * @param bool $success to define whether the response is expected to be successful - * @param string $type - */ - public function isSuccessful(Response $response, $success = true, $type = 'text/html'): void - { - HttpAssertions::isSuccessful($response, $success, $type); - } - - /** - * Executes a request on the given url and returns the response contents. - * - * This method also asserts the request was successful. - * - * @param string $path path of the requested page - * @param string $method The HTTP method to use, defaults to GET - * @param bool $authentication Whether to use authentication, defaults to false - * @param bool $success to define whether the response is expected to be successful - */ - public function fetchContent(string $path, string $method = 'GET', bool $authentication = false, bool $success = true): string - { - $client = ($authentication) ? $this->makeAuthenticatedClient() : $this->makeClient(); - - $client->request($method, $path); - - $content = $client->getResponse()->getContent(); - $this->isSuccessful($client->getResponse(), $success); - - return $content; - } - - /** - * Executes a request on the given url and returns a Crawler object. - * - * This method also asserts the request was successful. - * - * @param string $path path of the requested page - * @param string $method The HTTP method to use, defaults to GET - * @param bool $authentication Whether to use authentication, defaults to false - * @param bool $success Whether the response is expected to be successful - */ - public function fetchCrawler(string $path, string $method = 'GET', bool $authentication = false, bool $success = true): Crawler - { - $client = ($authentication) ? $this->makeAuthenticatedClient() : $this->makeClient(); - - $crawler = $client->request($method, $path); - - $this->isSuccessful($client->getResponse(), $success); - - return $crawler; - } - - /** - * @deprecated - */ - public function loginAs(UserInterface $user, string $firewallName): self - { - @trigger_error(\sprintf('"%s()" is deprecated, use loginClient() after creating a client.', __METHOD__), \E_USER_DEPRECATED); - - $this->firewallLogins[$firewallName] = $user; - - return $this; - } - - /** - * @deprecated - */ - public function loginClient(KernelBrowser $client, UserInterface $user, string $firewallName): void - { - // Available since Symfony 5.1 - if (method_exists($client, 'loginUser')) { - @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 = $this->getSession($client); - - $client->getCookieJar()->set(new Cookie($options['name'], $session->getId())); - - $token = $this->createUserToken($user, $firewallName); - - $tokenStorage = $client->getContainer()->get('security.token_storage'); - - $tokenStorage->setToken($token); - $session->set('_security_'.$firewallName, serialize($token)); - - $session->save(); - } - - /** - * Asserts that the HTTP response code of the last request performed by - * $client matches the expected code. If not, raises an error with more - * information. - */ - public static function assertStatusCode(int $expectedStatusCode, Client $client): void - { - HttpAssertions::assertStatusCode($expectedStatusCode, $client); - } - /** * Assert that the last validation errors within $container match the * expected keys. @@ -550,10 +341,7 @@ protected function tearDown(): void parent::tearDown(); } - /** - * @deprecated - */ - protected function createClientWithParams(array $params, ?string $username = null, ?string $password = null): Client + protected function createClientWithParams(array $params = [], ?string $username = null, ?string $password = null): Client { if ($username && $password) { $params = array_merge($params, [ diff --git a/src/Utils/HttpAssertions.php b/src/Utils/HttpAssertions.php index ab71019a..6ccda492 100644 --- a/src/Utils/HttpAssertions.php +++ b/src/Utils/HttpAssertions.php @@ -15,76 +15,10 @@ use Liip\FunctionalTestBundle\Test\ValidationErrorsConstraint; use PHPUnit\Framework\TestCase; -use Symfony\Bundle\FrameworkBundle\Client; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DomCrawler\Crawler; -use Symfony\Component\HttpFoundation\Response; class HttpAssertions extends TestCase { - /** - * Checks the success state of a response. - * - * @param Response $response Response object - * @param bool $success to define whether the response is expected to be successful - */ - public static function isSuccessful(Response $response, bool $success = true, string $type = 'text/html'): void - { - try { - $crawler = new Crawler(); - $crawler->addContent($response->getContent(), $type); - if (!\count($crawler->filter('title'))) { - $title = '['.$response->getStatusCode().'] - '.$response->getContent(); - } else { - $title = $crawler->filter('title')->text(); - } - } catch (\Exception $e) { - $title = $e->getMessage(); - } - - if ($success) { - self::assertTrue($response->isSuccessful(), 'The Response was not successful: '.$title); - } else { - self::assertFalse($response->isSuccessful(), 'The Response was successful: '.$title); - } - } - - /** - * Asserts that the HTTP response code of the last request performed by - * $client matches the expected code. If not, raises an error with more - * information. - */ - public static function assertStatusCode(int $expectedStatusCode, Client $client): void - { - $container = $client->getContainer(); - - if ($container->has('test.service_container')) { - $container = $container->get('test.service_container'); - } - - $helpfulErrorMessage = ''; - - if ($expectedStatusCode !== $client->getResponse()->getStatusCode()) { - // Get a more useful error message, if available - if ($exception = $container->get('liip_functional_test.exception_listener')->getLastException()) { - $helpfulErrorMessage = $exception->getMessage()."\n\n".$exception->getTraceAsString(); - } elseif ( - $container->has('liip_functional_test.validator') - && \count($validationErrors = $container->get('liip_functional_test.validator')->getLastErrors()) - ) { - $helpfulErrorMessage = "Unexpected validation errors:\n"; - - foreach ($validationErrors as $error) { - $helpfulErrorMessage .= \sprintf("+ %s: %s\n", $error->getPropertyPath(), $error->getMessage()); - } - } else { - $helpfulErrorMessage = substr((string) $client->getResponse(), 0, 200); - } - } - - self::assertSame($expectedStatusCode, $client->getResponse()->getStatusCode(), $helpfulErrorMessage); - } - /** * Assert that the last validation errors within $container match the * expected keys. diff --git a/tests/App/bootstrap.php b/tests/App/bootstrap.php index 1171c98f..972652d7 100644 --- a/tests/App/bootstrap.php +++ b/tests/App/bootstrap.php @@ -11,14 +11,6 @@ * with this source code in the file LICENSE. */ -use Doctrine\Common\Annotations\AnnotationRegistry; - $loader = require __DIR__.'/../../vendor/autoload.php'; -// This method only exist on doctrine/annotations:^1.3, -// it is missing but not needed with doctrine/annotations:^2.0 -if (method_exists(AnnotationRegistry::class, 'registerLoader')) { - AnnotationRegistry::registerLoader([$loader, 'loadClass']); -} - return $loader; diff --git a/tests/AppConfig/config.yml b/tests/AppConfig/config.yml index 639d5cc8..f02b470a 100644 --- a/tests/AppConfig/config.yml +++ b/tests/AppConfig/config.yml @@ -9,9 +9,6 @@ framework: liip_functional_test: command_verbosity: "very_verbose" command_decoration: false - query: - # TODO: it should be 1 - max_query_count: 0 authentication: username: "foobar" password: "12341234" diff --git a/tests/Command/CommandTest.php b/tests/Command/CommandTest.php index c0e2b472..4ebfd094 100644 --- a/tests/Command/CommandTest.php +++ b/tests/Command/CommandTest.php @@ -14,7 +14,6 @@ namespace Liip\Acme\Tests\Command; use Liip\FunctionalTestBundle\Test\WebTestCase; -use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Tester\CommandTester; @@ -71,17 +70,9 @@ public function testRunCommandWithInputs(): void $this->assertStringContainsString('Value of answer: AcmeDemoBundle', $this->commandTester->getDisplay()); } - /** - * @dataProvider useEnvProvider - */ - #[DataProvider('useEnvProvider')] - public function testRunCommandWithoutOptionsAndNotReuseKernel(bool $useEnv): void + public function testRunCommandWithoutOptionsAndNotReuseKernel(): void { - if ($useEnv) { - static::$env = 'test'; - } else { - $this->environment = 'test'; - } + static::$env = 'test'; // Run command without options $this->commandTester = $this->runCommand('liipfunctionaltestbundle:test'); @@ -97,11 +88,7 @@ public function testRunCommandWithoutOptionsAndNotReuseKernel(bool $useEnv): voi $this->assertTrue($this->getDecorated()); // Run command and reuse kernel - if ($useEnv) { - static::$env = 'prod'; - } else { - $this->environment = 'prod'; - } + static::$env = 'prod'; self::ensureKernelShutdown(); $this->getContainer(); @@ -113,14 +100,6 @@ public function testRunCommandWithoutOptionsAndNotReuseKernel(bool $useEnv): voi $this->assertStringContainsString('Verbosity level: NORMAL', $this->commandTester->getDisplay()); } - public static function useEnvProvider(): array - { - return [ - [true], - [false], - ]; - } - public function testRunCommandWithoutDecoration(): void { // Set `decorated` to false diff --git a/tests/DependencyInjection/Compiler/SetTestClientPassMockTest.php b/tests/DependencyInjection/Compiler/SetTestClientPassMockTest.php deleted file mode 100644 index 8aa333dc..00000000 --- a/tests/DependencyInjection/Compiler/SetTestClientPassMockTest.php +++ /dev/null @@ -1,67 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Liip\Acme\Tests\DependencyInjection\Compiler; - -use Liip\FunctionalTestBundle\DependencyInjection\Compiler\SetTestClientPass; -use PHPUnit\Framework\TestCase; - -/** - * Test DependencyInjection\Compiler\SetTestClientPass with mocks. - * - * try/catch block is based on PHPUnit internal test: - * - * @see https://github.com/sebastianbergmann/phpunit/blob/b12b9c37e382c096b93c3f26e7395775f59a5eea/tests/Framework/AssertTest.php#L3560-L3574 - */ -class SetTestClientPassMockTest extends TestCase -{ - /** - * Simulate a wrong environment. - */ - public function testSetTestClientPassElse(): void - { - /* @see http://gianarb.it/blog/symfony-unit-test-controller-with-phpunit#expectations */ - /** @var \Symfony\Component\DependencyInjection\ContainerBuilder $container */ - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->disableOriginalConstructor() - ->getMock(); - - $container->expects($this->any()) - ->method('getParameter') - ->willReturn(true); - - $container->expects($this->any()) - ->method('hasDefinition') - ->willReturn(false); - - $container->expects($this->any()) - ->method('hasAlias') - ->willReturn(false); - - try { - $setTestClientPass = new SetTestClientPass(); - $setTestClientPass->process($container); - } catch (\Exception $e) { - $this->assertSame( - 'The LiipFunctionalTestBundle\'s Query Counter can only be used in the test environment.'. - \PHP_EOL. - 'See https://github.com/liip/LiipFunctionalTestBundle#only-in-test-environment', - $e->getMessage() - ); - - return; - } - - $this->fail('Test failed.'); - } -} diff --git a/tests/DependencyInjection/ConfigurationConfigTest.php b/tests/DependencyInjection/ConfigurationConfigTest.php index 439a9122..34eac877 100644 --- a/tests/DependencyInjection/ConfigurationConfigTest.php +++ b/tests/DependencyInjection/ConfigurationConfigTest.php @@ -42,7 +42,6 @@ public static function parametersProvider(): array return [ ['command_verbosity', 'very_verbose'], ['command_decoration', false], - ['query.max_query_count', 0], ['authentication.username', 'foobar'], ['authentication.password', '12341234'], ]; diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index f90662d6..e4fa2ab8 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -26,7 +26,7 @@ class ConfigurationTest extends WebTestCase protected function setUp(): void { - $client = static::makeClient(); + $client = static::createClientWithParams(); $this->clientContainer = $client->getContainer(); } @@ -66,7 +66,6 @@ public static function parametersProvider(): array return [ ['command_verbosity', 'normal'], ['command_decoration', true], - ['query.max_query_count', null], ['authentication.username', ''], ['authentication.password', ''], ]; diff --git a/tests/Test/WebTestCaseConfigLeanFrameworkTest.php b/tests/Test/WebTestCaseConfigLeanFrameworkTest.php index 03d6a8db..4d6c2d79 100644 --- a/tests/Test/WebTestCaseConfigLeanFrameworkTest.php +++ b/tests/Test/WebTestCaseConfigLeanFrameworkTest.php @@ -41,19 +41,9 @@ protected static function getKernelClass(): string return AppConfigLeanFrameworkKernel::class; } - public function testAssertStatusCode(): void - { - $client = static::makeClient(); - - $path = '/'; - $client->request('GET', $path); - - $this->assertStatusCode(200, $client); - } - public function testAssertValidationErrorsTriggersError(): void { - $client = static::makeClient(); + $client = static::createClientWithParams(); $path = '/form'; $client->request('GET', $path); diff --git a/tests/Test/WebTestCaseConfigTest.php b/tests/Test/WebTestCaseConfigTest.php index 68d4f4ec..b2c82b69 100644 --- a/tests/Test/WebTestCaseConfigTest.php +++ b/tests/Test/WebTestCaseConfigTest.php @@ -17,9 +17,7 @@ use Liip\Acme\Tests\App\Entity\User; use Liip\Acme\Tests\AppConfig\AppConfigKernel; 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. @@ -54,48 +52,13 @@ protected static function getKernelClass(): string */ public function testIndexClientWithCredentials(): void { - $this->skipTestIfSymfonyHasVersion7(); - - $this->client = static::makeClientWithCredentials('foobar', '12341234'); - - $path = '/admin'; - - $crawler = $this->client->request('GET', $path); - - $this->assertStatusCode(200, $this->client); - - $this->assertSame( - 1, - $crawler->filter('html > body')->count() - ); - - $this->assertSame( - 'Logged in as foobar.', - $crawler->filter('p#user')->text() - ); - - $this->assertSame( - 'LiipFunctionalTestBundle', - $crawler->filter('h1')->text() - ); - } - - /** - * Log in as the user defined in the - * "liip_functional_test.authentication" - * node from the configuration file. - */ - public function testIndexAuthenticatedClient(): void - { - $this->skipTestIfSymfonyHasVersion7(); - - $this->client = static::makeAuthenticatedClient(); + $this->client = static::createClientWithParams([], 'foobar', '12341234'); $path = '/admin'; $crawler = $this->client->request('GET', $path); - $this->assertStatusCode(200, $this->client); + self::assertResponseStatusCodeSame(200); $this->assertSame( 1, @@ -112,164 +75,4 @@ public function testIndexAuthenticatedClient(): void $crawler->filter('h1')->text() ); } - - /** - * Log in as the user defined in the Data Fixture. - * - * loginAs() is deprecated, but we test if for Backward Compatibility. - */ - public function testIndexAuthenticationLoginAs(): void - { - $this->skipTestIfSymfonyHasVersion7(); - - $user = $this->loadTestFixtures(); - - $loginAs = $this->loginAs($user, 'secured_area'); - - $this->assertInstanceOf( - 'Liip\FunctionalTestBundle\Test\WebTestCase', - $loginAs - ); - - $this->client = static::makeClient(); - - $path = '/'; - - $crawler = $this->client->request('GET', $path); - - $this->assertStatusCode(200, $this->client); - - $this->assertSame( - 1, - $crawler->filter('html > body')->count() - ); - - $this->assertSame( - 'Logged in as foo bar.', - $crawler->filter('p#user')->text() - ); - - $this->assertSame( - 'LiipFunctionalTestBundle', - $crawler->filter('h1')->text() - ); - } - - /** - * Log in as the user defined in the Data Fixture. - */ - public function testIndexAuthenticationLoginClient(): void - { - $this->skipTestIfSymfonyHasVersion7(); - - $user = $this->loadTestFixtures(); - - $this->client = static::makeClient(); - - $this->loginClient($this->client, $user, 'secured_area'); - - $path = '/'; - - $crawler = $this->client->request('GET', $path); - - $this->assertStatusCode(200, $this->client); - - $this->assertSame( - 1, - $crawler->filter('html > body')->count() - ); - - $this->assertSame( - 'Logged in as foo bar.', - $crawler->filter('p#user')->text() - ); - - $this->assertSame( - 'LiipFunctionalTestBundle', - $crawler->filter('h1')->text() - ); - } - - /** - * Log in as the user defined in the Data Fixtures and except an - * AllowedQueriesExceededException exception. - * - * There will be 2 queries: - * - the user 1 is loaded from the database when logging in - * - the user 2 is loaded by the controller - * - * In the configuration the limit is 1, an Exception will be thrown. - */ - public function testAllowedQueriesExceededException(): void - { - $this->skipTestIfSymfonyHasVersion7(); - - $user = $this->loadTestFixtures(); - - $this->assertInstanceOf( - User::class, - $user - ); - - $this->client = static::makeClient(); - - $this->loginClient($this->client, $user, 'secured_area'); - - $path = '/user/2'; - - $this->expectException(\Liip\FunctionalTestBundle\Exception\AllowedQueriesExceededException::class); - - $crawler = $this->client->request('GET', $path); - - // The following code is called if no exception has been thrown, it should help to understand why - $this->assertStatusCode(200, $this->client); - $this->assertSame( - 'LiipFunctionalTestBundle', - $crawler->filter('h1')->text() - ); - $this->assertSame( - 'Logged in as foo bar.', - $crawler->filter('p#user')->text() - ); - $this->assertSame( - 'Name: alice bob', - $crawler->filter('div#content p:nth-child(1)')->text() - ); - $this->assertSame( - 'Email: alice@example.com', - $crawler->filter('div#content p:nth-child(2)')->text() - ); - } - - /** - * Expect an exception due to the QueryCount annotation. - * - * @QueryCount(0) - * - * There will be 1 query, in the annotation the limit is 0, - * an Exception will be thrown. - */ - public function testAnnotationAndException(): void - { - $this->skipTestIfSymfonyHasVersion7(); - - $this->loadTestFixtures(); - - $this->client = static::makeClient(); - - // One query to load the second user - $path = '/user/1'; - - $this->expectException(\Liip\FunctionalTestBundle\Exception\AllowedQueriesExceededException::class); - - $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 d2608c81..cf8d3527 100644 --- a/tests/Test/WebTestCaseTest.php +++ b/tests/Test/WebTestCaseTest.php @@ -18,7 +18,6 @@ use Liip\Acme\Tests\App\Service\DependencyService; use Liip\Acme\Tests\App\Service\Service; use Liip\FunctionalTestBundle\Test\WebTestCase; -use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpFoundation\RequestStack; @@ -57,14 +56,6 @@ public function testGetContainer(): void ); } - public function testMakeClient(): void - { - $this->assertInstanceOf( - 'Symfony\Bundle\FrameworkBundle\Client', - static::makeClient() - ); - } - public function testGetUrl(): void { $path = $this->getUrl( @@ -87,7 +78,7 @@ public function testIndex(): void { $path = '/'; - $crawler = static::makeClient()->request('GET', $path); + $crawler = static::createClientWithParams()->request('GET', $path); $this->assertSame( 1, @@ -105,174 +96,6 @@ public function testIndex(): void ); } - /** - * Call methods from the parent class. - */ - - /** - * @depends testIndex - */ - public function testIndexAssertStatusCode(): void - { - $path = '/'; - - $client = static::makeClient(); - - $client->request('GET', $path); - - $this->assertStatusCode(200, $client); - } - - /** - * Check the failure message returned by assertStatusCode(). - */ - public function testAssertStatusCodeFail(): void - { - $path = '/'; - - $client = static::makeClient(); - $client->request('GET', $path); - - try { - $this->assertStatusCode(-1, $client); - } catch (AssertionFailedError $e) { - $this->assertStringStartsWith( - 'HTTP/1.1 200 OK', - $e->getMessage() - ); - - $this->assertStringEndsWith( - 'Failed asserting that 200 is identical to -1.', - $e->getMessage() - ); - - return; - } - - $this->fail('Test failed.'); - } - - /** - * Check the failure message returned by assertStatusCode(). - */ - public function testAssertStatusCodeException(): void - { - $path = '/9999'; - - $client = static::makeClient(); - $client->request('GET', $path); - - try { - $this->assertStatusCode(-1, $client); - } catch (AssertionFailedError $e) { - $this->assertStringContainsString('No route found', $e->getMessage()); - $this->assertStringContainsString('Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest(', $e->getMessage()); - $this->assertStringContainsString('Failed asserting that 404 is identical to -1.', $e->getMessage()); - - return; - } - - $this->fail('Test failed.'); - } - - /** - * @depends testIndex - */ - public function testIndexIsSuccesful(): void - { - $path = '/'; - - $client = static::makeClient(); - $client->request('GET', $path); - - $this->isSuccessful($client->getResponse()); - } - - /** - * @depends testIndex - */ - public function testIndexFetchCrawler(): void - { - $path = '/'; - - $crawler = $this->fetchCrawler($path); - - $this->assertInstanceOf( - 'Symfony\Component\DomCrawler\Crawler', - $crawler - ); - - $this->assertSame( - 1, - $crawler->filter('html > body')->count() - ); - - $this->assertSame( - 'Not logged in.', - $crawler->filter('p#user')->text() - ); - - $this->assertSame( - 'LiipFunctionalTestBundle', - $crawler->filter('h1')->text() - ); - } - - /** - * @depends testIndex - */ - public function testIndexFetchContent(): void - { - $path = '/'; - - $content = $this->fetchContent($path); - - $this->assertIsString($content); - - $this->assertStringContainsString( - '

LiipFunctionalTestBundle

', - $content - ); - } - - public function test404Error(): void - { - $path = '/missing_page'; - - $client = static::makeClient(); - $client->request('GET', $path); - - $this->assertStatusCode(404, $client); - - $this->isSuccessful($client->getResponse(), false); - } - - /** - * Throw an Exception in the try/catch block and check the failure message - * returned by assertStatusCode(). - */ - public function testIsSuccessfulException(): void - { - $path = '/exception'; - - $client = static::makeClient(); - $client->request('GET', $path); - - try { - $this->isSuccessful($client->getResponse()); - } catch (AssertionFailedError $e) { - $string = <<<'EOF' - The Response was not successful: foo (500 Internal Server Error) - Failed asserting that false is true. - EOF; - $this->assertSame($string, $e->getMessage()); - - return; - } - - $this->fail('Test failed.'); - } - /** * Form. */ @@ -280,15 +103,15 @@ public function testForm(): void { $path = '/form'; - $client = static::makeClient(); + $client = static::createClientWithParams(); $crawler = $client->request('GET', $path); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $form = $crawler->selectButton('Submit')->form(); $crawler = $client->submit($form); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $this->assertValidationErrors(['children[name].data'], $client->getContainer()); @@ -297,7 +120,7 @@ public function testForm(): void $form->setValues(['form[name]' => 'foo bar']); $crawler = $client->submit($form); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $this->assertStringContainsString( 'Name submitted.', @@ -314,15 +137,15 @@ public function testFormWithEmbed(): void { $path = '/form-with-embed'; - $client = static::makeClient(); + $client = static::createClientWithParams(); $crawler = $client->request('GET', $path); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $form = $crawler->selectButton('Submit')->form(); $crawler = $client->submit($form); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $this->assertValidationErrors(['children[name].data'], $client->getContainer()); @@ -331,7 +154,7 @@ public function testFormWithEmbed(): void $form->setValues(['form[name]' => 'foo bar']); $crawler = $client->submit($form); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $this->assertStringContainsString( 'Name submitted.', @@ -346,70 +169,21 @@ public function testFormWithException(): void { $path = '/form'; - $client = static::makeClient(); + $client = static::createClientWithParams(); $crawler = $client->request('GET', $path); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $form = $crawler->selectButton('Submit')->form(); $client->submit($form); - $this->assertStatusCode(200, $client); + self::assertResponseStatusCodeSame(200); $this->expectException(\PHPUnit\Framework\ExpectationFailedException::class); $this->assertValidationErrors([''], $client->getContainer()); } - /** - * Check the failure message returned by assertStatusCode() - * when an invalid form is submitted. - */ - public function testFormWithExceptionAssertStatusCode(): void - { - $path = '/form'; - - $client = static::makeClient(); - $crawler = $client->request('GET', $path); - - $form = $crawler->selectButton('Submit')->form(); - - $client->submit($form); - - try { - $this->assertStatusCode(-1, $client); - } catch (AssertionFailedError $e) { - $string = <<<'EOF' - Unexpected validation errors: - + children[name].data: This value should not be blank. - - Failed asserting that 200 is identical to -1. - EOF; - $this->assertSame($string, $e->getMessage()); - - return; - } - - $this->fail('Test failed.'); - } - - /** - * Call isSuccessful() with "application/json" content type. - */ - public function testJsonIsSuccessful(): void - { - $path = '/json'; - - $client = static::makeClient(); - $client->request('GET', $path); - - $this->isSuccessful( - $client->getResponse(), - true, - 'application/json' - ); - } - public function testSetServiceMockCommand(): void { $mockedServiceClass = RequestStack::class;