-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Psr18Client to make it straightforward to use PSR-18 (#230)
- Loading branch information
1 parent
d35947f
commit 07b7cc3
Showing
4 changed files
with
184 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
namespace Http\Discovery; | ||
|
||
use Psr\Http\Client\ClientInterface; | ||
use Psr\Http\Message\RequestFactoryInterface; | ||
use Psr\Http\Message\RequestInterface; | ||
use Psr\Http\Message\ResponseFactoryInterface; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestFactoryInterface; | ||
use Psr\Http\Message\StreamFactoryInterface; | ||
use Psr\Http\Message\UploadedFileFactoryInterface; | ||
use Psr\Http\Message\UriFactoryInterface; | ||
|
||
/** | ||
* A generic PSR-18 and PSR-17 implementation. | ||
* | ||
* You can create this class with concrete client and factory instances | ||
* or let it use discovery to find suitable implementations as needed. | ||
* | ||
* @author Nicolas Grekas <[email protected]> | ||
*/ | ||
class Psr18Client extends Psr17Factory implements ClientInterface | ||
{ | ||
private $client; | ||
|
||
public function __construct( | ||
ClientInterface $client = null, | ||
RequestFactoryInterface $requestFactory = null, | ||
ResponseFactoryInterface $responseFactory = null, | ||
ServerRequestFactoryInterface $serverRequestFactory = null, | ||
StreamFactoryInterface $streamFactory = null, | ||
UploadedFileFactoryInterface $uploadedFileFactory = null, | ||
UriFactoryInterface $uriFactory = null | ||
) { | ||
parent::__construct($requestFactory, $responseFactory, $serverRequestFactory, $streamFactory, $uploadedFileFactory, $uriFactory); | ||
|
||
$this->client = $client ?? Psr18ClientDiscovery::find(); | ||
} | ||
|
||
public function sendRequest(RequestInterface $request): ResponseInterface | ||
{ | ||
return $this->client->sendRequest($request); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
namespace tests\Http\Discovery; | ||
|
||
use Http\Discovery\Psr17Factory; | ||
use Http\Discovery\Psr18Client; | ||
use Http\Discovery\Psr18ClientDiscovery; | ||
use Http\Discovery\Strategy\DiscoveryStrategy; | ||
use PHPUnit\Framework\TestCase; | ||
use Psr\Http\Client\ClientInterface; | ||
use Psr\Http\Message\RequestFactoryInterface; | ||
use Psr\Http\Message\RequestInterface; | ||
use Psr\Http\Message\ResponseInterface; | ||
|
||
class Psr18ClientTest extends TestCase | ||
{ | ||
protected function setUp(): void | ||
{ | ||
if (!interface_exists(RequestFactoryInterface::class)) { | ||
$this->markTestSkipped(RequestFactoryInterface::class.' required.'); | ||
} | ||
if (!interface_exists(ClientInterface::class)) { | ||
$this->markTestSkipped(ClientInterface::class.' required.'); | ||
} | ||
} | ||
|
||
public function testClient() | ||
{ | ||
$mockClient = new class() implements ClientInterface { | ||
public $request; | ||
public $response; | ||
|
||
public function sendRequest(RequestInterface $request): ResponseInterface | ||
{ | ||
$this->request = $request; | ||
|
||
return $this->response; | ||
} | ||
}; | ||
|
||
$client = new Psr18Client($mockClient); | ||
$this->assertInstanceOf(Psr17Factory::class, $client); | ||
|
||
$mockResponse = $client->createResponse(); | ||
$mockClient->response = $mockResponse; | ||
|
||
$request = $client->createRequest('GET', '/foo'); | ||
$this->assertSame($mockResponse, $client->sendRequest($request)); | ||
$this->assertSame($request, $mockClient->request); | ||
} | ||
|
||
public function testDiscovery() | ||
{ | ||
$mockClient = new class() implements ClientInterface, DiscoveryStrategy { | ||
public static $client; | ||
|
||
public $request; | ||
public $response; | ||
|
||
public function __construct() | ||
{ | ||
self::$client = $this; | ||
} | ||
|
||
public function sendRequest(RequestInterface $request): ResponseInterface | ||
{ | ||
$this->request = $request; | ||
|
||
return $this->response; | ||
} | ||
|
||
public static function getCandidates($type) | ||
{ | ||
return is_a(ClientInterface::class, $type, true) | ||
? [['class' => self::class, 'condition' => self::class]] | ||
: []; | ||
} | ||
}; | ||
|
||
Psr18ClientDiscovery::prependStrategy(get_class($mockClient)); | ||
$client = new Psr18Client(); | ||
|
||
$this->assertInstanceOf(get_class($mockClient), $mockClient::$client); | ||
$mockClient = $mockClient::$client; | ||
$mockResponse = $client->createResponse(); | ||
$mockClient->response = $mockResponse; | ||
|
||
$request = $client->createRequest('GET', '/foo'); | ||
$this->assertSame($mockResponse, $client->sendRequest($request)); | ||
$this->assertSame($request, $mockClient->request); | ||
} | ||
} |