8000 Merge branch '6.4' into 7.1 · symfony/symfony@65d3c20 · GitHub
[go: up one dir, main page]

Skip to content

Commit 65d3c20

Browse files
committed
Merge branch '6.4' into 7.1
* 6.4: relax assertions on generated hashes [Messenger] ensure exception on rollback does not hide previous exception require the writer to implement getFormats() in the translation:extract don't require fake notifier transports to be installed as non-dev dependencies Remove 5.4 branch from PR template [Scheduler] Fix optional count variable in testGetNextRunDates
2 parents 05ba52b + be52235 commit 65d3c20

File tree

13 files changed

+101
-32
lines changed
  • Tests/Functional
  • Component
  • 13 files changed

    +101
    -32
    lines changed

    .github/PULL_REQUEST_TEMPLATE.md

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -1,6 +1,6 @@
    11
    | Q | A
    22
    | ------------- | ---
    3-
    | Branch? | 7.3 for features / 5.4, 6.4, 7.1, and 7.2 for bug fixes <!-- see below -->
    3+
    | Branch? | 7.3 for features / 6.4, 7.1, and 7.2 for bug fixes <!-- see below -->
    44
    | Bug fix? | yes/no
    55
    | New feature? | yes/no <!-- please update src/**/CHANGELOG.md files -->
    66
    | Deprecations? | yes/no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->

    src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php

    Lines changed: 10 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -27,22 +27,30 @@ class DoctrineTransactionMiddleware extends AbstractDoctrineMiddleware
    2727
    protected function handleForManager(EntityManagerInterface $entityManager, Envelope $envelope, StackInterface $stack): Envelope
    2828
    {
    2929
    $entityManager->getConnection()->beginTransaction();
    30+
    31+
    $success = false;
    3032
    try {
    3133
    $envelope = $stack->next()->handle($envelope, $stack);
    3234
    $entityManager->flush();
    3335
    $entityManager->getConnection()->commit();
    3436

    37+
    $success = true;
    38+
    3539
    return $envelope;
    3640
    } catch (\Throwable $exception) {
    37-
    $entityManager->getConnection()->rollBack();
    38-
    3941
    if ($exception instanceof HandlerFailedException) {
    4042
    // Remove all HandledStamp from the envelope so the retry will execute all handlers again.
    4143
    // When a handler fails, the queries of allegedly successful previous handlers just got rolled back.
    4244
    throw new HandlerFailedException($exception->getEnvelope()->withoutAll(HandledStamp::class), $exception->getWrappedExceptions());
    4345
    }
    4446

    4547
    throw $exception;
    48+
    } finally {
    49+
    $connection = $entityManager->getConnection();
    50+
    51+
    if (!$success && $connection->isTransactionActive()) {
    52+
    $connection->rollBack();
    53+
    }
    4654
    }
    4755
    }
    4856
    }

    src/Symfony/Bridge/Doctrine/Tests/Messenger/DoctrineTransactionMiddlewareTest.php

    Lines changed: 24 additions & 6 deletions
    Original file line numberDiff line numberDiff line change
    @@ -56,19 +56,37 @@ public function testMiddlewareWrapsInTransactionAndFlushes()
    5656

    5757
    public function testTransactionIsRolledBackOnException()
    5858
    {
    59-
    $this->connection->expects($this->once())
    60-
    ->method('beginTransaction')
    61-
    ;
    62-
    $this->connection->expects($this->once())
    63-
    ->method('rollBack')
    64-
    ;
    59+
    $this->connection->expects($this->once())->method('beginTransaction');
    60+
    $this->connection->expects($this->once())->method('isTransactionActive')->willReturn(true);
    61+
    $this->connection->expects($this->once())->method('rollBack');
    6562

    6663
    $this->expectException(\RuntimeException::class);
    6764
    $this->expectExceptionMessage('Thrown from next middleware.');
    6865

    6966
    $this->middleware->handle(new Envelope(new \stdClass()), $this->getThrowingStackMock());
    7067
    }
    7168

    69+
    public function testExceptionInRollBackDoesNotHidePreviousException()
    70+
    {
    71+
    $this->connection->expects($this->once())->method('beginTransaction');
    72+
    $this->connection->expects($this->once())->method('isTransactionActive')->willReturn(true);
    73+
    $this->connection->expects($this->once())->method('rollBack')->willThrowException(new \RuntimeException('Thrown from rollBack.'));
    74+
    75+
    try {
    76+
    $this->middleware->handle(new Envelope(new \stdClass()), $this->getThrowingStackMock());
    77+
    } catch (\Throwable $exception) {
    78+
    }
    79+
    80+
    self::assertNotNull($exception);
    81+
    self::assertInstanceOf(\RuntimeException::class, $exception);
    82+
    self::assertSame('Thrown from rollBack.', $exception->getMessage());
    83+
    84+
    $previous = $exception->getPrevious();
    85+
    self::assertNotNull($previous);
    86+
    self::assertInstanceOf(\RuntimeException::class, $previous);
    87+
    self::assertSame('Thrown from next middleware.', $previous->getMessage());
    88+
    }
    89+
    7290
    public function testInvalidEntityManagerThrowsException()
    7391
    {
    7492
    $managerRegistry = $this->createMock(ManagerRegistry::class);

    src/Symfony/Bridge/Twig/Tests/Extension/HttpKernelExtensionTest.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -80,7 +80,7 @@ public function testGenerateFragmentUri()
    8080
    ]);
    8181
    $twig->addRuntimeLoader($loader);
    8282

    83-
    $this->assertSame('/_fragment?_hash=XCg0hX8QzSwik8Xuu9aMXhoCeI4oJOob7lUVacyOtyY%3D&amp;_path=template%3Dfoo.html.twig%26_format%3Dhtml%26_locale%3Den%26_controller%3DSymfony%255CBundle%255CFrameworkBundle%255CController%255CTemplateController%253A%253AtemplateAction', $twig->render('index'));
    83+
    $this->assertMatchesRegularExpression('#/_fragment\?_hash=.+&amp;_path=template%3Dfoo.html.twig%26_format%3Dhtml%26_locale%3Den%26_controller%3DSymfony%255CBundle%255CFrameworkBundle%255CController%255CTemplateController%253A%253AtemplateAction$#', $twig->render('index'));
    8484
    }
    8585

    8686
    protected function getFragmentHandler($returnOrException): FragmentHandler

    src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php

    Lines changed: 4 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -62,6 +62,10 @@ public function __construct(
    6262
    private array $enabledLocales = [],
    6363
    ) {
    6464
    parent::__construct();
    65+
    66+
    if (!method_exists($writer, 'getFormats')) {
    67+
    throw new \InvalidArgumentException(sprintf('The writer class "%s" does not implement the "getFormats()" method.', $writer::class));
    68+
    }
    6569
    }
    6670

    6771
    protected function configure(): void
    Lines changed: 31 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,31 @@
    1+
    <?php
    2+
    3+
    /*
    4+
    * This file is part of the Symfony package.
    5+
    *
    6+
    * (c) Fabien Potencier <fabien@symfony.com>
    7+
    *
    8+
    * For the full copyright and license information, please view the LICENSE
    9+
    * file that was distributed with this source code.
    10+
    */
    11+
    12+
    namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
    13+
    14+
    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    15+
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    16+
    17+
    class TranslationUpdateCommandPass implements CompilerPassInterface
    18+
    {
    19+
    public function process(ContainerBuilder $container): void
    20+
    {
    21+
    if (!$container->hasDefinition('console.command.translation_extract')) {
    22+
    return;
    23+
    }
    24+
    25+
    $translationWriterClass = $container->getParameterBag()->resolveValue($container->findDefinition('translation.writer')->getClass());
    26+
    27+
    if (!method_exists($translationWriterClass, 'getFormats')) {
    28+
    $container->removeDefinition('console.command.translation_extract');
    29+
    }
    30+
    }
    31+
    }

    src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

    Lines changed: 16 additions & 10 deletions
    Original file line numberDiff line numberDiff line change
    @@ -120,6 +120,8 @@
    120120
    use Symfony\Component\Mime\MimeTypeGuesserInterface;
    121121
    use Symfony\Component\Mime\MimeTypes;
    122122
    use Symfony\Component\Notifier\Bridge as NotifierBridge;
    123+
    use Symfony\Component\Notifier\Bridge\FakeChat\FakeChatTransportFactory;
    124+
    use Symfony\Component\Notifier\Bridge\FakeSms\FakeSmsTransportFactory;
    123125
    use Symfony\Component\Notifier\ChatterInterface;
    124126
    use Symfony\Component\Notifier\Notifier;
    125127
    use Symfony\Component\Notifier\Recipient\Recipient;
    @@ -2762,8 +2764,6 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $
    27622764
    NotifierBridge\Engagespot\EngagespotTransportFactory::class => 'notifier.transport_factory.engagespot',
    27632765
    NotifierBridge\Esendex\EsendexTransportFactory::class => 'notifier.transport_factory.esendex',
    27642766
    NotifierBridge\Expo\ExpoTransportFactory::class => 'notifier.transport_factory.expo',
    2765-
    NotifierBridge\FakeChat\FakeChatTransportFactory::class => 'notifier.transport_factory.fake-chat',
    2766-
    NotifierBridge\FakeSms\FakeSmsTransportFactory::class => 'notifier.transport_factory.fake-sms',
    27672767
    NotifierBridge\Firebase\FirebaseTransportFactory::class => 'notifier.transport_factory.firebase',
    27682768
    NotifierBridge\FortySixElks\FortySixElksTransportFactory::class => 'notifier.transport_factory.forty-six-elks',
    27692769
    NotifierBridge\FreeMobile\FreeMobileTransportFactory::class => 'notifier.transport_factory.free-mobile',
    @@ -2847,20 +2847,26 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $
    28472847
    $container->removeDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]);
    28482848
    }
    28492849

    2850-
    if (ContainerBuilder::willBeAvailable('symfony/fake-chat-notifier', NotifierBridge\FakeChat\FakeChatTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) {
    2851-
    $container->getDefinition($classToServices[NotifierBridge\FakeChat\FakeChatTransportFactory::class])
    2852-
    ->replaceArgument(0, new Reference('mailer'))
    2853-
    ->replaceArgument(1, new Reference('logger'))
    2850+
    // don't use ContainerBuilder::willBeAvailable() as these are not needed in production
    2851+
    if (class_exists(FakeChatTransportFactory::class)) {
    2852+
    $container->getDefinition('notifier.transport_factory.fake-chat')
    2853+
    ->replaceArgument(0, new Reference('mailer', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
    2854+
    ->replaceArgument(1, new Reference('logger', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
    28542855
    ->addArgument(new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
    28552856
    ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
    2857+
    } else {
    2858+
    $container->removeDefinition('notifier.transport_factory.fake-chat');
    28562859
    }
    28572860

    2858-
    if (ContainerBuilder::willBeAvailable('symfony/fake-sms-notifier', NotifierBridge\FakeSms\FakeSmsTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) {
    2859-
    $container->getDefinition($classToServices[NotifierBridge\FakeSms\FakeSmsTransportFactory::class])
    2860-
    ->replaceArgument(0, new Reference('mailer'))
    2861-
    ->replaceArgument(1, new Reference('logger'))
    2861+
    // don't use ContainerBuilder::willBeAvailable() as these are not needed in production
    2862+
    if (class_exists(FakeSmsTransportFactory::class)) {
    2863+
    $container->getDefinition('notifier.transport_factory.fake-sms')
    2864+
    ->replaceArgument(0, new Reference('mailer', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
    2865+
    ->replaceArgument(1, new Reference('logger', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
    28622866
    ->addArgument(new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
    28632867
    ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
    2868+
    } else {
    2869+
    $container->removeDefinition('notifier.transport_factory.fake-sms');
    28642870
    }
    28652871

    28662872
    if (ContainerBuilder::willBeAvailable('symfony/bluesky-notifier', NotifierBridge\Bluesky\BlueskyTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier'])) {

    src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

    Lines changed: 2 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -19,6 +19,7 @@
    1919
    use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RemoveUnusedSessionMarshallingHandlerPass;
    2020
    use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass;
    2121
    use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass;
    22+
    use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationUpdateCommandPass;
    2223
    use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass;
    2324
    use Symfony\Bundle\FrameworkBundle\DependencyInjection\VirtualRequestStackPass;
    2425
    use Symfony\Component\Cache\Adapter\ApcuAdapter;
    @@ -181,6 +182,7 @@ public function build(ContainerBuilder $container): void
    181182
    // must be registered after MonologBundle's LoggerChannelPass
    182183
    $container->addCompilerPass(new ErrorLoggerCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
    183184
    $container->addCompilerPass(new VirtualRequestStackPass());
    185+
    $container->addCompilerPass(new TranslationUpdateCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
    184186

    185187
    if ($container->getParameter('kernel.debug')) {
    186188
    $container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 2);

    src/Symfony/Bundle/FrameworkBundle/Tests/Functional/FragmentTest.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -50,6 +50,6 @@ public function testGenerateFragmentUri()
    5050
    $client = self::createClient(['test_case' => 'Fragment', 'root_config' => 'config.yml', 'debug' => true]);
    5151
    $client->request('GET', '/fragment_uri');
    5252

    53-
    $this->assertSame('/_fragment?_hash=CCRGN2D%2FoAJbeGz%2F%2FdoH3bNSPwLCrmwC1zAYCGIKJ0E%3D&_path=_format%3Dhtml%26_locale%3Den%26_controller%3DSymfony%255CBundle%255CFrameworkBundle%255CTests%255CFunctional%255CBundle%255CTestBundle%255CController%255CFragmentController%253A%253AindexAction', $client->getResponse()->getContent());
    53+
    $this->assertMatchesRegularExpression('#/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Den%26_controller%3DSymfony%255CBundle%255CFrameworkBundle%255CTests%255CFunctional%255CBundle%255CTestBundle%255CController%255CFragmentController%253A%253AindexAction$#', $client->getResponse()->getContent());
    5454
    }
    5555
    }

    src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php

    Lines changed: 4 additions & 4 deletions
    Original file line numberDiff line numberDiff line change
    @@ -60,8 +60,8 @@ public function testRenderControllerReference()
    6060
    $reference = new ControllerReference('main_controller', [], []);
    6161
    $altReference = new ControllerReference('alt_controller', [], []);
    6262

    63-
    $this->assertEquals(
    64-
    '<esi:include src="/_fragment?_hash=Jz1P8NErmhKTeI6onI1EdAXTB85359MY3RIk5mSJ60w%3D&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" alt="/_fragment?_hash=iPJEdRoUpGrM1ztqByiorpfMPtiW%2FOWwdH1DBUXHhEc%3D&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dalt_controller" />',
    63+
    $this->assertMatchesRegularExpression(
    64+
    '#^<esi:include src="/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" alt="/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dalt_controller" />$#',
    6565
    $strategy->render($reference, $request, ['alt' => $altReference])->getContent()
    6666
    );
    6767
    }
    @@ -78,8 +78,8 @@ public function testRenderControllerReferenceWithAbsoluteUri()
    7878
    $reference = new ControllerReference('main_controller', [], []);
    7979
    $altReference = new ControllerReference('alt_controller', [], []);
    8080

    81-
    $this->assertSame(
    82-
    '<esi:include src="http://localhost/_fragment?_hash=Jz1P8NErmhKTeI6onI1EdAXTB85359MY3RIk5mSJ60w%3D&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" alt="http://localhost/_fragment?_hash=iPJEdRoUpGrM1ztqByiorpfMPtiW%2FOWwdH1DBUXHhEc%3D&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dalt_controller" />',
    81+
    $this->assertMatchesRegularExpression(
    82+
    '#^<esi:include src="http://localhost/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" alt="http://localhost/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dalt_controller" />$#',
    8383
    $strategy->render($reference, $request, ['alt' => $altReference, 'absolute_uri' => true])->getContent()
    8484
    );
    8585
    }

    src/Symfony/Component/HttpKernel/Tests/Fragment/HIncludeFragmentRendererTest.php

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -32,7 +32,7 @@ public function testRenderWithControllerAndSigner()
    3232
    {
    3333
    $strategy = new HIncludeFragmentRenderer(null, new UriSigner('foo'));
    3434

    35-
    $this->assertEquals('<hx:include src="/_fragment?_hash=BP%2BOzCD5MRUI%2BHJpgPDOmoju00FnzLhP3TGcSHbbBLs%3D&amp;_path=_format%3Dhtml%26_locale%3Den%26_controller%3Dmain_controller"></hx:include>', $strategy->render(new ControllerReference('main_controller', [], []), Request::create('/'))->getContent());
    35+
    $this->assertMatchesRegularExpression('#^<hx:include src="/_fragment\?_hash=.+&amp;_path=_format%3Dhtml%26_locale%3Den%26_controller%3Dmain_controller"></hx:include>$#', $strategy->render(new ControllerReference('main_controller', [], []), Request::create('/'))->getContent());
    3636
    }
    3737

    3838
    public function testRenderWithUri()

    src/Symfony/Component/HttpKernel/Tests/Fragment/SsiFragmentRendererTest.php

    Lines changed: 4 additions & 4 deletions
    Original file line numberDiff line numberDiff line change
    @@ -51,8 +51,8 @@ public function testRenderControllerReference()
    5151
    $reference = new ControllerReference('main_controller', [], []);
    5252
    $altReference = new ControllerReference('alt_controller', [], []);
    5353

    54-
    $this->assertEquals(
    55-
    '<!--#include virtual="/_fragment?_hash=Jz1P8NErmhKTeI6onI1EdAXTB85359MY3RIk5mSJ60w%3D&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" -->',
    54+
    $this->assertMatchesRegularExpression(
    55+
    '{^<!--#include virtual="/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" -->$}',
    5656
    $strategy->render($reference, $request, ['alt' => $altReference])->getContent()
    5757
    );
    5858
    }
    @@ -69,8 +69,8 @@ public function testRenderControllerReferenceWithAbsoluteUri()
    6969
    $reference = new ControllerReference('main_controller', [], []);
    7070
    $altReference = new ControllerReference('alt_controller', [], []);
    7171

    72-
    $this->assertSame(
    73-
    '<!--#include virtual="http://localhost/_fragment?_hash=Jz1P8NErmhKTeI6onI1EdAXTB85359MY3RIk5mSJ60w%3D&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" -->',
    72+
    $this->assertMatchesRegularExpression(
    73+
    '{^<!--#include virtual="http://localhost/_fragment\?_hash=.+&_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3Dmain_controller" -->$}',
    7474
    $strategy->render($reference, $request, ['alt' => $altReference, 'absolute_uri' => true])->getContent()
    7575
    );
    7676
    }

    src/Symfony/Component/Scheduler/Tests/Trigger/PeriodicalTriggerTest.php

    Lines changed: 2 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -105,9 +105,9 @@ public static function provideForToString()
    105105
    /**
    106106
    * @dataProvider providerGetNextRunDates
    107107
    */
    108-
    public function testGetNextRunDates(\DateTimeImmutable $from, TriggerInterface $trigger, array $expected, int $count = 0)
    108+
    public function testGetNextRunDates(\DateTimeImmutable $from, TriggerInterface $trigger, array $expected, int $count)
    109109
    {
    110-
    $this->assertEquals($expected, $this->getNextRunDates($from, $trigger, $count ?? \count($expected)));
    110+
    $this->assertEquals($expected, $this->getNextRunDates($from, $trigger, $count));
    111111
    }
    112112

    113113
    public static function providerGetNextRunDates(): iterable

    0 commit comments

    Comments
     (0)
    0