diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php index 0e7444a291271..e0f28ae42eaad 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php @@ -36,7 +36,7 @@ public function __construct(ManagerRegistry $managerRegistry, ?string $entityMan /** * {@inheritdoc} */ - public function handle(Envelope $envelope, StackInterface $stack): void + public function handle(Envelope $envelope, StackInterface $stack): Envelope { $entityManager = $this->managerRegistry->getManager($this->entityManagerName); @@ -46,9 +46,11 @@ public function handle(Envelope $envelope, StackInterface $stack): void $entityManager->getConnection()->beginTransaction(); try { - $stack->next()->handle($envelope, $stack); + $envelope = $stack->next()->handle($envelope, $stack); $entityManager->flush(); $entityManager->getConnection()->commit(); + + return $envelope; } catch (\Throwable $exception) { $entityManager->getConnection()->rollBack(); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Messenger/DummyMiddleware.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Messenger/DummyMiddleware.php new file mode 100644 index 0000000000000..2c4ee61d65026 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Messenger/DummyMiddleware.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Messenger; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\DBAL\Connection; +use Doctrine\ORM\EntityManagerInterface; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware; +use Symfony\Bridge\Doctrine\Tests\Fixtures\Messenger\DummyMiddleware; +use Symfony\Bridge\Doctrine\Tests\Fixtures\Messenger\ThrowingMiddleware; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Middleware\StackInterface; + +class DoctrineTransactionMiddlewareTest extends TestCase +{ + private $connection; + private $entityManager; + private $middleware; + private $stack; + + public function setUp() + { + $this->connection = $this->createMock(Connection::class); + + $this->entityManager = $this->createMock(EntityManagerInterface::class); + $this->entityManager->method('getConnection')->willReturn($this->connection); + + $managerRegistry = $this->createMock(ManagerRegistry::class); + $managerRegistry->method('getManager')->willReturn($this->entityManager); + + $this->middleware = new DoctrineTransactionMiddleware($managerRegistry, null); + + $this->stack = $this->createMock(StackInterface::class); + } + + public function testMiddlewareWrapsInTransactionAndFlushes() + { + $this->connection->expects($this->once()) + ->method('beginTransaction') + ; + $this->connection->expects($this->once()) + ->method('commit') + ; + $this->entityManager->expects($this->once()) + ->method('flush') + ; + $this->stack + ->expects($this->once()) + ->method('next') + ->willReturn(new DummyMiddleware()) + ; + + $this->middleware->handle(new Envelope(new \stdClass()), $this->stack); + } + + public function testTransactionIsRolledBackOnException() + { + $this->connection->expects($this->once()) + ->method('beginTransaction') + ; + $this->connection->expects($this->once()) + ->method('rollBack') + ; + $this->stack + ->expects($this->once()) + ->method('next') + ->willReturn(new ThrowingMiddleware()) + ; + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Thrown from middleware.'); + + $this->middleware->handle(new Envelope(new \stdClass()), $this->stack); + } +} diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index cc344b2039ed7..bc828b43e21b6 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -29,6 +29,7 @@ "symfony/dependency-injection": "~3.4|~4.0", "symfony/form": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0", + "symfony/messenger": "~4.2", "symfony/property-access": "~3.4|~4.0", "symfony/property-info": "~3.4|~4.0", "symfony/proxy-manager-bridge": "~3.4|~4.0",