diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index e0052636..103f88c4 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -18,6 +18,8 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 + with: + php-version: '8.0' - name: Install dependencies run: composer update --no-progress --no-interaction --prefer-dist @@ -50,9 +52,11 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 + with: + php-version: '8.0' - name: Install dependencies run: composer update --no-progress --no-interaction --prefer-dist - name: Run script - run: composer psalm + run: composer psalm -- --php-version=8.0 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 5859ede8..8ff173ad 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -27,9 +27,16 @@ jobs: - 3.4.* - 4.4.* - 5.* + - 6.* dependencies: - highest exclude: + - php: '7.2' + symfony-version: 6.* + - php: '7.3' + symfony-version: 6.* + - php: '7.4' + symfony-version: 6.* - php: '8.0' symfony-version: 3.4.* - php: '8.1' @@ -44,6 +51,9 @@ jobs: - php: '7.2' symfony-version: 5.* dependencies: lowest + - php: '8.0' + symfony-version: 6.* + dependencies: lowest steps: - name: Checkout @@ -61,6 +71,9 @@ jobs: - name: Setup Problem Matchers for PHPUnit run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + - name: Remove PHP-CS-Fixer + run: composer remove --dev friendsofphp/php-cs-fixer --no-update + - name: Remove Symfony Messenger run: composer remove --dev symfony/messenger --no-update if: matrix.symfony-version == '3.4.*' diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d6cf0d..9910678a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Add support for Symfony 6 (#566) - Fix fatal errors logged twice on Symfony `3.4` (#570) ## 4.2.4 (2021-10-20) diff --git a/composer.json b/composer.json index c6570f89..11a3dc81 100644 --- a/composer.json +++ b/composer.json @@ -24,18 +24,18 @@ "php-http/discovery": "^1.11", "sentry/sdk": "^3.1", "symfony/cache-contracts": "^1.1||^2.4", - "symfony/config": "^3.4.44||^4.4.20||^5.0.11", - "symfony/console": "^3.4.44||^4.4.20||^5.0.11", - "symfony/dependency-injection": "^3.4.44||^4.4.20||^5.0.11", - "symfony/event-dispatcher": "^3.4.44||^4.4.20||^5.0.11", - "symfony/http-kernel": "^3.4.44||^4.4.20||^5.0.11", + "symfony/config": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/console": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/dependency-injection": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/event-dispatcher": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/http-kernel": "^3.4.44||^4.4.20||^5.0.11||^6.0", "symfony/polyfill-php80": "^1.22", "symfony/psr-http-message-bridge": "^1.2||^2.0", - "symfony/security-core": "^3.4.44||^4.4.20||^5.0.11" + "symfony/security-core": "^3.4.44||^4.4.20||^5.0.11||^6.0" }, "require-dev": { "doctrine/dbal": "^2.13||^3.0", - "doctrine/doctrine-bundle": "^1.12||^2.0", + "doctrine/doctrine-bundle": "^1.12||^2.5", "friendsofphp/php-cs-fixer": "^2.18", "jangregor/phpstan-prophecy": "^0.8", "monolog/monolog": "^1.3||^2.0", @@ -44,16 +44,17 @@ "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5.14||^9.0", - "symfony/browser-kit": "^3.4.44||^4.4.20||^5.0.11", - "symfony/cache": "^3.4.44||^4.4.20||^5.0.11", - "symfony/dom-crawler": "^3.4.44||^4.4.20||^5.0.11", - "symfony/framework-bundle": "^3.4.44||^4.4.20||^5.0.11", - "symfony/messenger": "^4.4.20||^5.0.11", + "phpunit/phpunit": "^8.5.14||^9.3.9", + "symfony/browser-kit": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/cache": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/dom-crawler": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/framework-bundle": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/messenger": "^4.4.20||^5.0.11||^6.0", "symfony/monolog-bundle": "^3.4", - "symfony/phpunit-bridge": "^5.2.6", - "symfony/twig-bundle": "^3.4.44||^4.4.20||^5.0.11", - "symfony/yaml": "^3.4.44||^4.4.20||^5.0.11", + "symfony/phpunit-bridge": "^5.2.6||^6.0", + "symfony/process": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/twig-bundle": "^3.4.44||^4.4.20||^5.0.11||^6.0", + "symfony/yaml": "^3.4.44||^4.4.20||^5.0.11||^6.0", "vimeo/psalm": "^4.3" }, "suggest": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 596517e1..8b1503d9 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15,11 +15,26 @@ parameters: count: 1 path: src/DependencyInjection/SentryExtension.php + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" + count: 1 + path: src/EventListener/AbstractTracingRequestListener.php + - message: "#^Else branch is unreachable because previous condition is always true\\.$#" count: 1 path: src/EventListener/ErrorListener.php + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" + count: 1 + path: src/EventListener/RequestListener.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" + count: 1 + path: src/EventListener/SubRequestListener.php + - message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverConnection\\:\\:errorInfo\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -100,6 +115,11 @@ parameters: count: 1 path: tests/EventListener/MessengerListenerTest.php + - + message: "#^Call to function method_exists\\(\\) with \\$this\\(Sentry\\\\SentryBundle\\\\Tests\\\\EventListener\\\\AuthenticatedTokenStub\\) and 'setAuthenticated' will always evaluate to false\\.$#" + count: 1 + path: tests/EventListener/RequestListenerTest.php + - message: "#^Instantiated class Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\FilterControllerEvent not found\\.$#" count: 3 @@ -107,7 +127,7 @@ parameters: - message: "#^Instantiated class Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\GetResponseEvent not found\\.$#" - count: 8 + count: 9 path: tests/EventListener/RequestListenerTest.php - @@ -120,6 +140,11 @@ parameters: count: 1 path: tests/EventListener/RequestListenerTest.php + - + message: "#^Parameter \\#1 \\$user of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\AbstractToken\\:\\:setUser\\(\\) expects Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface, string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface given\\.$#" + count: 1 + path: tests/EventListener/RequestListenerTest.php + - message: "#^Parameter \\$controllerEvent of method Sentry\\\\SentryBundle\\\\Tests\\\\EventListener\\\\RequestListenerTest\\:\\:testHandleKernelControllerEvent\\(\\) has invalid typehint type Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\FilterControllerEvent\\.$#" count: 1 @@ -130,6 +155,11 @@ parameters: count: 1 path: tests/EventListener/RequestListenerTest.php + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" + count: 1 + path: tests/EventListener/SubRequestListenerTest.php + - message: "#^Instantiated class Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\GetResponseEvent not found\\.$#" count: 2 @@ -170,11 +200,6 @@ parameters: count: 1 path: tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php - - - message: "#^Call to method PHPUnit\\\\Framework\\\\Assert\\:\\:assertSame\\(\\) with array\\(Symfony\\\\Component\\\\Cache\\\\CacheItem\\) and iterable\\&Traversable will always evaluate to false\\.$#" - count: 1 - path: tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php - - message: "#^Parameter \\#1 \\$decoratedAdapter of method Sentry\\\\SentryBundle\\\\Tests\\\\Tracing\\\\Cache\\\\AbstractTraceableCacheAdapterTest\\\\:\\:createCacheAdapter\\(\\) expects TDecoratedCacheAdapter of Symfony\\\\Component\\\\Cache\\\\Adapter\\\\AdapterInterface, PHPUnit\\\\Framework\\\\MockObject\\\\MockObject&Sentry\\\\SentryBundle\\\\Tests\\\\Tracing\\\\Cache\\\\CacheInterface given\\.$#" count: 2 diff --git a/phpstan.neon b/phpstan.neon index cabfaeda..5eabf3b3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,6 +14,7 @@ parameters: - src/Tracing/Doctrine/DBAL/TracingDriverForV2.php - tests/End2End/App - tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php + - tests/EventListener/Fixtures/UserWithoutIdentifierStub.php dynamicConstantNames: - Symfony\Component\HttpKernel\Kernel::VERSION - Symfony\Component\HttpKernel\Kernel::VERSION_ID diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 07b7c6af..8b53fba0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + FatalErrorException @@ -13,11 +13,37 @@ public function __construct(HubInterface $hub, bool $captureErrors = true) + + + $event instanceof ExceptionEvent + + + getException + + + + + isMasterRequest + + + + + iterable + + ExceptionConverterDriver + + + $this->decoratedDriver->getSchemaManager($conn, $platform) + + + AbstractSchemaManager<T> + + $this->decoratedStatement diff --git a/src/EventListener/ErrorListener.php b/src/EventListener/ErrorListener.php index 088c33c7..dc3e3776 100644 --- a/src/EventListener/ErrorListener.php +++ b/src/EventListener/ErrorListener.php @@ -34,7 +34,6 @@ public function __construct(HubInterface $hub) */ public function handleExceptionEvent(ErrorListenerExceptionEvent $event): void { - /** @psalm-suppress RedundantCondition */ if ($event instanceof ExceptionEvent) { $this->hub->captureException($event->getThrowable()); } else { diff --git a/src/EventListener/RequestListener.php b/src/EventListener/RequestListener.php index b373fa90..a639f302 100644 --- a/src/EventListener/RequestListener.php +++ b/src/EventListener/RequestListener.php @@ -8,6 +8,7 @@ use Sentry\State\Scope; use Sentry\UserDataBag; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\User\UserInterface; /** @@ -67,7 +68,7 @@ public function handleKernelRequestEvent(RequestListenerRequestEvent $event): vo $token = $this->tokenStorage->getToken(); } - if (null !== $token && $token->isAuthenticated() && null !== $token->getUser()) { + if ($this->isTokenAuthenticated($token)) { $userData->setUsername($this->getUsername($token->getUser())); } @@ -124,4 +125,17 @@ private function getUsername($user): ?string return null; } + + private function isTokenAuthenticated(?TokenInterface $token): bool + { + if (null === $token) { + return false; + } + + if (method_exists($token, 'isAuthenticated') && !$token->isAuthenticated(false)) { + return false; + } + + return null !== $token->getUser(); + } } diff --git a/src/Tracing/Cache/TraceableCacheAdapterTrait.php b/src/Tracing/Cache/TraceableCacheAdapterTrait.php index cb0d62ed..458b2221 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterTrait.php +++ b/src/Tracing/Cache/TraceableCacheAdapterTrait.php @@ -9,6 +9,7 @@ use Sentry\Tracing\SpanContext; use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface; +use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Symfony\Contracts\Cache\CacheInterface; @@ -35,7 +36,7 @@ trait TraceableCacheAdapterTrait /** * {@inheritdoc} */ - public function getItem($key) + public function getItem($key): CacheItem { return $this->traceFunction('cache.get_item', function () use ($key) { return $this->decoratedAdapter->getItem($key); @@ -45,7 +46,7 @@ public function getItem($key) /** * {@inheritdoc} */ - public function getItems(array $keys = []) + public function getItems(array $keys = []): iterable { return $this->traceFunction('cache.get_items', function () use ($keys) { return $this->decoratedAdapter->getItems($keys); @@ -66,6 +67,8 @@ public function clear(string $prefix = ''): bool * {@inheritdoc} * * @param mixed[] $metadata + * + * @return mixed */ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnection.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnection.php index ee1587be..d4f7790d 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnection.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnection.php @@ -106,6 +106,8 @@ public function query(?string $sql = null, ...$args): Result /** * {@inheritdoc} + * + * @return mixed */ public function quote($value, $type = ParameterType::STRING) { @@ -124,6 +126,8 @@ public function exec($sql): int /** * {@inheritdoc} + * + * @return string|int|false */ public function lastInsertId($name = null) { diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php b/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php index 85435c6f..e4fbd21f 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php @@ -64,6 +64,12 @@ public function getDatabasePlatform(): AbstractPlatform /** * {@inheritdoc} + * + * @phpstan-template T of AbstractPlatform + * + * @phpstan-param T $platform + * + * @phpstan-return AbstractSchemaManager */ public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager { diff --git a/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php b/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php index 98c7cadd..c8a95d58 100644 --- a/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php +++ b/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php @@ -51,6 +51,8 @@ public function query(?string $sql = null, ...$args): Result /** * {@inheritdoc} + * + * @return mixed */ public function quote($value, $type = ParameterType::STRING) { @@ -67,8 +69,10 @@ public function exec($sql): int /** * {@inheritdoc} + * + * @return string|int|false */ - public function lastInsertId($name = null): ?string + public function lastInsertId($name = null) { return $this->decoratedConnection->lastInsertId($name); } diff --git a/tests/EventListener/AbstractConsoleListenerTest.php b/tests/EventListener/AbstractConsoleListenerTest.php index 48711d47..36eb14dd 100644 --- a/tests/EventListener/AbstractConsoleListenerTest.php +++ b/tests/EventListener/AbstractConsoleListenerTest.php @@ -15,8 +15,8 @@ use Symfony\Component\Console\Event\ConsoleErrorEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\NullOutput; abstract class AbstractConsoleListenerTest extends TestCase { @@ -60,25 +60,25 @@ public function testHandleConsoleCommandEvent(ConsoleCommandEvent $consoleEvent, public function handleConsoleCommmandEventDataProvider(): \Generator { yield [ - new ConsoleCommandEvent(null, $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)), + new ConsoleCommandEvent(null, new ArrayInput([]), new NullOutput()), [], [], ]; yield [ - new ConsoleCommandEvent(new Command(), $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)), + new ConsoleCommandEvent(new Command(), new ArrayInput([]), new NullOutput()), [], [], ]; yield [ - new ConsoleCommandEvent(new Command('foo:bar'), $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)), + new ConsoleCommandEvent(new Command('foo:bar'), new ArrayInput([]), new NullOutput()), ['console.command' => 'foo:bar'], [], ]; yield [ - new ConsoleCommandEvent(new Command('foo:bar'), new ArgvInput(['bin/console', 'foo:bar', '--foo=bar']), $this->createMock(OutputInterface::class)), + new ConsoleCommandEvent(new Command('foo:bar'), new ArgvInput(['bin/console', 'foo:bar', '--foo=bar']), new NullOutput()), ['console.command' => 'foo:bar'], ['Full command' => "'foo:bar' --foo=bar"], ]; @@ -92,7 +92,7 @@ public function testHandleConsoleTerminateEvent(): void $this->hub->expects($this->once()) ->method('popScope'); - $listener->handleConsoleTerminateEvent(new ConsoleTerminateEvent(new Command(), $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class), 0)); + $listener->handleConsoleTerminateEvent(new ConsoleTerminateEvent(new Command(), new ArrayInput([]), new NullOutput(), 0)); } /** @@ -101,7 +101,7 @@ public function testHandleConsoleTerminateEvent(): void public function testHandleConsoleErrorEvent(bool $captureErrors): void { $scope = new Scope(); - $consoleEvent = new ConsoleErrorEvent($this->createMock(InputInterface::class), $this->createMock(OutputInterface::class), new \Exception()); + $consoleEvent = new ConsoleErrorEvent(new ArrayInput([]), new NullOutput(), new \Exception()); $listenerClass = static::getListenerClass(); $listener = new $listenerClass($this->hub, $captureErrors); diff --git a/tests/EventListener/Fixtures/UserWithIdentifierStub.php b/tests/EventListener/Fixtures/UserWithIdentifierStub.php new file mode 100644 index 00000000..bdeb2aec --- /dev/null +++ b/tests/EventListener/Fixtures/UserWithIdentifierStub.php @@ -0,0 +1,39 @@ +getUsername(); + } + + public function getUsername(): string + { + return 'foo_user'; + } + + public function getRoles(): array + { + return []; + } + + public function getPassword(): ?string + { + return null; + } + + public function getSalt(): ?string + { + return null; + } + + public function eraseCredentials(): void + { + } +} diff --git a/tests/EventListener/Fixtures/UserWithoutIdentifierStub.php b/tests/EventListener/Fixtures/UserWithoutIdentifierStub.php new file mode 100644 index 00000000..b547df5d --- /dev/null +++ b/tests/EventListener/Fixtures/UserWithoutIdentifierStub.php @@ -0,0 +1,34 @@ +getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(false); - } - - public function getCredentials() - { - return null; - } - }, + new UnauthenticatedTokenStub(), UserDataBag::createFromUserIpAddress('127.0.0.1'), ]; @@ -152,19 +142,7 @@ public function getCredentials() HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(true); - } - - public function getCredentials() - { - return null; - } - }, + new AuthenticatedTokenStub(null), UserDataBag::createFromUserIpAddress('127.0.0.1'), ]; @@ -175,49 +153,29 @@ public function getCredentials() HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(true); - $this->setUser('foo_user'); - } - - public function getCredentials() - { - return null; - } - }, + new AuthenticatedTokenStub('foo_user'), new UserDataBag(null, null, '127.0.0.1', 'foo_user'), ]; - yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface' => [ + yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface && getUserIdentifier() method DOES NOT EXISTS' => [ new GetResponseEvent( $this->createMock(HttpKernelInterface::class), new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(true); - $this->setUser(new class() extends UserStub { - public function getUserIdentifier(): string - { - return $this->getUsername(); - } - }); - } + new AuthenticatedTokenStub(new UserWithoutIdentifierStub()), + new UserDataBag(null, null, '127.0.0.1', 'foo_user'), + ]; - public function getCredentials() - { - return null; - } - }, + yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface && getUserIdentifier() method EXISTS' => [ + new GetResponseEvent( + $this->createMock(HttpKernelInterface::class), + new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), + HttpKernelInterface::MASTER_REQUEST + ), + $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), + new AuthenticatedTokenStub(new UserWithIdentifierStub()), new UserDataBag(null, null, '127.0.0.1', 'foo_user'), ]; @@ -228,25 +186,12 @@ public function getCredentials() HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() + new AuthenticatedTokenStub(new class() implements \Stringable { + public function __toString(): string { - parent::__construct(); - - $this->setAuthenticated(true); - $this->setUser(new class() implements \Stringable { - public function __toString(): string - { - return 'foo_user'; - } - }); + return 'foo_user'; } - - public function getCredentials() - { - return null; - } - }, + }), new UserDataBag(null, null, '127.0.0.1', 'foo_user'), ]; } @@ -300,19 +245,7 @@ public function handleKernelRequestEventForSymfonyVersionAtLeast43DataProvider() HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(false); - } - - public function getCredentials() - { - return null; - } - }, + new UnauthenticatedTokenStub(), UserDataBag::createFromUserIpAddress('127.0.0.1'), ]; @@ -323,101 +256,58 @@ public function getCredentials() HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(true); - } - - public function getCredentials() - { - return null; - } - }, + new AuthenticatedTokenStub(null), UserDataBag::createFromUserIpAddress('127.0.0.1'), ]; - yield 'token.authenticated = TRUE && token.user INSTANCEOF string' => [ - new RequestEvent( - $this->createMock(HttpKernelInterface::class), - new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), - HttpKernelInterface::MASTER_REQUEST - ), - $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(true); - $this->setUser('foo_user'); - } - - public function getCredentials() - { - return null; - } - }, - new UserDataBag(null, null, '127.0.0.1', 'foo_user'), - ]; + if (version_compare(Kernel::VERSION, '6.0.0', '<')) { + yield 'token.authenticated = TRUE && token.user INSTANCEOF string' => [ + new RequestEvent( + $this->createMock(HttpKernelInterface::class), + new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), + HttpKernelInterface::MASTER_REQUEST + ), + $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), + new AuthenticatedTokenStub('foo_user'), + new UserDataBag(null, null, '127.0.0.1', 'foo_user'), + ]; - yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface && getUserIdentifier() method DOES NOT EXISTS' => [ - new RequestEvent( - $this->createMock(HttpKernelInterface::class), - new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), - HttpKernelInterface::MASTER_REQUEST - ), - $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new TokenStub(new class() extends UserStub {}), - new UserDataBag(null, null, '127.0.0.1', 'foo_user'), - ]; + yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface && getUserIdentifier() method DOES NOT EXISTS' => [ + new RequestEvent( + $this->createMock(HttpKernelInterface::class), + new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), + HttpKernelInterface::MASTER_REQUEST + ), + $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), + new AuthenticatedTokenStub(new UserWithoutIdentifierStub()), + new UserDataBag(null, null, '127.0.0.1', 'foo_user'), + ]; - if (Kernel::VERSION_ID >= 503000) { - yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface && getUserIdentifier() method EXISTS' => [ + yield 'token.authenticated = TRUE && token.user INSTANCEOF object && __toString() method EXISTS' => [ new RequestEvent( $this->createMock(HttpKernelInterface::class), new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new TokenStub(new class() extends UserStub { - public function getUserIdentifier(): string + new AuthenticatedTokenStub(new class() implements \Stringable { + public function __toString(): string { - return $this->getUsername(); + return 'foo_user'; } }), new UserDataBag(null, null, '127.0.0.1', 'foo_user'), ]; } - yield 'token.authenticated = TRUE && token.user INSTANCEOF object && __toString() method EXISTS' => [ + yield 'token.authenticated = TRUE && token.user INSTANCEOF UserInterface && getUserIdentifier() method EXISTS' => [ new RequestEvent( $this->createMock(HttpKernelInterface::class), new Request([], [], [], [], [], ['REMOTE_ADDR' => '127.0.0.1']), HttpKernelInterface::MASTER_REQUEST ), $this->getMockedClientWithOptions(new Options(['send_default_pii' => true])), - new class() extends AbstractToken { - public function __construct() - { - parent::__construct(); - - $this->setAuthenticated(true); - $this->setUser(new class() implements \Stringable { - public function __toString(): string - { - return 'foo_user'; - } - }); - } - - public function getCredentials() - { - return null; - } - }, + new AuthenticatedTokenStub(new UserWithIdentifierStub()), new UserDataBag(null, null, '127.0.0.1', 'foo_user'), ]; @@ -558,45 +448,34 @@ private function getMockedClientWithOptions(Options $options): ClientInterface } } -final class TokenStub extends AbstractToken +final class UnauthenticatedTokenStub extends AbstractToken { - public function __construct(UserInterface $user) - { - parent::__construct(); - - $this->setAuthenticated(true); - $this->setUser($user); - } - public function getCredentials(): ?string { return null; } } -abstract class UserStub implements UserInterface +final class AuthenticatedTokenStub extends AbstractToken { - public function getUsername(): string + /** + * @param UserInterface|\Stringable|string|null $user + */ + public function __construct($user) { - return 'foo_user'; - } + parent::__construct(); - public function getRoles(): array - { - return []; - } + if (method_exists($this, 'setAuthenticated')) { + $this->setAuthenticated(true); + } - public function getPassword(): ?string - { - return null; + if (null !== $user) { + $this->setUser($user); + } } - public function getSalt(): ?string + public function getCredentials(): ?string { return null; } - - public function eraseCredentials(): void - { - } } diff --git a/tests/EventListener/TracingConsoleListenerTest.php b/tests/EventListener/TracingConsoleListenerTest.php index b36f720d..ab26c9fd 100644 --- a/tests/EventListener/TracingConsoleListenerTest.php +++ b/tests/EventListener/TracingConsoleListenerTest.php @@ -15,8 +15,8 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\NullOutput; final class TracingConsoleListenerTest extends TestCase { @@ -58,8 +58,8 @@ public function testHandleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHub $listener = new TracingConsoleListener($this->hub); $listener->handleConsoleCommandEvent(new ConsoleCommandEvent( $command, - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class) + new ArrayInput([]), + new NullOutput() )); } @@ -112,8 +112,8 @@ public function testHandleConsoleCommandEventStartsChildSpanIfSpanIsSetOnHub(Com $listener = new TracingConsoleListener($this->hub); $listener->handleConsoleCommandEvent(new ConsoleCommandEvent( $command, - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class) + new ArrayInput([]), + new NullOutput() )); } @@ -141,8 +141,8 @@ public function testHandleConsoleCommandEvent(): void $listener = new TracingConsoleListener($this->hub, ['foo:bar']); $listener->handleConsoleCommandEvent(new ConsoleCommandEvent( new Command('foo:bar'), - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class) + new ArrayInput([]), + new NullOutput() )); } @@ -157,8 +157,8 @@ public function testHandleConsoleTerminateEvent(): void $listener = new TracingConsoleListener($this->hub); $listener->handleConsoleTerminateEvent(new ConsoleTerminateEvent( new Command(), - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class), + new ArrayInput([]), + new NullOutput(), 0 )); @@ -174,8 +174,8 @@ public function testHandleConsoleTerminateEventDoesNothingIfNoSpanIsSetOnHub(): $listener = new TracingConsoleListener($this->hub); $listener->handleConsoleTerminateEvent(new ConsoleTerminateEvent( new Command(), - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class), + new ArrayInput([]), + new NullOutput(), 0 )); } @@ -188,8 +188,8 @@ public function testHandleConsoleTerminateEventDoesNothingIfCommandIsExcluded(): $listener = new TracingConsoleListener($this->hub, ['foo:bar']); $listener->handleConsoleTerminateEvent(new ConsoleTerminateEvent( new Command('foo:bar'), - $this->createMock(InputInterface::class), - $this->createMock(OutputInterface::class), + new ArrayInput([]), + new NullOutput(), 0 )); } diff --git a/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php b/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php index 8663a743..3f1b2c65 100644 --- a/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php +++ b/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php @@ -68,7 +68,7 @@ public function testGetItem(): void public function testGetItems(): void { - $cacheItems = [new CacheItem()]; + $cacheItems = ['foo' => new CacheItem()]; $transaction = new Transaction(new TransactionContext(), $this->hub); $transaction->initSpanRecorder();