Skip to content

Commit

Permalink
Make sure we support any psr-18 client (#295)
Browse files Browse the repository at this point in the history
* Make sure we support any psr-18 client

* wring use statement

* Updated exceptions

* use use statements

* Added tests with a PSR18 client
  • Loading branch information
Nyholm committed Dec 30, 2018
1 parent 9d208e2 commit 853b2c4
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 10 deletions.
6 changes: 4 additions & 2 deletions Collector/Formatter.php
Expand Up @@ -7,6 +7,8 @@
use Http\Client\Exception\TransferException;
use Http\Message\Formatter as MessageFormatter;
use Http\Message\Formatter\CurlCommandFormatter;
use Psr\Http\Client\NetworkExceptionInterface;
use Psr\Http\Client\RequestExceptionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -49,11 +51,11 @@ public function __construct(MessageFormatter $formatter, CurlCommandFormatter $c
*/
public function formatException(Exception $exception)
{
if ($exception instanceof HttpException) {
if ($exception instanceof HttpException || $exception instanceof RequestExceptionInterface) {
return $this->formatter->formatResponse($exception->getResponse());
}

if ($exception instanceof TransferException) {
if ($exception instanceof TransferException || $exception instanceof NetworkExceptionInterface) {
return sprintf('Transfer error: %s', $exception->getMessage());
}

Expand Down
7 changes: 4 additions & 3 deletions Collector/PluginClientFactory.php
Expand Up @@ -6,6 +6,7 @@
use Http\Client\Common\PluginClient;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Psr\Http\Client\ClientInterface;
use Symfony\Component\Stopwatch\Stopwatch;

/**
Expand Down Expand Up @@ -46,9 +47,9 @@ public function __construct(Collector $collector, Formatter $formatter, Stopwatc
}

/**
* @param HttpClient|HttpAsyncClient $client
* @param Plugin[] $plugins
* @param array $options {
* @param HttpClient|ClientInterface|HttpAsyncClient $client
* @param Plugin[] $plugins
* @param array $options {
*
* @var string $client_name to give client a name which may be used when displaying client information like in
* the HTTPlugBundle profiler.
Expand Down
6 changes: 4 additions & 2 deletions Collector/ProfileClient.php
Expand Up @@ -7,6 +7,8 @@
use Http\Client\Exception\HttpException;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Client\RequestExceptionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\Stopwatch\Stopwatch;
Expand Down Expand Up @@ -58,7 +60,7 @@ class ProfileClient implements HttpClient, HttpAsyncClient
*/
public function __construct($client, Collector $collector, Formatter $formatter, Stopwatch $stopwatch)
{
if (!($client instanceof HttpClient && $client instanceof HttpAsyncClient)) {
if (!(($client instanceof ClientInterface || $client instanceof HttpClient) && $client instanceof HttpAsyncClient)) {
$client = new FlexibleHttpClient($client);
}

Expand Down Expand Up @@ -181,7 +183,7 @@ private function collectResponseInformations(ResponseInterface $response, Stopwa
*/
private function collectExceptionInformations(\Exception $exception, StopwatchEvent $event, Stack $stack)
{
if ($exception instanceof HttpException) {
if ($exception instanceof HttpException || $exception instanceof RequestExceptionInterface) {
$this->collectResponseInformations($exception->getResponse(), $event, $stack);
}

Expand Down
3 changes: 2 additions & 1 deletion Collector/ProfileClientFactory.php
Expand Up @@ -6,6 +6,7 @@
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\HttplugBundle\ClientFactory\ClientFactory;
use Psr\Http\Client\ClientInterface;
use Symfony\Component\Stopwatch\Stopwatch;

/**
Expand Down Expand Up @@ -61,7 +62,7 @@ public function createClient(array $config = [])
{
$client = is_callable($this->factory) ? call_user_func($this->factory, $config) : $this->factory->createClient($config);

if (!($client instanceof HttpClient && $client instanceof HttpAsyncClient)) {
if (!(($client instanceof HttpClient || $client instanceof ClientInterface) && $client instanceof HttpAsyncClient)) {
$client = new FlexibleHttpClient($client);
}

Expand Down
24 changes: 24 additions & 0 deletions Tests/Functional/ServiceInstantiationTest.php
Expand Up @@ -10,6 +10,8 @@
use Http\HttplugBundle\Collector\ProfilePlugin;
use Http\HttplugBundle\Collector\StackPlugin;
use Nyholm\NSA;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -77,6 +79,28 @@ public function testProfilingDecoration()
$this->assertInstanceOf(ProfilePlugin::class, $plugins[4]);
}

public function testProfilingPsr18Decoration()
{
if (!interface_exists(ClientInterface::class)) {
$this->markTestSkipped('PSR-18 is not installed');
}

static::bootKernel(['debug' => true, 'environment' => 'psr18']);
$container = static::$kernel->getContainer();

$client = $container->get('httplug.client.my_psr18');
$this->assertInstanceOf(PluginClient::class, $client);
$profileClient = NSA::getProperty($client, 'client');
$this->assertInstanceOf(ProfileClient::class, $profileClient);

$flexibleClient = NSA::getProperty($profileClient, 'client');
$psr18Client = NSA::getProperty($flexibleClient, 'httpClient');
$this->assertInstanceOf(ClientInterface::class, $psr18Client);

$response = $client->sendRequest(new \GuzzleHttp\Psr7\Request('GET', 'https://example.com'));
$this->assertInstanceOf(ResponseInterface::class, $response);
}

/**
* {@inheritdoc}
*/
Expand Down
17 changes: 17 additions & 0 deletions Tests/Resources/MyPsr18TestClient.php
@@ -0,0 +1,17 @@
<?php

namespace Http\HttplugBundle\Tests\Resources;

use GuzzleHttp\Psr7\Response;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class MyPsr18TestClient implements ClientInterface
{
public function sendRequest(RequestInterface $request): ResponseInterface
{
return new Response();
}

}
2 changes: 1 addition & 1 deletion Tests/Resources/app/AppKernel.php
Expand Up @@ -28,7 +28,7 @@ public function registerBundles()
new \Http\HttplugBundle\HttplugBundle(),
];

if (in_array($this->getEnvironment(), array('dev', 'test'))) {
if (in_array($this->getEnvironment(), array('dev', 'test', 'psr18'))) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
}

Expand Down
28 changes: 28 additions & 0 deletions Tests/Resources/app/config/config_psr18.yml
@@ -0,0 +1,28 @@
imports:
- { resource: config_test.yml }

httplug:
discovery:
async_client: auto
clients:
my_psr18:
service: 'my_psr18_client'
public: true
plugins:
-
decoder:
use_content_encoding: false
- app.http.plugin.custom
-
add_host:
host: "http://localhost:8000"
-
authentication:
my_basic:
type: basic
username: foo
password: bar

services:
my_psr18_client:
class: Http\HttplugBundle\Tests\Resources\MyPsr18TestClient
5 changes: 4 additions & 1 deletion composer.json
Expand Up @@ -61,7 +61,10 @@
"autoload": {
"psr-4": {
"Http\\HttplugBundle\\": ""
}
},
"exclude-from-classmap": [
"/Tests/Resources/MyPsr18TestClient.php"
]
},
"autoload-dev": {
"classmap": [
Expand Down

0 comments on commit 853b2c4

Please sign in to comment.