From 6a83e138a87b795a1c32943b10a911781cd07da5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 27 Jun 2019 20:37:35 +0200 Subject: [PATCH 1/8] [HttpClient] Add support for NTLM authentication --- DependencyInjection/Configuration.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ea64157fd..1b16809d6 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -1414,6 +1414,9 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode) ->scalarNode('auth_bearer') ->info('A token enabling HTTP Bearer authorization.') ->end() + ->scalarNode('auth_ntlm') + ->info('A "username:password" pair to use Microsoft NTLM authentication (requires the cURL extension).') + ->end() ->arrayNode('query') ->info('Associative array of query string values merged with the base URI.') ->useAttributeAsKey('key') From 3e33ab75c7e2d33b3c1c5a9f63321d9b5da78cd5 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 28 Jun 2019 18:36:51 +0200 Subject: [PATCH 2/8] deprecate the framework.templating option --- CHANGELOG.md | 1 + DependencyInjection/Configuration.php | 1 + Tests/DependencyInjection/ConfigurationTest.php | 3 +++ Tests/DependencyInjection/FrameworkExtensionTest.php | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c877f562..d8c07db3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 4.3.0 ----- + * Deprecated the `framework.templating` option, use Twig instead. * Added `WebTestAssertionsTrait` (included by default in `WebTestCase`) * Renamed `Client` to `KernelBrowser` * Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ea64157fd..e7233cd49 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -605,6 +605,7 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) ->arrayNode('templating') ->info('templating configuration') ->canBeEnabled() + ->setDeprecated('The "%path%.%node%" configuration is deprecated since Symfony 4.3. Use the "twig" service directly instead.') ->beforeNormalization() ->ifTrue(function ($v) { return false === $v || \is_array($v) && false === $v['enabled']; }) ->then(function () { return ['enabled' => false, 'engines' => false]; }) diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 398003600..4a5001e10 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -35,6 +35,9 @@ public function testDefaultConfig() ); } + /** + * @group legacy + */ public function testDoNoDuplicateDefaultFormResources() { $input = ['templating' => [ diff --git a/Tests/DependencyInjection/FrameworkExtensionTest.php b/Tests/DependencyInjection/FrameworkExtensionTest.php index fab27d489..01cd04a74 100644 --- a/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -602,6 +602,9 @@ public function testTemplating() $this->assertEquals('global_hinclude_template', $container->getParameter('fragment.renderer.hinclude.global_template'), '->registerTemplatingConfiguration() registers the global hinclude.js template'); } + /** + * @group legacy + */ public function testTemplatingCanBeDisabled() { $container = $this->createContainerFromFile('templating_disabled'); @@ -867,6 +870,7 @@ public function testTranslatorMultipleFallbacks() } /** + * @group legacy * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException */ public function testTemplatingRequiresAtLeastOneEngine() From dc81d59030e9ac7cb437bc5a6559b821670d1f01 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Mon, 1 Jul 2019 10:32:47 -0400 Subject: [PATCH 3/8] Fixing validation for messenger transports retry_strategy service key --- DependencyInjection/Configuration.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ea64157fd..e7034b411 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -1195,9 +1195,14 @@ function ($a) { ->end() ->arrayNode('retry_strategy') ->addDefaultsIfNotSet() - ->validate() - ->ifTrue(function ($v) { return null !== $v['service'] && (isset($v['max_retries']) || isset($v['delay']) || isset($v['multiplier']) || isset($v['max_delay'])); }) - ->thenInvalid('"service" cannot be used along with the other retry_strategy options.') + ->beforeNormalization() + ->always(function ($v) { + if (isset($v['service']) && (isset($v['max_retries']) || isset($v['delay']) || isset($v['multiplier']) || isset($v['max_delay']))) { + throw new \InvalidArgumentException('The "service" cannot be used along with the other "retry_strategy" options.'); + } + + return $v; + }) ->end() ->children() ->scalarNode('service')->defaultNull()->info('Service id to override the retry strategy entirely')->end() From d61a9de929d085342cf600922c2fc57b694767b6 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 2 Jul 2019 17:10:36 +0200 Subject: [PATCH 4/8] [FrmaeworkBundle] More simplifications in the DI configuration --- DependencyInjection/Configuration.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ea64157fd..443332f2c 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -339,10 +339,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) ->defaultNull() ->end() ->arrayNode('initial_marking') - ->beforeNormalization() - ->ifTrue(function ($v) { return !\is_array($v); }) - ->then(function ($v) { return [$v]; }) - ->end() + ->beforeNormalization()->castToArray()->end() ->defaultValue([]) ->prototype('scalar')->end() ->end() From 8fb5ab68621aeb95f0cede620bd7d49a129e11f3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 2 Jul 2019 17:01:08 +0200 Subject: [PATCH 5/8] [FrameworkBundle] Simplified some code in the DI configuration --- DependencyInjection/Configuration.php | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ea64157fd..a5e36e3f3 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -585,10 +585,7 @@ private function addRequestSection(ArrayNodeDefinition $rootNode) ->ifTrue(function ($v) { return \is_array($v) && isset($v['mime_type']); }) ->then(function ($v) { return $v['mime_type']; }) ->end() - ->beforeNormalization() - ->ifTrue(function ($v) { return !\is_array($v); }) - ->then(function ($v) { return [$v]; }) - ->end() + ->beforeNormalization()->castToArray()->end() ->prototype('scalar')->end() ->end() ->end() @@ -646,10 +643,7 @@ private function addTemplatingSection(ArrayNodeDefinition $rootNode) ->fixXmlConfig('loader') ->children() ->arrayNode('loaders') - ->beforeNormalization() - ->ifTrue(function ($v) { return !\is_array($v); }) - ->then(function ($v) { return [$v]; }) - ->end() + ->beforeNormalization()->castToArray()->end() ->prototype('scalar')->end() ->end() ->end() @@ -674,10 +668,7 @@ private function addAssetsSection(ArrayNodeDefinition $rootNode) ->scalarNode('base_path')->defaultValue('')->end() ->arrayNode('base_urls') ->requiresAtLeastOneElement() - ->beforeNormalization() - ->ifTrue(function ($v) { return !\is_array($v); }) - ->then(function ($v) { return [$v]; }) - ->end() + ->beforeNormalization()->castToArray()->end() ->prototype('scalar')->end() ->end() ->end() @@ -719,10 +710,7 @@ private function addAssetsSection(ArrayNodeDefinition $rootNode) ->scalarNode('base_path')->defaultValue('')->end() ->arrayNode('base_urls') ->requiresAtLeastOneElement() - ->beforeNormalization() - ->ifTrue(function ($v) { return !\is_array($v); }) - ->then(function ($v) { return [$v]; }) - ->end() + ->beforeNormalization()->castToArray()->end() ->prototype('scalar')->end() ->end() ->end() @@ -817,10 +805,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode) ->defaultValue(['loadValidatorMetadata']) ->prototype('scalar')->end() ->treatFalseLike([]) - ->validate() - ->ifTrue(function ($v) { return !\is_array($v); }) - ->then(function ($v) { return (array) $v; }) - ->end() + ->validate()->castToArray()->end() ->end() ->scalarNode('translation_domain')->defaultValue('validators')->end() ->booleanNode('strict_email')->end() From 55c3328481f5d12cb99199dc769da54e45112093 Mon Sep 17 00:00:00 2001 From: Chris Tanaskoski Date: Tue, 11 Jun 2019 12:05:04 +0200 Subject: [PATCH 6/8] [WIP][Mailer] Overwrite envelope sender and recipients from config --- DependencyInjection/Configuration.php | 16 ++++++ DependencyInjection/FrameworkExtension.php | 7 +++ Resources/config/mailer.xml | 6 +++ Tests/Functional/MailerTest.php | 62 ++++++++++++++++++++++ Tests/Functional/app/Mailer/bundles.php | 18 +++++++ Tests/Functional/app/Mailer/config.yml | 9 ++++ 6 files changed, 118 insertions(+) create mode 100644 Tests/Functional/MailerTest.php create mode 100644 Tests/Functional/app/Mailer/bundles.php create mode 100644 Tests/Functional/app/Mailer/config.yml diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ea64157fd..86eb3bb79 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -1525,6 +1525,22 @@ private function addMailerSection(ArrayNodeDefinition $rootNode) ->{!class_exists(FullStack::class) && class_exists(Mailer::class) ? 'canBeDisabled' : 'canBeEnabled'}() ->children() ->scalarNode('dsn')->defaultValue('smtp://null')->end() + ->arrayNode('envelope') + ->info('Mailer Envelope configuration') + ->children() + ->scalarNode('sender')->end() + ->arrayNode('recipients') + ->performNoDeepMerging() + ->beforeNormalization() + ->ifArray() + ->then(function ($v) { + return array_filter(array_values($v)); + }) + ->end() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() ->end() ->end() ->end() diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index 19386d972..34ab211f0 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -1918,6 +1918,13 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co $loader->load('mailer.xml'); $container->getDefinition('mailer.default_transport')->setArgument(0, $config['dsn']); + + $recipients = $config['envelope']['recipients'] ?? null; + $sender = $config['envelope']['sender'] ?? null; + + $envelopeListener = $container->getDefinition('mailer.envelope_listener'); + $envelopeListener->setArgument(0, $sender); + $envelopeListener->setArgument(1, $recipients); } /** diff --git a/Resources/config/mailer.xml b/Resources/config/mailer.xml index 1f567a6c9..cfe98f21d 100644 --- a/Resources/config/mailer.xml +++ b/Resources/config/mailer.xml @@ -25,5 +25,11 @@ + + + + + + diff --git a/Tests/Functional/MailerTest.php b/Tests/Functional/MailerTest.php new file mode 100644 index 000000000..85987fe28 --- /dev/null +++ b/Tests/Functional/MailerTest.php @@ -0,0 +1,62 @@ + 'Mailer']); + + $onDoSend = function (SentMessage $message) { + $envelope = $message->getEnvelope(); + + $this->assertEquals( + [new Address('redirected@example.org')], + $envelope->getRecipients() + ); + + $this->assertEquals('sender@example.org', $envelope->getSender()->getAddress()); + }; + + $eventDispatcher = self::$container->get(EventDispatcherInterface::class); + $logger = self::$container->get('logger'); + + $testTransport = new class($eventDispatcher, $logger, $onDoSend) extends AbstractTransport { + /** + * @var callable + */ + private $onDoSend; + + public function __construct(EventDispatcherInterface $eventDispatcher, LoggerInterface $logger, callable $onDoSend) + { + parent::__construct($eventDispatcher, $logger); + $this->onDoSend = $onDoSend; + } + + protected function doSend(SentMessage $message): void + { + $onDoSend = $this->onDoSend; + $onDoSend($message); + } + }; + + $mailer = new Mailer($testTransport, null); + + $message = (new Email()) + ->subject('Test subject') + ->text('Hello world') + ->from('from@example.org') + ->to('to@example.org'); + + $mailer->send($message); + } +} diff --git a/Tests/Functional/app/Mailer/bundles.php b/Tests/Functional/app/Mailer/bundles.php new file mode 100644 index 000000000..15ff182c6 --- /dev/null +++ b/Tests/Functional/app/Mailer/bundles.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; +use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle; + +return [ + new FrameworkBundle(), + new TestBundle(), +]; diff --git a/Tests/Functional/app/Mailer/config.yml b/Tests/Functional/app/Mailer/config.yml new file mode 100644 index 000000000..196869945 --- /dev/null +++ b/Tests/Functional/app/Mailer/config.yml @@ -0,0 +1,9 @@ +imports: + - { resource: ../config/default.yml } + +framework: + mailer: + envelope: + sender: sender@example.org + recipients: + - redirected@example.org From dcc4f96d180177262eeafd607743ed175b66d384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 27 Jun 2019 08:20:20 +0200 Subject: [PATCH 7/8] [FrameworkBundle] Allow to use the BrowserKit assertions with Panther and API Platform's test client --- Test/BrowserKitAssertionsTrait.php | 159 ++++++++++++++++++++++ Test/DomCrawlerAssertionsTrait.php | 94 +++++++++++++ Test/WebTestAssertionsTrait.php | 211 +---------------------------- 3 files changed, 255 insertions(+), 209 deletions(-) create mode 100644 Test/BrowserKitAssertionsTrait.php create mode 100644 Test/DomCrawlerAssertionsTrait.php diff --git a/Test/BrowserKitAssertionsTrait.php b/Test/BrowserKitAssertionsTrait.php new file mode 100644 index 000000000..086d83e8a --- /dev/null +++ b/Test/BrowserKitAssertionsTrait.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Test; + +use PHPUnit\Framework\Constraint\LogicalAnd; +use PHPUnit\Framework\Constraint\LogicalNot; +use Symfony\Component\BrowserKit\AbstractBrowser; +use Symfony\Component\BrowserKit\Test\Constraint as BrowserKitConstraint; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Test\Constraint as ResponseConstraint; + +/** + * Ideas borrowed from Laravel Dusk's assertions. + * + * @see https://laravel.com/docs/5.7/dusk#available-assertions + */ +trait BrowserKitAssertionsTrait +{ + public static function assertResponseIsSuccessful(string $message = ''): void + { + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseIsSuccessful(), $message); + } + + public static function assertResponseStatusCodeSame(int $expectedCode, string $message = ''): void + { + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseStatusCodeSame($expectedCode), $message); + } + + public static function assertResponseRedirects(string $expectedLocation = null, int $expectedCode = null, string $message = ''): void + { + $constraint = new ResponseConstraint\ResponseIsRedirected(); + if ($expectedLocation) { + $constraint = LogicalAnd::fromConstraints($constraint, new ResponseConstraint\ResponseHeaderSame('Location', $expectedLocation)); + } + if ($expectedCode) { + $constraint = LogicalAnd::fromConstraints($constraint, new ResponseConstraint\ResponseStatusCodeSame($expectedCode)); + } + + self::assertThat(self::getResponse(), $constraint, $message); + } + + public static function assertResponseHasHeader(string $headerName, string $message = ''): void + { + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHasHeader($headerName), $message); + } + + public static function assertResponseNotHasHeader(string $headerName, string $message = ''): void + { + self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasHeader($headerName)), $message); + } + + public static function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void + { + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue), $message); + } + + public static function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void + { + self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue)), $message); + } + + public static function assertResponseHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + { + self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHasCookie($name, $path, $domain), $message); + } + + public static function assertResponseNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + { + self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasCookie($name, $path, $domain)), $message); + } + + public static function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', string $domain = null, string $message = ''): void + { + self::assertThat(self::getResponse(), LogicalAnd::fromConstraints( + new ResponseConstraint\ResponseHasCookie($name, $path, $domain), + new ResponseConstraint\ResponseCookieValueSame($name, $expectedValue, $path, $domain) + ), $message); + } + + public static function assertBrowserHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + { + self::assertThat(self::getClient(), new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), $message); + } + + public static function assertBrowserNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + { + self::assertThat(self::getClient(), new LogicalNot(new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain)), $message); + } + + public static function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', string $domain = null, string $message = ''): void + { + self::assertThat(self::getClient(), LogicalAnd::fromConstraints( + new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), + new BrowserKitConstraint\BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain) + ), $message); + } + + public static function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void + { + self::assertThat(self::getRequest(), new ResponseConstraint\RequestAttributeValueSame($name, $expectedValue), $message); + } + + public static function assertRouteSame($expectedRoute, array $parameters = [], string $message = ''): void + { + $constraint = new ResponseConstraint\RequestAttributeValueSame('_route', $expectedRoute); + $constraints = []; + foreach ($parameters as $key => $value) { + $constraints[] = new ResponseConstraint\RequestAttributeValueSame($key, $value); + } + if ($constraints) { + $constraint = LogicalAnd::fromConstraints($constraint, ...$constraints); + } + + self::assertThat(self::getRequest(), $constraint, $message); + } + + private static function getClient(AbstractBrowser $newClient = null): ?AbstractBrowser + { + static $client; + + if (0 < \func_num_args()) { + return $client = $newClient; + } + + if (!$client instanceof AbstractBrowser) { + static::fail(sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); + } + + return $client; + } + + private static function getResponse(): Response + { + if (!$response = self::getClient()->getResponse()) { + static::fail('A client must have an HTTP Response to make assertions. Did you forget to make an HTTP request?'); + } + + return $response; + } + + private static function getRequest(): Request + { + if (!$request = self::getClient()->getRequest()) { + static::fail('A client must have an HTTP Request to make assertions. Did you forget to make an HTTP request?'); + } + + return $request; + } +} diff --git a/Test/DomCrawlerAssertionsTrait.php b/Test/DomCrawlerAssertionsTrait.php new file mode 100644 index 000000000..465c265f6 --- /dev/null +++ b/Test/DomCrawlerAssertionsTrait.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Test; + +use PHPUnit\Framework\Constraint\LogicalAnd; +use PHPUnit\Framework\Constraint\LogicalNot; +use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\DomCrawler\Test\Constraint as DomCrawlerConstraint; + +/** + * Ideas borrowed from Laravel Dusk's assertions. + * + * @see https://laravel.com/docs/5.7/dusk#available-assertions + */ +trait DomCrawlerAssertionsTrait +{ + public static function assertSelectorExists(string $selector, string $message = ''): void + { + self::assertThat(self::getCrawler(), new DomCrawlerConstraint\CrawlerSelectorExists($selector), $message); + } + + public static function assertSelectorNotExists(string $selector, string $message = ''): void + { + self::assertThat(self::getCrawler(), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorExists($selector)), $message); + } + + public static function assertSelectorTextContains(string $selector, string $text, string $message = ''): void + { + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( + new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text) + ), $message); + } + + public static function assertSelectorTextSame(string $selector, string $text, string $message = ''): void + { + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( + new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new DomCrawlerConstraint\CrawlerSelectorTextSame($selector, $text) + ), $message); + } + + public static function assertSelectorTextNotContains(string $selector, string $text, string $message = ''): void + { + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( + new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text)) + ), $message); + } + + public static function assertPageTitleSame(string $expectedTitle, string $message = ''): void + { + self::assertSelectorTextSame('title', $expectedTitle, $message); + } + + public static function assertPageTitleContains(string $expectedTitle, string $message = ''): void + { + self::assertSelectorTextContains('title', $expectedTitle, $message); + } + + public static function assertInputValueSame(string $fieldName, string $expectedValue, string $message = ''): void + { + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( + new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), + new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue) + ), $message); + } + + public static function assertInputValueNotSame(string $fieldName, string $expectedValue, string $message = ''): void + { + self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( + new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), + new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue)) + ), $message); + } + + private static function getCrawler(): Crawler + { + if (!$crawler = self::getClient()->getCrawler()) { + static::fail('A client must have a crawler to make assertions. Did you forget to make an HTTP request?'); + } + + return $crawler; + } +} diff --git a/Test/WebTestAssertionsTrait.php b/Test/WebTestAssertionsTrait.php index f820e8d08..197f2131b 100644 --- a/Test/WebTestAssertionsTrait.php +++ b/Test/WebTestAssertionsTrait.php @@ -11,16 +11,6 @@ namespace Symfony\Bundle\FrameworkBundle\Test; -use PHPUnit\Framework\Constraint\LogicalAnd; -use PHPUnit\Framework\Constraint\LogicalNot; -use Symfony\Bundle\FrameworkBundle\KernelBrowser; -use Symfony\Component\BrowserKit\Test\Constraint as BrowserKitConstraint; -use Symfony\Component\DomCrawler\Crawler; -use Symfony\Component\DomCrawler\Test\Constraint as DomCrawlerConstraint; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Test\Constraint as ResponseConstraint; - /** * Ideas borrowed from Laravel Dusk's assertions. * @@ -28,203 +18,6 @@ */ trait WebTestAssertionsTrait { - public static function assertResponseIsSuccessful(string $message = ''): void - { - self::assertThat(self::getResponse(), new ResponseConstraint\ResponseIsSuccessful(), $message); - } - - public static function assertResponseStatusCodeSame(int $expectedCode, string $message = ''): void - { - self::assertThat(self::getResponse(), new ResponseConstraint\ResponseStatusCodeSame($expectedCode), $message); - } - - public static function assertResponseRedirects(string $expectedLocation = null, int $expectedCode = null, string $message = ''): void - { - $constraint = new ResponseConstraint\ResponseIsRedirected(); - if ($expectedLocation) { - $constraint = LogicalAnd::fromConstraints($constraint, new ResponseConstraint\ResponseHeaderSame('Location', $expectedLocation)); - } - if ($expectedCode) { - $constraint = LogicalAnd::fromConstraints($constraint, new ResponseConstraint\ResponseStatusCodeSame($expectedCode)); - } - - self::assertThat(self::getResponse(), $constraint, $message); - } - - public static function assertResponseHasHeader(string $headerName, string $message = ''): void - { - self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHasHeader($headerName), $message); - } - - public static function assertResponseNotHasHeader(string $headerName, string $message = ''): void - { - self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasHeader($headerName)), $message); - } - - public static function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void - { - self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue), $message); - } - - public static function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void - { - self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue)), $message); - } - - public static function assertResponseHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void - { - self::assertThat(self::getResponse(), new ResponseConstraint\ResponseHasCookie($name, $path, $domain), $message); - } - - public static function assertResponseNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void - { - self::assertThat(self::getResponse(), new LogicalNot(new ResponseConstraint\ResponseHasCookie($name, $path, $domain)), $message); - } - - public static function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', string $domain = null, string $message = ''): void - { - self::assertThat(self::getResponse(), LogicalAnd::fromConstraints( - new ResponseConstraint\ResponseHasCookie($name, $path, $domain), - new ResponseConstraint\ResponseCookieValueSame($name, $expectedValue, $path, $domain) - ), $message); - } - - public static function assertBrowserHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void - { - self::assertThat(self::getClient(), new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), $message); - } - - public static function assertBrowserNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void - { - self::assertThat(self::getClient(), new LogicalNot(new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain)), $message); - } - - public static function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', string $domain = null, string $message = ''): void - { - self::assertThat(self::getClient(), LogicalAnd::fromConstraints( - new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), - new BrowserKitConstraint\BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain) - ), $message); - } - - public static function assertSelectorExists(string $selector, string $message = ''): void - { - self::assertThat(self::getCrawler(), new DomCrawlerConstraint\CrawlerSelectorExists($selector), $message); - } - - public static function assertSelectorNotExists(string $selector, string $message = ''): void - { - self::assertThat(self::getCrawler(), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorExists($selector)), $message); - } - - public static function assertSelectorTextContains(string $selector, string $text, string $message = ''): void - { - self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), - new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text) - ), $message); - } - - public static function assertSelectorTextSame(string $selector, string $text, string $message = ''): void - { - self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), - new DomCrawlerConstraint\CrawlerSelectorTextSame($selector, $text) - ), $message); - } - - public static function assertSelectorTextNotContains(string $selector, string $text, string $message = ''): void - { - self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), - new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text)) - ), $message); - } - - public static function assertPageTitleSame(string $expectedTitle, string $message = ''): void - { - self::assertSelectorTextSame('title', $expectedTitle, $message); - } - - public static function assertPageTitleContains(string $expectedTitle, string $message = ''): void - { - self::assertSelectorTextContains('title', $expectedTitle, $message); - } - - public static function assertInputValueSame(string $fieldName, string $expectedValue, string $message = ''): void - { - self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), - new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue) - ), $message); - } - - public static function assertInputValueNotSame(string $fieldName, string $expectedValue, string $message = ''): void - { - self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), - new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue)) - ), $message); - } - - public static function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void - { - self::assertThat(self::getRequest(), new ResponseConstraint\RequestAttributeValueSame($name, $expectedValue), $message); - } - - public static function assertRouteSame($expectedRoute, array $parameters = [], string $message = ''): void - { - $constraint = new ResponseConstraint\RequestAttributeValueSame('_route', $expectedRoute); - $constraints = []; - foreach ($parameters as $key => $value) { - $constraints[] = new ResponseConstraint\RequestAttributeValueSame($key, $value); - } - if ($constraints) { - $constraint = LogicalAnd::fromConstraints($constraint, ...$constraints); - } - - self::assertThat(self::getRequest(), $constraint, $message); - } - - private static function getClient(KernelBrowser $newClient = null): ?KernelBrowser - { - static $client; - - if (0 < \func_num_args()) { - return $client = $newClient; - } - - if (!$client instanceof KernelBrowser) { - static::fail(sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); - } - - return $client; - } - - private static function getCrawler(): Crawler - { - if (!$crawler = self::getClient()->getCrawler()) { - static::fail('A client must have a crawler to make assertions. Did you forget to make an HTTP request?'); - } - - return $crawler; - } - - private static function getResponse(): Response - { - if (!$response = self::getClient()->getResponse()) { - static::fail('A client must have an HTTP Response to make assertions. Did you forget to make an HTTP request?'); - } - - return $response; - } - - private static function getRequest(): Request - { - if (!$request = self::getClient()->getRequest()) { - static::fail('A client must have an HTTP Request to make assertions. Did you forget to make an HTTP request?'); - } - - return $request; - } + use BrowserKitAssertionsTrait; + use DomCrawlerAssertionsTrait; } From 36590ecd45e780f55cf2d96965523da4ad42e412 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 4 Jul 2019 10:44:43 +0200 Subject: [PATCH 8/8] [FrameworkBundle] reset cache pools between requests --- Resources/config/cache.xml | 14 +++++++------- .../DependencyInjection/FrameworkExtensionTest.php | 5 ----- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Resources/config/cache.xml b/Resources/config/cache.xml index 36db49a49..a7aaaec7c 100644 --- a/Resources/config/cache.xml +++ b/Resources/config/cache.xml @@ -8,7 +8,7 @@ - + @@ -29,7 +29,7 @@ - + 0 @@ -39,7 +39,7 @@ - + 0 @@ -50,7 +50,7 @@ - + @@ -61,7 +61,7 @@ - + 0 @@ -72,14 +72,14 @@ - + 0 - + diff --git a/Tests/DependencyInjection/FrameworkExtensionTest.php b/Tests/DependencyInjection/FrameworkExtensionTest.php index 51b4ff152..73c33a3f5 100644 --- a/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -19,7 +19,6 @@ use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Cache\Adapter\ApcuAdapter; use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ChainAdapter; use Symfony\Component\Cache\Adapter\DoctrineAdapter; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Adapter\ProxyAdapter; @@ -1244,10 +1243,6 @@ private function assertCachePoolServiceDefinitionIsCreated(ContainerBuilder $con $this->assertSame(DoctrineAdapter::class, $parentDefinition->getClass()); break; case 'cache.app': - if (ChainAdapter::class === $parentDefinition->getClass()) { - break; - } - // no break case 'cache.adapter.filesystem': $this->assertSame(FilesystemAdapter::class, $parentDefinition->getClass()); break;