From cec50f6907db14eabcbbc3aaf2dfcfb43de86428 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Sat, 18 Nov 2023 19:04:14 +0100 Subject: [PATCH 1/5] fix some deprecations --- composer.json | 5 +- src/Collector/Formatter.php | 7 +- src/Collector/ProfileClient.php | 30 ++--- src/Collector/ProfilePlugin.php | 23 ++-- src/Collector/StackPlugin.php | 4 +- tests/Unit/ClientFactory/CurlFactoryTest.php | 4 +- .../Unit/ClientFactory/SymfonyFactoryTest.php | 4 +- tests/Unit/Collector/FormatterTest.php | 40 ++++-- .../PluginClientFactoryListenerTest.php | 9 +- .../Collector/ProfileClientFactoryTest.php | 14 +- tests/Unit/Collector/ProfileClientTest.php | 123 ++++++------------ tests/Unit/Collector/ProfilePluginTest.php | 68 ++++------ tests/Unit/Collector/StackPluginTest.php | 102 ++++----------- 13 files changed, 170 insertions(+), 263 deletions(-) diff --git a/composer.json b/composer.json index 2a7a03d4..1f5fb212 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "php-http/discovery": "^1.14", "php-http/httplug": "^2.0", "php-http/logger-plugin": "^1.1", - "php-http/message": "^1.9", + "php-http/message": "^1.13", "php-http/message-factory": "^1.0.2", "php-http/stopwatch-plugin": "^1.2", "psr/http-message": "^1.0 || ^2.0", @@ -73,7 +73,8 @@ "config": { "sort-packages": true, "allow-plugins": { - "symfony/flex": true + "symfony/flex": true, + "php-http/discovery": false } }, "autoload": { diff --git a/src/Collector/Formatter.php b/src/Collector/Formatter.php index 8fca820d..29be2d96 100644 --- a/src/Collector/Formatter.php +++ b/src/Collector/Formatter.php @@ -33,7 +33,7 @@ class Formatter implements MessageFormatter */ private $curlFormatter; - public function __construct(MessageFormatter $formatter, CurlCommandFormatter $curlFormatter) + public function __construct(MessageFormatter $formatter, MessageFormatter $curlFormatter) { $this->formatter = $formatter; $this->curlFormatter = $curlFormatter; @@ -47,7 +47,7 @@ public function __construct(MessageFormatter $formatter, CurlCommandFormatter $c public function formatException(\Throwable $exception) { if ($exception instanceof HttpException) { - return $this->formatter->formatResponse($exception->getResponse()); + return $this->formatter->formatResponseForRequest($exception->getResponse(), $exception->getRequest()); } if ($exception instanceof TransferException || $exception instanceof NetworkExceptionInterface) { @@ -74,9 +74,6 @@ public function formatResponseForRequest(ResponseInterface $response, RequestInt return $this->formatter->formatResponse($response); } - /** - * {@inheritdoc} - */ public function formatResponse(ResponseInterface $response) { return $this->formatter->formatResponse($response); diff --git a/src/Collector/ProfileClient.php b/src/Collector/ProfileClient.php index 191b2b44..ba796a76 100644 --- a/src/Collector/ProfileClient.php +++ b/src/Collector/ProfileClient.php @@ -70,9 +70,6 @@ public function __construct($client, Collector $collector, Formatter $formatter, $this->stopwatch = $stopwatch; } - /** - * {@inheritdoc} - */ public function sendAsyncRequest(RequestInterface $request) { $activateStack = true; @@ -89,8 +86,8 @@ public function sendAsyncRequest(RequestInterface $request) $this->collectRequestInformations($request, $stack); $event = $this->stopwatch->start($this->getStopwatchEventName($request), self::STOPWATCH_CATEGORY); - $onFulfilled = function (ResponseInterface $response) use ($event, $stack) { - $this->collectResponseInformations($response, $event, $stack); + $onFulfilled = function (ResponseInterface $response) use ($request, $event, $stack) { + $this->collectResponseInformations($request, $response, $event, $stack); $event->stop(); return $response; @@ -134,13 +131,9 @@ protected function doSendRequest(RequestInterface $request) try { $response = $this->client->sendRequest($request); - $this->collectResponseInformations($response, $event, $stack); + $this->collectResponseInformations($request, $response, $event, $stack); return $response; - } catch (\Exception $e) { - $this->collectExceptionInformations($e, $event, $stack); - - throw $e; } catch (\Throwable $e) { $this->collectExceptionInformations($e, $event, $stack); @@ -150,7 +143,7 @@ protected function doSendRequest(RequestInterface $request) } } - private function collectRequestInformations(RequestInterface $request, Stack $stack) + private function collectRequestInformations(RequestInterface $request, Stack $stack): void { $uri = $request->getUri(); $stack->setRequestTarget($request->getRequestTarget()); @@ -162,29 +155,24 @@ private function collectRequestInformations(RequestInterface $request, Stack $st $stack->setCurlCommand($this->formatter->formatAsCurlCommand($request)); } - private function collectResponseInformations(ResponseInterface $response, StopwatchEvent $event, Stack $stack) + private function collectResponseInformations(RequestInterface $request, ResponseInterface $response, StopwatchEvent $event, Stack $stack): void { $stack->setDuration($event->getDuration()); $stack->setResponseCode($response->getStatusCode()); - $stack->setClientResponse($this->formatter->formatResponse($response)); + $stack->setClientResponse($this->formatter->formatResponseForRequest($response, $request)); } - private function collectExceptionInformations(\Throwable $exception, StopwatchEvent $event, Stack $stack) + private function collectExceptionInformations(\Throwable $exception, StopwatchEvent $event, Stack $stack): void { if ($exception instanceof HttpException) { - $this->collectResponseInformations($exception->getResponse(), $event, $stack); + $this->collectResponseInformations($exception->getRequest(), $exception->getResponse(), $event, $stack); } $stack->setDuration($event->getDuration()); $stack->setClientException($this->formatter->formatException($exception)); } - /** - * Generates the event name. - * - * @return string - */ - private function getStopwatchEventName(RequestInterface $request) + private function getStopwatchEventName(RequestInterface $request): string { $name = sprintf('%s %s', $request->getMethod(), $request->getUri()); diff --git a/src/Collector/ProfilePlugin.php b/src/Collector/ProfilePlugin.php index da29ffa0..3f362b32 100644 --- a/src/Collector/ProfilePlugin.php +++ b/src/Collector/ProfilePlugin.php @@ -48,6 +48,9 @@ protected function doHandleRequest(RequestInterface $request, callable $next, ca $profile = new Profile(get_class($this->plugin)); $stack = $this->collector->getActiveStack(); + if (null === $stack) { + throw new \LogicException('No active stack'); + } $stack->addProfile($profile); // wrap the next callback to profile the plugin request changes @@ -83,31 +86,25 @@ protected function doHandleRequest(RequestInterface $request, callable $next, ca }); } - /** - * @param Stack $stack - */ private function onException( RequestInterface $request, Profile $profile, Exception $exception, - Stack $stack = null - ) { + Stack $stack + ): void { $profile->setFailed(true); $profile->setResponse($this->formatter->formatException($exception)); $this->collectRequestInformation($request, $stack); } - private function onOutgoingRequest(RequestInterface $request, Profile $profile) + private function onOutgoingRequest(RequestInterface $request, Profile $profile): void { $profile->setRequest($this->formatter->formatRequest($request)); } - /** - * @param Stack $stack - */ - private function onOutgoingResponse(ResponseInterface $response, Profile $profile, RequestInterface $request, Stack $stack = null) + private function onOutgoingResponse(ResponseInterface $response, Profile $profile, RequestInterface $request, Stack $stack): void { - $profile->setResponse($this->formatter->formatResponse($response)); + $profile->setResponse($this->formatter->formatResponseForRequest($response, $request)); $this->collectRequestInformation($request, $stack); } @@ -115,7 +112,7 @@ private function onOutgoingResponse(ResponseInterface $response, Profile $profil * Collect request information when not already done by the HTTP client. This happens when using the CachePlugin * and the cache is hit without re-validation. */ - private function collectRequestInformation(RequestInterface $request, Stack $stack = null) + private function collectRequestInformation(RequestInterface $request, Stack $stack): void { $uri = $request->getUri(); if (empty($stack->getRequestTarget())) { @@ -127,7 +124,7 @@ private function collectRequestInformation(RequestInterface $request, Stack $sta if (empty($stack->getRequestScheme())) { $stack->setRequestScheme($uri->getScheme()); } - if (empty($stack->getRequestPort())) { + if (null === $stack->getRequestPort()) { $stack->setRequestPort($uri->getPort()); } if (empty($stack->getRequestHost())) { diff --git a/src/Collector/StackPlugin.php b/src/Collector/StackPlugin.php index cb423b61..a71e2f0b 100644 --- a/src/Collector/StackPlugin.php +++ b/src/Collector/StackPlugin.php @@ -53,8 +53,8 @@ protected function doHandleRequest(RequestInterface $request, callable $next, ca $this->collector->addStack($stack); $this->collector->activateStack($stack); - $onFulfilled = function (ResponseInterface $response) use ($stack) { - $stack->setResponse($this->formatter->formatResponse($response)); + $onFulfilled = function (ResponseInterface $response) use ($stack, $request) { + $stack->setResponse($this->formatter->formatResponseForRequest($response, $request)); return $response; }; diff --git a/tests/Unit/ClientFactory/CurlFactoryTest.php b/tests/Unit/ClientFactory/CurlFactoryTest.php index 7e4fa6a8..02913ea3 100644 --- a/tests/Unit/ClientFactory/CurlFactoryTest.php +++ b/tests/Unit/ClientFactory/CurlFactoryTest.php @@ -22,8 +22,8 @@ public function testCreateClient(): void } $factory = new CurlFactory( - $this->getMockBuilder(ResponseFactoryInterface::class)->getMock(), - $this->getMockBuilder(StreamFactoryInterface::class)->getMock() + $this->createMock(ResponseFactoryInterface::class), + $this->createMock(StreamFactoryInterface::class) ); $client = $factory->createClient(); diff --git a/tests/Unit/ClientFactory/SymfonyFactoryTest.php b/tests/Unit/ClientFactory/SymfonyFactoryTest.php index 4fd29e43..fe54c6be 100644 --- a/tests/Unit/ClientFactory/SymfonyFactoryTest.php +++ b/tests/Unit/ClientFactory/SymfonyFactoryTest.php @@ -22,8 +22,8 @@ public function testCreateClient(): void } $factory = new SymfonyFactory( - $this->getMockBuilder(ResponseFactoryInterface::class)->getMock(), - $this->getMockBuilder(StreamFactoryInterface::class)->getMock() + $this->createMock(ResponseFactoryInterface::class), + $this->createMock(StreamFactoryInterface::class) ); $client = $factory->createClient(); diff --git a/tests/Unit/Collector/FormatterTest.php b/tests/Unit/Collector/FormatterTest.php index 2ea3247e..4150756c 100644 --- a/tests/Unit/Collector/FormatterTest.php +++ b/tests/Unit/Collector/FormatterTest.php @@ -11,18 +11,19 @@ use Http\HttplugBundle\Collector\Formatter; use Http\Message\Formatter as MessageFormatter; use Http\Message\Formatter\CurlCommandFormatter; +use Http\Message\Formatter\SimpleFormatter; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; class FormatterTest extends TestCase { /** - * @var MessageFormatter|MockObject + * @var MessageFormatter&MockObject */ private $formatter; /** - * @var CurlCommandFormatter|MockObject + * @var CurlCommandFormatter&MockObject */ private $curlFormatter; @@ -33,8 +34,8 @@ class FormatterTest extends TestCase public function setUp(): void { - $this->formatter = $this->getMockBuilder(MessageFormatter::class)->getMock(); - $this->curlFormatter = $this->getMockBuilder(CurlCommandFormatter::class)->getMock(); + $this->formatter = $this->createMock(MessageFormatter::class); + $this->curlFormatter = $this->createMock(CurlCommandFormatter::class); $this->subject = new Formatter($this->formatter, $this->curlFormatter); } @@ -52,6 +53,26 @@ public function testFormatRequest(): void $this->subject->formatRequest($request); } + public function testFormatResponseForRequest(): void + { + $formatter = $this->createMock(SimpleFormatter::class); + $subject = new Formatter($formatter, $this->curlFormatter); + + $response = new Response(); + $request = new Request('GET', '/'); + + $formatter + ->expects($this->once()) + ->method('formatResponseForRequest') + ->with($this->identicalTo($response), $this->identicalTo($request)) + ; + + $subject->formatResponseForRequest($response, $request); + } + + /** + * @group legacy + */ public function testFormatResponse(): void { $response = new Response(); @@ -67,18 +88,21 @@ public function testFormatResponse(): void public function testFormatHttpException(): void { + $formatter = $this->createMock(SimpleFormatter::class); + $subject = new Formatter($formatter, $this->curlFormatter); + $request = new Request('GET', '/'); $response = new Response(); $exception = new HttpException('', $request, $response); - $this->formatter + $formatter ->expects($this->once()) - ->method('formatResponse') - ->with($this->identicalTo($response)) + ->method('formatResponseForRequest') + ->with($this->identicalTo($response), $this->identicalTo($request)) ->willReturn('FormattedException') ; - $this->assertEquals('FormattedException', $this->subject->formatException($exception)); + $this->assertEquals('FormattedException', $subject->formatException($exception)); } public function testFormatTransferException(): void diff --git a/tests/Unit/Collector/PluginClientFactoryListenerTest.php b/tests/Unit/Collector/PluginClientFactoryListenerTest.php index ef2be31a..05e5ff09 100644 --- a/tests/Unit/Collector/PluginClientFactoryListenerTest.php +++ b/tests/Unit/Collector/PluginClientFactoryListenerTest.php @@ -9,6 +9,7 @@ use Http\HttplugBundle\Collector\Formatter; use Http\HttplugBundle\Collector\PluginClientFactory; use Http\HttplugBundle\Collector\PluginClientFactoryListener; +use Http\Message\Formatter as MessageFormatter; use Nyholm\NSA; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\Event as LegacyEvent; @@ -20,9 +21,9 @@ final class PluginClientFactoryListenerTest extends TestCase { public function testRegisterPluginClientFactory(): void { - $collector = $this->getMockBuilder(Collector::class)->getMock(); - $formatter = $this->getMockBuilder(Formatter::class)->disableOriginalConstructor()->getMock(); - $stopwatch = $this->getMockBuilder(Stopwatch::class)->getMock(); + $collector = new Collector(); + $formatter = new Formatter($this->createMock(MessageFormatter::class), $this->createMock(MessageFormatter::class)); + $stopwatch = $this->createMock(Stopwatch::class); $factory = new PluginClientFactory($collector, $formatter, $stopwatch); @@ -31,6 +32,6 @@ public function testRegisterPluginClientFactory(): void $class = (Kernel::MAJOR_VERSION >= 5) ? Event::class : LegacyEvent::class; $listener->onEvent(new $class()); - $this->assertTrue(is_callable(NSA::getProperty(DefaultPluginClientFactory::class, 'factory'))); + $this->assertIsCallable(NSA::getProperty(DefaultPluginClientFactory::class, 'factory')); } } diff --git a/tests/Unit/Collector/ProfileClientFactoryTest.php b/tests/Unit/Collector/ProfileClientFactoryTest.php index 4aeae247..4e5c5343 100644 --- a/tests/Unit/Collector/ProfileClientFactoryTest.php +++ b/tests/Unit/Collector/ProfileClientFactoryTest.php @@ -10,6 +10,8 @@ use Http\HttplugBundle\Collector\Formatter; use Http\HttplugBundle\Collector\ProfileClient; use Http\HttplugBundle\Collector\ProfileClientFactory; +use Http\Message\Formatter as MessageFormatter; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Stopwatch\Stopwatch; @@ -26,21 +28,21 @@ class ProfileClientFactoryTest extends TestCase private $formatter; /** - * @var Stopwatch + * @var Stopwatch&MockObject */ private $stopwatch; /** - * @var HttpClient + * @var HttpClient&MockObject */ private $client; public function setUp(): void { - $this->collector = $this->getMockBuilder(Collector::class)->disableOriginalConstructor()->getMock(); - $this->formatter = $this->getMockBuilder(Formatter::class)->disableOriginalConstructor()->getMock(); - $this->stopwatch = $this->getMockBuilder(Stopwatch::class)->getMock(); - $this->client = $this->getMockBuilder(HttpClient::class)->getMock(); + $this->collector = new Collector(); + $this->formatter = new Formatter($this->createMock(MessageFormatter::class), $this->createMock(MessageFormatter::class)); + $this->stopwatch = $this->createMock(Stopwatch::class); + $this->client = $this->createMock(HttpClient::class); } public function testCreateClientFromClientFactory(): void diff --git a/tests/Unit/Collector/ProfileClientTest.php b/tests/Unit/Collector/ProfileClientTest.php index a6db587a..7e266957 100644 --- a/tests/Unit/Collector/ProfileClientTest.php +++ b/tests/Unit/Collector/ProfileClientTest.php @@ -13,6 +13,8 @@ use Http\HttplugBundle\Collector\Formatter; use Http\HttplugBundle\Collector\ProfileClient; use Http\HttplugBundle\Collector\Stack; +use Http\Message\Formatter as MessageFormatter; +use Http\Message\Formatter\SimpleFormatter; use Http\Promise\FulfilledPromise; use Http\Promise\Promise; use Http\Promise\RejectedPromise; @@ -20,7 +22,6 @@ use PHPUnit\Framework\TestCase; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\UriInterface; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\Stopwatch\StopwatchEvent; @@ -32,12 +33,7 @@ class ProfileClientTest extends TestCase private $collector; /** - * @var Stack - */ - private $activeStack; - - /** - * @var HttpClient|MockObject + * @var HttpClient&MockObject */ private $client; @@ -46,16 +42,6 @@ class ProfileClientTest extends TestCase */ private $request; - /** - * @var Formatter|MockObject - */ - private $formatter; - - /** - * @var Stopwatch - */ - private $stopwatch; - /** * @var StopwatchEvent */ @@ -76,45 +62,37 @@ class ProfileClientTest extends TestCase */ private $fulfilledPromise; - /** - * @var \Exception - */ - private $exception; - /** * @var RejectedPromise */ private $rejectedPromise; - /** - * @var UriInterface - */ - private $uri; - public function setUp(): void { - $this->collector = $this->getMockBuilder(Collector::class)->disableOriginalConstructor()->getMock(); - $this->activeStack = new Stack('default', 'FormattedRequest'); + $messageFormatter = $this->createMock(SimpleFormatter::class); + $formatter = new Formatter($messageFormatter, $this->createMock(MessageFormatter::class)); + $this->collector = new Collector(); + $stopwatch = $this->createMock(Stopwatch::class); + + $activeStack = new Stack('default', 'FormattedRequest'); + $this->collector->activateStack($activeStack); $this->client = $this->getMockBuilder(ClientInterface::class)->getMock(); - $this->uri = new Uri('https://example.com/target'); - $this->request = new Request('GET', $this->uri); - $this->formatter = $this->getMockBuilder(Formatter::class)->disableOriginalConstructor()->getMock(); - $this->stopwatch = $this->getMockBuilder(Stopwatch::class)->disableOriginalConstructor()->getMock(); - $this->stopwatchEvent = $this->getMockBuilder(StopwatchEvent::class)->disableOriginalConstructor()->getMock(); - $this->subject = new ProfileClient($this->client, $this->collector, $this->formatter, $this->stopwatch); + $uri = new Uri('https://example.com/target'); + $this->request = new Request('GET', $uri); + $this->stopwatchEvent = $this->createMock(StopwatchEvent::class); + $this->subject = new ProfileClient($this->client, $this->collector, $formatter, $stopwatch); $this->response = new Response(); - $this->exception = new \Exception(); + $exception = new \Exception('test'); $this->fulfilledPromise = new FulfilledPromise($this->response); - $this->rejectedPromise = new RejectedPromise($this->exception); + $this->rejectedPromise = new RejectedPromise($exception); - $this->collector->method('getActiveStack')->willReturn($this->activeStack); - $this->formatter - ->method('formatResponse') - ->with($this->response) + $messageFormatter + ->method('formatResponseForRequest') + ->with($this->response, $this->request) ->willReturn('FormattedResponse') ; - $this->stopwatch + $stopwatch ->method('start') ->willReturn($this->stopwatchEvent) ; @@ -137,10 +115,12 @@ public function testSendRequest(): void $response = $this->subject->sendRequest($this->request); $this->assertEquals($this->response, $response); - $this->assertEquals('GET', $this->activeStack->getRequestMethod()); - $this->assertEquals('/target', $this->activeStack->getRequestTarget()); - $this->assertEquals('example.com', $this->activeStack->getRequestHost()); - $this->assertEquals('https', $this->activeStack->getRequestScheme()); + $activeStack = $this->collector->getActiveStack(); + $this->assertInstanceOf(Stack::class, $activeStack); + $this->assertEquals('GET', $activeStack->getRequestMethod()); + $this->assertEquals('/target', $activeStack->getRequestTarget()); + $this->assertEquals('example.com', $activeStack->getRequestHost()); + $this->assertEquals('https', $activeStack->getRequestScheme()); } public function testSendRequestTypeError() @@ -151,10 +131,6 @@ public function testSendRequestTypeError() ->willReturnCallback(function () { throw new \Error('You set string to int prop'); }); - $this->formatter - ->expects($this->once()) - ->method('formatException') - ->with($this->isInstanceOf(\Error::class)); $this->expectException(\Error::class); $this->expectExceptionMessage('You set string to int prop'); @@ -170,28 +146,19 @@ public function testSendAsyncRequest(): void ->willReturn($this->fulfilledPromise) ; - $this->collector - ->expects($this->once()) - ->method('deactivateStack') - ; - $promise = $this->subject->sendAsyncRequest($this->request); $this->assertEquals($this->fulfilledPromise, $promise); - $this->assertEquals('GET', $this->activeStack->getRequestMethod()); - $this->assertEquals('/target', $this->activeStack->getRequestTarget()); - $this->assertEquals('example.com', $this->activeStack->getRequestHost()); - $this->assertEquals('https', $this->activeStack->getRequestScheme()); + $activeStack = $this->collector->getActiveStack(); + $this->assertInstanceOf(Stack::class, $activeStack); + $this->assertEquals('GET', $activeStack->getRequestMethod()); + $this->assertEquals('/target', $activeStack->getRequestTarget()); + $this->assertEquals('example.com', $activeStack->getRequestHost()); + $this->assertEquals('https', $activeStack->getRequestScheme()); } public function testOnFulfilled(): void { - $this->collector - ->expects($this->once()) - ->method('activateStack') - ->with($this->activeStack) - ; - $this->stopwatchEvent ->expects($this->once()) ->method('stop') @@ -204,19 +171,15 @@ public function testOnFulfilled(): void $this->subject->sendAsyncRequest($this->request); - $this->assertEquals(42, $this->activeStack->getDuration()); - $this->assertEquals(200, $this->activeStack->getResponseCode()); - $this->assertEquals('FormattedResponse', $this->activeStack->getClientResponse()); + $activeStack = $this->collector->getActiveStack(); + $this->assertInstanceOf(Stack::class, $activeStack); + $this->assertEquals(42, $activeStack->getDuration()); + $this->assertEquals(200, $activeStack->getResponseCode()); + $this->assertEquals('FormattedResponse', $activeStack->getClientResponse()); } public function testOnRejected(): void { - $this->collector - ->expects($this->once()) - ->method('activateStack') - ->with($this->activeStack) - ; - $this->stopwatchEvent ->expects($this->once()) ->method('stop') @@ -227,16 +190,12 @@ public function testOnRejected(): void ->willReturn($this->rejectedPromise) ; - $this->formatter - ->method('formatException') - ->with($this->exception) - ->willReturn('FormattedException') - ; - $this->subject->sendAsyncRequest($this->request); - $this->assertEquals(42, $this->activeStack->getDuration()); - $this->assertEquals('FormattedException', $this->activeStack->getClientException()); + $activeStack = $this->collector->getActiveStack(); + $this->assertInstanceOf(Stack::class, $activeStack); + $this->assertEquals(42, $activeStack->getDuration()); + $this->assertEquals('Unexpected exception of type "Exception": test', $activeStack->getClientException()); } } diff --git a/tests/Unit/Collector/ProfilePluginTest.php b/tests/Unit/Collector/ProfilePluginTest.php index 115d8c60..8b2d2f54 100644 --- a/tests/Unit/Collector/ProfilePluginTest.php +++ b/tests/Unit/Collector/ProfilePluginTest.php @@ -12,6 +12,8 @@ use Http\HttplugBundle\Collector\Formatter; use Http\HttplugBundle\Collector\ProfilePlugin; use Http\HttplugBundle\Collector\Stack; +use Http\Message\Formatter as MessageFormatter; +use Http\Message\Formatter\SimpleFormatter; use Http\Promise\FulfilledPromise; use Http\Promise\Promise; use Http\Promise\RejectedPromise; @@ -26,11 +28,6 @@ class ProfilePluginTest extends TestCase */ private $plugin; - /** - * @var Collector - */ - private $collector; - /** * @var RequestInterface */ @@ -46,11 +43,6 @@ class ProfilePluginTest extends TestCase */ private $fulfilledPromise; - /** - * @var Stack - */ - private $currentStack; - /** * @var TransferException */ @@ -61,32 +53,26 @@ class ProfilePluginTest extends TestCase */ private $rejectedPromise; - /** - * @var Formatter - */ - private $formatter; - /** * @var ProfilePlugin */ private $subject; + private $collector; public function setUp(): void { - $this->plugin = $this->getMockBuilder(Plugin::class)->getMock(); - $this->collector = $this->getMockBuilder(Collector::class)->disableOriginalConstructor()->getMock(); + $this->collector = new Collector(); + $messageFormatter = $this->createMock(SimpleFormatter::class); + $formatter = new Formatter($messageFormatter, $this->createMock(MessageFormatter::class)); + + $this->plugin = $this->createMock(Plugin::class); $this->request = new Request('GET', '/'); $this->response = new Response(); $this->fulfilledPromise = new FulfilledPromise($this->response); - $this->currentStack = new Stack('default', 'FormattedRequest'); + $currentStack = new Stack('default', 'FormattedRequest'); + $this->collector->activateStack($currentStack); $this->exception = new TransferException(); $this->rejectedPromise = new RejectedPromise($this->exception); - $this->formatter = $this->getMockBuilder(Formatter::class)->disableOriginalConstructor()->getMock(); - - $this->collector - ->method('getActiveStack') - ->willReturn($this->currentStack) - ; $this->plugin ->method('handleRequest') @@ -95,29 +81,22 @@ public function setUp(): void }) ; - $this->formatter + $messageFormatter ->method('formatRequest') ->with($this->identicalTo($this->request)) ->willReturn('FormattedRequest') ; - $this->formatter - ->method('formatResponse') - ->with($this->identicalTo($this->response)) + $messageFormatter + ->method('formatResponseForRequest') + ->with($this->identicalTo($this->response), $this->identicalTo($this->request)) ->willReturn('FormattedResponse') ; - $this->formatter - ->method('formatException') - ->with($this->identicalTo($this->exception)) - ->willReturn('FormattedException') - ; - $this->subject = new ProfilePlugin( $this->plugin, $this->collector, - $this->formatter, - 'http.plugin.mock' + $formatter ); } @@ -142,8 +121,9 @@ public function testProfileIsInitialized(): void }, function (): void { }); - $this->assertCount(1, $this->currentStack->getProfiles()); - $profile = $this->currentStack->getProfiles()[0]; + $activeStack = $this->collector->getActiveStack(); + $this->assertCount(1, $activeStack->getProfiles()); + $profile = $activeStack->getProfiles()[0]; $this->assertEquals(get_class($this->plugin), $profile->getPlugin()); } @@ -154,7 +134,9 @@ public function testCollectRequestInformations(): void }, function (): void { }); - $profile = $this->currentStack->getProfiles()[0]; + $activeStack = $this->collector->getActiveStack(); + $this->assertCount(1, $activeStack->getProfiles()); + $profile = $activeStack->getProfiles()[0]; $this->assertEquals('FormattedRequest', $profile->getRequest()); } @@ -166,7 +148,10 @@ public function testOnFulfilled(): void }); $this->assertEquals($this->response, $promise->wait()); - $profile = $this->currentStack->getProfiles()[0]; + + $activeStack = $this->collector->getActiveStack(); + $this->assertCount(1, $activeStack->getProfiles()); + $profile = $activeStack->getProfiles()[0]; $this->assertEquals('FormattedResponse', $profile->getResponse()); } @@ -177,6 +162,9 @@ public function testOnRejected(): void }, function (): void { }); + $activeStack = $this->collector->getActiveStack(); + $this->assertCount(1, $activeStack->getProfiles()); + $this->expectException(TransferException::class); $promise->wait(); } diff --git a/tests/Unit/Collector/StackPluginTest.php b/tests/Unit/Collector/StackPluginTest.php index 8eb443cd..3202e082 100644 --- a/tests/Unit/Collector/StackPluginTest.php +++ b/tests/Unit/Collector/StackPluginTest.php @@ -9,8 +9,9 @@ use Http\Client\Exception\HttpException; use Http\HttplugBundle\Collector\Collector; use Http\HttplugBundle\Collector\Formatter; -use Http\HttplugBundle\Collector\Stack; use Http\HttplugBundle\Collector\StackPlugin; +use Http\Message\Formatter as MessageFormatter; +use Http\Message\Formatter\SimpleFormatter; use Http\Promise\FulfilledPromise; use Http\Promise\RejectedPromise; use PHPUnit\Framework\Error\Warning; @@ -25,11 +26,6 @@ class StackPluginTest extends TestCase */ private $collector; - /** - * @var Formatter - */ - private $formatter; - /** * @var RequestInterface */ @@ -52,75 +48,46 @@ class StackPluginTest extends TestCase public function setUp(): void { - $this->collector = $this->getMockBuilder(Collector::class)->disableOriginalConstructor()->getMock(); - $this->formatter = $this->getMockBuilder(Formatter::class)->disableOriginalConstructor()->getMock(); + $this->collector = new Collector(); + $messageFormatter = $this->createMock(SimpleFormatter::class); + $formatter = new Formatter($messageFormatter, $this->createMock(MessageFormatter::class)); $this->request = new Request('GET', '/'); $this->response = new Response(); $this->exception = new HttpException('', $this->request, $this->response); - $this->formatter + $messageFormatter ->method('formatRequest') ->with($this->request) ->willReturn('FormattedRequest') ; - $this->formatter - ->method('formatResponse') - ->with($this->response) + $messageFormatter + ->method('formatResponseForRequest') + ->with($this->response, $this->request) ->willReturn('FormattedResponse') ; - $this->formatter - ->method('formatException') - ->with($this->exception) - ->willReturn('FormattedException') - ; - - $this->subject = new StackPlugin($this->collector, $this->formatter, 'default'); + $this->subject = new StackPlugin($this->collector, $formatter, 'default'); } public function testStackIsInitialized(): void { - $this->collector - ->expects($this->once()) - ->method('addStack') - ->with($this->callback(function (Stack $stack) { - $this->assertEquals('default', $stack->getClient()); - $this->assertEquals('FormattedRequest', $stack->getRequest()); - - return true; - })) - ; - $this->collector - ->expects($this->once()) - ->method('activateStack') - ; - $next = function () { return new FulfilledPromise($this->response); }; $this->subject->handleRequest($this->request, $next, function (): void { }); + + $this->assertNull($this->collector->getActiveStack()); + $stacks = $this->collector->getStacks(); + $this->assertCount(1, $stacks); + $this->assertEquals('default', $stacks[0]->getClient()); + $this->assertEquals('FormattedRequest', $stacks[0]->getRequest()); } public function testOnFulfilled(): void { - //Capture the current stack - $currentStack = null; - $this->collector - ->method('addStack') - ->with($this->callback(function (Stack $stack) use (&$currentStack) { - $currentStack = $stack; - - return true; - })) - ; - $this->collector - ->expects($this->once()) - ->method('deactivateStack') - ; - $next = function () { return new FulfilledPromise($this->response); }; @@ -129,27 +96,14 @@ public function testOnFulfilled(): void }); $this->assertEquals($this->response, $promise->wait()); - $this->assertInstanceOf(Stack::class, $currentStack); - $this->assertEquals('FormattedResponse', $currentStack->getResponse()); + $this->assertNull($this->collector->getActiveStack()); + $stacks = $this->collector->getStacks(); + $this->assertCount(1, $stacks); + $this->assertEquals('FormattedResponse', $stacks[0]->getResponse()); } public function testOnRejected(): void { - //Capture the current stack - $currentStack = null; - $this->collector - ->method('addStack') - ->with($this->callback(function (Stack $stack) use (&$currentStack) { - $currentStack = $stack; - - return true; - })) - ; - $this->collector - ->expects($this->once()) - ->method('deactivateStack') - ; - $next = function () { return new RejectedPromise($this->exception); }; @@ -157,17 +111,18 @@ public function testOnRejected(): void $promise = $this->subject->handleRequest($this->request, $next, function (): void { }); + $this->assertNull($this->collector->getActiveStack()); + $stacks = $this->collector->getStacks(); + $this->assertCount(1, $stacks); + $this->assertEquals('FormattedResponse', $stacks[0]->getResponse()); + $this->assertTrue($stacks[0]->isFailed()); + $this->expectException(\Exception::class); $promise->wait(); } public function testOnException(): void { - $this->collector - ->expects($this->once()) - ->method('deactivateStack') - ; - $next = function (): void { throw new \Exception(); }; @@ -185,11 +140,6 @@ public function testOnError(): void $this->expectException(Warning::class); } - $this->collector - ->expects($this->once()) - ->method('deactivateStack') - ; - $next = function () { return 2 / 0; }; From 91789a450c555cd17a2274a70faa4fdd741bf15c Mon Sep 17 00:00:00 2001 From: Kai Dederichs Date: Tue, 5 Dec 2023 16:22:10 +0100 Subject: [PATCH 2/5] feat: Support Symfony 7 --- .github/workflows/continuous-integration.yml | 7 +++++ CHANGELOG.md | 2 ++ composer.json | 30 +++++++++---------- tests/Functional/ServiceInstantiationTest.php | 3 +- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 6b6a2647..aac801de 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -43,6 +43,9 @@ jobs: - dependencies: "php-http/guzzle7-adapter" php-version: "8.2" symfony-deprecations-helper: "weak" + - dependencies: "php-http/guzzle7-adapter" + php-version: "8.3" + symfony-deprecations-helper: "weak" # Test with httplug 2.x clients - dependencies: "php-http/guzzle7-adapter php-http/curl-client:^2.0.0 php-http/vcr-plugin:^1.0@dev php-http/socket-client:^2.0" @@ -68,6 +71,10 @@ jobs: symfony-require: "5.4.*" php-version: "7.3" symfony-deprecations-helper: "weak" + - dependencies: "php-http/guzzle7-adapter symfony/http-client:^6.0" + symfony-require: "6.4.*" + php-version: "8.1" + symfony-deprecations-helper: "weak" steps: - name: "Checkout" diff --git a/CHANGELOG.md b/CHANGELOG.md index 43434250..480cea37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee # Version 1 +- Added support for Symfony 7 + # 1.31.0 - 2023-11-06 - Added configuration for the `header` authentication plugin (#437). diff --git a/composer.json b/composer.json index 1f5fb212..c5680a22 100644 --- a/composer.json +++ b/composer.json @@ -35,11 +35,11 @@ "php-http/message-factory": "^1.0.2", "php-http/stopwatch-plugin": "^1.2", "psr/http-message": "^1.0 || ^2.0", - "symfony/config": "^4.4 || ^5.0 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0", - "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", - "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0" + "symfony/config": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0 || ^7.0" }, "conflict": { "php-http/guzzle6-adapter": "<1.1", @@ -48,21 +48,21 @@ }, "require-dev": { "guzzlehttp/psr7": "^1.7 || ^2.0", - "matthiasnoback/symfony-dependency-injection-test": "^4.0", + "matthiasnoback/symfony-dependency-injection-test": "^4.0 || ^5.0", "nyholm/nsa": "^1.1", "nyholm/psr7": "^1.2.1", "php-http/cache-plugin": "^1.7", "php-http/mock-client": "^1.2", "php-http/promise": "^1.0", - "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", - "symfony/cache": "^4.4 || ^5.0 || ^6.0", - "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0", - "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", - "symfony/http-foundation": "^4.4.19 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^5.3", - "symfony/stopwatch": "^4.4 || ^5.0 || ^6.0", - "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0", - "symfony/web-profiler-bundle": "^4.4.19 || ^5.0 || ^6.0", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/cache": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/http-foundation": "^4.4.19 || ^5.0 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.4.1", + "symfony/stopwatch": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/web-profiler-bundle": "^4.4.19 || ^5.0 || ^6.0 || ^7.0", "twig/twig": "^1.41 || ^2.10 || ^3.0" }, "suggest": { diff --git a/tests/Functional/ServiceInstantiationTest.php b/tests/Functional/ServiceInstantiationTest.php index 35dcfffa..008b6d60 100644 --- a/tests/Functional/ServiceInstantiationTest.php +++ b/tests/Functional/ServiceInstantiationTest.php @@ -134,7 +134,8 @@ protected static function bootKernel(array $options = []): KernelInterface $dispatcher = static::$kernel->getContainer()->get('event_dispatcher'); $class = (Kernel::MAJOR_VERSION >= 5) ? RequestEvent::class : GetResponseEvent::class; - $event = new $class(static::$kernel, SymfonyRequest::create('/'), HttpKernelInterface::MASTER_REQUEST); + $requestType = (Kernel::MAJOR_VERSION >= 6) ? HttpKernelInterface::MAIN_REQUEST : HttpKernelInterface::MASTER_REQUEST; + $event = new $class(static::$kernel, SymfonyRequest::create('/'), $requestType); $dispatcher->dispatch($event, KernelEvents::REQUEST); From 7faff5c33d0fb507dae4a8dedfbe4dc32165e8fa Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Wed, 6 Dec 2023 15:57:48 +0100 Subject: [PATCH 3/5] prepare release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 480cea37..eca49571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee # Version 1 +# 1.32.0 - 2023-12-06 + - Added support for Symfony 7 # 1.31.0 - 2023-11-06 From a29d3504f451222708d0ee1565973fd9ab089289 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Fri, 12 Jan 2024 15:37:13 +0100 Subject: [PATCH 4/5] adjust composer install steps --- .github/workflows/continuous-integration.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index aac801de..b2a550e9 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -93,8 +93,10 @@ jobs: run: "composer config minimum-stability stable" if: "${{ matrix.stability == 'stable' }}" - - name: "Install dependencies" - run: "composer require --no-progress --no-scripts --no-plugins symfony/flex ${{ matrix.dependencies }}" + - name: "Add dependencies and enable flex" + run: | + composer require --no-update symfony/flex ${{ matrix.dependencies }} + composer config --no-plugins allow-plugins.symfony/flex true - name: "Install dependencies with Composer" uses: "ramsey/composer-install@v2" From 0f11377a73a2bc1050bcccebe668a37cc3979424 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Mon, 26 Feb 2024 16:11:29 +0100 Subject: [PATCH 5/5] only use latest phpunit bridge --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 59ead6c9..11048c18 100644 --- a/composer.json +++ b/composer.json @@ -62,7 +62,7 @@ "symfony/dom-crawler": "^5.4 || ^6.0 || ^7.0", "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", "symfony/http-foundation": "^5.4 || ^6.0 || ^7.0", - "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^7.0.3", "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", "symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0", "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0",