Skip to content

Commit

Permalink
Merge pull request #239 from jderusse/fix-compatibility
Browse files Browse the repository at this point in the history
Fix compatibility issue with symfony 5.0
  • Loading branch information
jderusse authored Nov 26, 2019
2 parents 5580074 + 07b46bc commit 566e390
Show file tree
Hide file tree
Showing 16 changed files with 167 additions and 47 deletions.
11 changes: 5 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ env:
global:
- PHPUNIT_FLAGS="-v"
- SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit"
- SYMFONY_PHPUNIT_VERSION="6.5"

matrix:
fast_finish: true
Expand All @@ -29,9 +28,11 @@ matrix:
# Test LTS versions. This makes sure we do not use Symfony packages with version greater
# than 2 or 3 respectively. Read more at https://github.com/symfony/lts
- php: 7.3
env: DEPENDENCIES="dunglas/symfony-lock:^3"
env: SYMFONY_REQUIRE="^3.0"
- php: 7.3
env: DEPENDENCIES="dunglas/symfony-lock:^4"
env: SYMFONY_REQUIRE="^4.0"
- php: 7.3
env: SYMFONY_REQUIRE="^5.0"

# Latest commit to master
- php: 7.3
Expand All @@ -44,11 +45,9 @@ matrix:
before_install:
- if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi
- if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; fi;
- if ! [ -v "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi;
- if ! [ -v "$SYMFONY_REQUIRE" ]; then composer global require symfony/flex; fi;

install:
# To be removed when this issue will be resolved: https://github.com/composer/composer/issues/5355
- if [[ "$COMPOSER_FLAGS" == *"--prefer-lowest"* ]]; then composer update --prefer-dist --no-interaction --prefer-stable --quiet; fi
- composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction
- ./vendor/bin/simple-phpunit install

Expand Down
12 changes: 10 additions & 2 deletions Listener/ExceptionListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Ekino\NewRelicBundle\NewRelic\NewRelicInteractorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelEvents;
Expand All @@ -38,9 +39,16 @@ public static function getSubscribedEvents(): array
];
}

public function onKernelException(GetResponseForExceptionEvent $event): void
/**
* @param GetResponseForExceptionEvent|ExceptionEvent $event
*/
public function onKernelException($event): void
{
$exception = $event->getException();
if (!$event instanceof GetResponseForExceptionEvent && !$event instanceof ExceptionEvent) {
throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ExceptionEvent::class) ? ExceptionEvent::class : GetResponseForExceptionEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}

$exception = \method_exists($event, 'getThrowable') ? $event->getThrowable() : $event->getException();
if (!$exception instanceof HttpExceptionInterface) {
$this->interactor->noticeThrowable($exception);
}
Expand Down
37 changes: 32 additions & 5 deletions Listener/RequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
use Ekino\NewRelicBundle\NewRelic\NewRelicInteractorInterface;
use Ekino\NewRelicBundle\TransactionNamingStrategy\TransactionNamingStrategyInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;

Expand Down Expand Up @@ -58,8 +58,15 @@ public static function getSubscribedEvents(): array
];
}

public function setApplicationName(GetResponseEvent $event): void
/**
* @param GetResponseEvent|ResponseEvent $event
*/
public function setApplicationName($event): void
{
if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}

if (!$this->isEventValid($event)) {
return;
}
Expand All @@ -80,8 +87,15 @@ public function setApplicationName(GetResponseEvent $event): void
}
}

public function setTransactionName(GetResponseEvent $event): void
/**
* @param GetResponseEvent|ResponseEvent $event
*/
public function setTransactionName($event): void
{
if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}

if (!$this->isEventValid($event)) {
return;
}
Expand All @@ -91,8 +105,15 @@ public function setTransactionName(GetResponseEvent $event): void
$this->interactor->setTransactionName($transactionName);
}

public function setIgnoreTransaction(GetResponseEvent $event): void
/**
* @param GetResponseEvent|ResponseEvent $event
*/
public function setIgnoreTransaction($event): void
{
if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}

if (!$this->isEventValid($event)) {
return;
}
Expand All @@ -109,9 +130,15 @@ public function setIgnoreTransaction(GetResponseEvent $event): void

/**
* Make sure we should consider this event. Example: make sure it is a master request.
*
* @param GetResponseEvent|ResponseEvent $event
*/
private function isEventValid(GetResponseEvent $event): bool
private function isEventValid($event): bool
{
if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}

return HttpKernelInterface::MASTER_REQUEST === $event->getRequestType();
}
}
10 changes: 9 additions & 1 deletion Listener/ResponseListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class ResponseListener implements EventSubscriberInterface
Expand Down Expand Up @@ -52,8 +53,15 @@ public static function getSubscribedEvents(): array
];
}

public function onKernelResponse(FilterResponseEvent $event): void
/**
* @param FilterResponseEvent|ResponseEvent $event
*/
public function onKernelResponse($event): void
{
if (!$event instanceof FilterResponseEvent && !$event instanceof ResponseEvent) {
throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : FilterResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}

if (!$event->isMasterRequest()) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/BundleInitializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
*/
class BundleInitializationTest extends BaseBundleTestCase
{
protected function setUp()
protected function setUp(): void
{
parent::setUp();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

class MonologHandlerPassTest extends AbstractCompilerPassTestCase
{
protected function registerCompilerPass(ContainerBuilder $container)
protected function registerCompilerPass(ContainerBuilder $container): void
{
$container->addCompilerPass(new MonologHandlerPass());
}
Expand Down
8 changes: 4 additions & 4 deletions Tests/DependencyInjection/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ public function testDefaults()
$config = $processor->processConfiguration(new Configuration(), []);

$this->assertEmpty($config['http']['ignored_routes']);
$this->assertInternalType('array', $config['http']['ignored_routes']);
$this->assertIsArray($config['http']['ignored_routes']);
$this->assertEmpty($config['http']['ignored_paths']);
$this->assertInternalType('array', $config['http']['ignored_paths']);
$this->assertIsArray($config['http']['ignored_paths']);
$this->assertEmpty($config['commands']['ignored_commands']);
$this->assertInternalType('array', $config['commands']['ignored_commands']);
$this->assertIsArray($config['commands']['ignored_commands']);
$this->assertEmpty($config['deployment_names']);
$this->assertInternalType('array', $config['deployment_names']);
$this->assertIsArray($config['deployment_names']);
}

public static function ignoredRoutesProvider()
Expand Down
4 changes: 2 additions & 2 deletions Tests/DependencyInjection/EkinoNewRelicExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@

class EkinoNewRelicExtensionTest extends AbstractExtensionTestCase
{
protected function getContainerExtensions()
protected function getContainerExtensions(): array
{
return [new EkinoNewRelicExtension()];
}

protected function setUp()
protected function setUp(): void
{
parent::setUp();

Expand Down
15 changes: 12 additions & 3 deletions Tests/Listener/DeprecationListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ class DeprecationListenerTest extends TestCase
public function testDeprecationIsReported()
{
$interactor = $this->getMockBuilder(NewRelicInteractorInterface::class)->getMock();
$interactor->expects($this->once())->method('noticeThrowable')->with($this->isInstanceOf(DeprecationException::class));
$interactor->expects($this->once())->method('noticeThrowable')->with(
$this->isInstanceOf(DeprecationException::class)
);

$listener = new DeprecationListener($interactor);

Expand Down Expand Up @@ -78,7 +80,7 @@ public function testInitialHandlerIsCalled()
$interactor = $this->getMockBuilder(NewRelicInteractorInterface::class)->getMock();
$interactor->expects($this->once())->method('noticeThrowable');

$handler = $this->createPartialMock(\stdClass::class, ['__invoke']);
$handler = $this->createPartialMock(DummyHandler::class, ['__invoke']);
$handler->expects($this->once())->method('__invoke');

$listener = new DeprecationListener($interactor);
Expand Down Expand Up @@ -114,7 +116,7 @@ public function testUnregisterRestorePreviousHandler()
{
$interactor = $this->getMockBuilder(NewRelicInteractorInterface::class)->getMock();

$handler = $this->createPartialMock(\stdClass::class, ['__invoke']);
$handler = $this->createPartialMock(DummyHandler::class, ['__invoke']);
$handler->expects($this->once())->method('__invoke');

$listener = new DeprecationListener($interactor);
Expand All @@ -129,3 +131,10 @@ public function testUnregisterRestorePreviousHandler()
}
}
}

class DummyHandler
{
public function __invoke()
{
}
}
60 changes: 60 additions & 0 deletions Tests/Listener/ExceptionListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

/*
* This file is part of Ekino New Relic bundle.
*
* (c) Ekino - Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Ekino\NewRelicBundle\Tests\Listener;

use Ekino\NewRelicBundle\Listener\ExceptionListener;
use Ekino\NewRelicBundle\NewRelic\NewRelicInteractorInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class ExceptionListenerTest extends TestCase
{
public function testOnKernelException()
{
$exception = new \Exception('Boom');

$interactor = $this->getMockBuilder(NewRelicInteractorInterface::class)->getMock();
$interactor->expects($this->once())->method('noticeThrowable')->with($exception);

$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();

$eventClass = \class_exists(ExceptionEvent::class) ? ExceptionEvent::class : GetResponseForExceptionEvent::class;
$event = new $eventClass($kernel, $request, HttpKernelInterface::SUB_REQUEST, $exception);

$listener = new ExceptionListener($interactor);
$listener->onKernelException($event);
}

public function testOnKernelExceptionWithHttp()
{
$exception = new BadRequestHttpException('Boom');

$interactor = $this->getMockBuilder(NewRelicInteractorInterface::class)->getMock();
$interactor->expects($this->never())->method('noticeThrowable');

$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();

$eventClass = \class_exists(ExceptionEvent::class) ? ExceptionEvent::class : GetResponseForExceptionEvent::class;
$event = new $eventClass($kernel, $request, HttpKernelInterface::SUB_REQUEST, $exception);

$listener = new ExceptionListener($interactor);
$listener->onKernelException($event);
}
}
24 changes: 14 additions & 10 deletions Tests/Listener/RequestListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
use Ekino\NewRelicBundle\TransactionNamingStrategy\TransactionNamingStrategyInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class RequestListenerTest extends TestCase
Expand All @@ -32,9 +34,9 @@ public function testSubRequest()
$namingStrategy = $this->getMockBuilder(TransactionNamingStrategyInterface::class)->getMock();

$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST);
$eventClass = \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class;
$event = new $eventClass($kernel, new Request(), HttpKernelInterface::SUB_REQUEST, new Response());

$listener = new RequestListener(new Config('App name', 'Token'), $interactor, [], [], $namingStrategy);
$listener->setApplicationName($event);
Expand All @@ -51,9 +53,9 @@ public function testMasterRequest()
$namingStrategy->expects($this->once())->method('getTransactionName')->willReturn('foobar');

$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$eventClass = \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class;
$event = new $eventClass($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, new Response());

$listener = new RequestListener(new Config('App name', 'Token'), $interactor, [], [], $namingStrategy);
$listener->setTransactionName($event);
Expand All @@ -69,7 +71,8 @@ public function testPathIsIgnored()
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request([], [], [], [], [], ['REQUEST_URI' => '/ignored_path']);

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$eventClass = \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class;
$event = new $eventClass($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new Response());

$listener = new RequestListener(new Config('App name', 'Token'), $interactor, [], ['/ignored_path'], $namingStrategy);
$listener->setIgnoreTransaction($event);
Expand All @@ -85,7 +88,8 @@ public function testRouteIsIgnored()
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request([], [], ['_route' => 'ignored_route']);

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$eventClass = \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class;
$event = new $eventClass($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new Response());

$listener = new RequestListener(new Config('App name', 'Token'), $interactor, ['ignored_route'], [], $namingStrategy);
$listener->setIgnoreTransaction($event);
Expand All @@ -99,9 +103,9 @@ public function testSymfonyCacheEnabled()
$namingStrategy = $this->getMockBuilder(TransactionNamingStrategyInterface::class)->getMock();

$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$eventClass = \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class;
$event = new $eventClass($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, new Response());

$listener = new RequestListener(new Config('App name', 'Token'), $interactor, [], [], $namingStrategy, true);
$listener->setApplicationName($event);
Expand All @@ -115,9 +119,9 @@ public function testSymfonyCacheDisabled()
$namingStrategy = $this->getMockBuilder(TransactionNamingStrategyInterface::class)->getMock();

$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$eventClass = \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class;
$event = new $eventClass($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, new Response());

$listener = new RequestListener(new Config('App name', 'Token'), $interactor, [], [], $namingStrategy, false);
$listener->setApplicationName($event);
Expand Down
Loading

0 comments on commit 566e390

Please sign in to comment.