From 44d545db7af61ef6f0f7666d0ac599eb411d4a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Fri, 11 Aug 2017 15:19:28 +0200 Subject: [PATCH] Rewritten for asynchronous requests and promises --- README.md | 8 ++-- src/AbstractApi.php | 8 ++-- src/Api.php | 74 +++++++++++++++++++------------ src/ApiInterface.php | 11 ++--- src/CommonEndpointInterface.php | 10 +++-- src/Replica.php | 40 ++++++++++------- tests/ApiTest.php | 77 ++++++++++++++++++++------------- tests/ReplicaTest.php | 35 +++++++++------ 8 files changed, 163 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 486c3d6..0a90054 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,21 @@ use ParagonIE\Sapient\CryptographyKeys\SigningPublicKey; use ParagonIE\Sapient\CryptographyKeys\SigningSecretKey; $api = new Api( - new Client(), // Client must implement Http\Client\HttpClient + new Client(), // Client must implement Http\Client\HttpAsyncClient new RequestFactory(), // RequestFactory must implement Interop\Http\Factory\RequestFactoryInterface 'https://chronicle.uri', new SigningPublicKey(Base64UrlSafe::decode('chronicle public key')) // optional, omit if you don't care about validating API responses ); -$api->lastHash(); +var_dump($api->lastHash()->wait()); // you must authenticate first before you can publish a message $api->authenticate( new SigningSecretKey(Base64UrlSafe::decode('your secret key')), 'your client id' ); -$api->publish('hello world'); +var_dump($api->publish('hello world')->wait()); ``` For implementations of client and request factory, you can use for example [Guzzle 6 HTTP Adapter](https://github.com/php-http/guzzle6-adapter) and [HTTP Factory for Guzzle](https://github.com/http-interop/http-factory-guzzle) respectively. + +All endpoints return `Http\Promise\Promise`, so you can either just `->wait()` for the response, or handle it asynchronously with `->then()`. Responses are just plain arrays, look up the structure in the Chronicle's documentation. diff --git a/src/AbstractApi.php b/src/AbstractApi.php index 8340669..0a87a8e 100644 --- a/src/AbstractApi.php +++ b/src/AbstractApi.php @@ -39,7 +39,7 @@ protected function verifyAndReturnResponse(ResponseInterface $response): array if ($this->chroniclePublicKey !== \null) { $headers = $response->getHeader(Sapient::HEADER_SIGNATURE_NAME); if (\count($headers) === 0) { - throw new HeaderMissingException(\sprintf('No signed response header (%s) found.', Sapient::HEADER_SIGNATURE_NAME)); + throw new HeaderMissingException(\sprintf('No signed response header (%s) found', Sapient::HEADER_SIGNATURE_NAME)); } foreach ($headers as $header) { if (\ParagonIE_Sodium_Compat::crypto_sign_verify_detached( @@ -52,10 +52,10 @@ protected function verifyAndReturnResponse(ResponseInterface $response): array } } } - if ($verified) { - return \json_decode($body, \true); + if (!$verified) { + throw new InvalidMessageException('No valid signature given for this HTTP response'); } - throw new InvalidMessageException('No valid signature given for this HTTP response'); + return \json_decode($body, \true); } } diff --git a/src/Api.php b/src/Api.php index dd87534..a10c505 100644 --- a/src/Api.php +++ b/src/Api.php @@ -4,7 +4,8 @@ namespace Lookyman\Chronicle; -use Http\Client\HttpClient; +use Http\Client\HttpAsyncClient; +use Http\Promise\Promise; use Interop\Http\Factory\RequestFactoryInterface; use ParagonIE\ConstantTime\Base64UrlSafe; use ParagonIE\Sapient\Adapter\Generic\Stream; @@ -13,6 +14,7 @@ use ParagonIE\Sapient\Sapient; use Psr\Http\Message\MessageInterface; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; final class Api extends AbstractApi implements ApiInterface { @@ -20,7 +22,7 @@ final class Api extends AbstractApi implements ApiInterface const CHRONICLE_CLIENT_KEY_ID = 'Chronicle-Client-Key-ID'; /** - * @var HttpClient + * @var HttpAsyncClient */ private $client; @@ -45,7 +47,7 @@ final class Api extends AbstractApi implements ApiInterface private $chronicleClientId; public function __construct( - HttpClient $client, + HttpAsyncClient $client, RequestFactoryInterface $requestFactory, string $chronicleUri, SigningPublicKey $chroniclePublicKey = \null @@ -62,64 +64,74 @@ public function authenticate(SigningSecretKey $signingSecretKey, string $chronic $this->chronicleClientId = $chronicleClientId; } - public function lastHash(): array + public function lastHash(): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/lasthash', $this->chronicleUri ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function lookup(string $hash): array + public function lookup(string $hash): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/lookup/%s', $this->chronicleUri, \urlencode($hash) ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function since(string $hash): array + public function since(string $hash): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/since/%s', $this->chronicleUri, \urlencode($hash) ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function export(): array + public function export(): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/export', $this->chronicleUri ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function index(): array + public function index(): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle', $this->chronicleUri ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function register(SigningPublicKey $publicKey, string $comment = \null): array + public function register(SigningPublicKey $publicKey, string $comment = \null): Promise { $message = \json_encode([ 'publickey' => $publicKey->getString(), @@ -133,10 +145,12 @@ public function register(SigningPublicKey $publicKey, string $comment = \null): 'Content-Type', 'application/json' )); - return $this->verifyAndReturnResponse($this->client->sendRequest($request)); + return $this->client->sendAsyncRequest($request)->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function revoke(string $clientId, SigningPublicKey $publicKey): array + public function revoke(string $clientId, SigningPublicKey $publicKey): Promise { $message = \json_encode([ 'clientid' => $clientId, @@ -150,17 +164,21 @@ public function revoke(string $clientId, SigningPublicKey $publicKey): array 'Content-Type', 'application/json' )); - return $this->verifyAndReturnResponse($this->client->sendRequest($request)); + return $this->client->sendAsyncRequest($request)->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function publish(string $message): array + public function publish(string $message): Promise { /** @var RequestInterface $request */ $request = $this->authenticateAndSignMessage($this->requestFactory->createRequest( 'POST', \sprintf('%s/chronicle/publish', $this->chronicleUri) )->withBody(Stream::fromString($message))); - return $this->verifyAndReturnResponse($this->client->sendRequest($request)); + return $this->client->sendAsyncRequest($request)->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } public function replica(string $source): CommonEndpointInterface @@ -174,15 +192,17 @@ public function replica(string $source): CommonEndpointInterface ); } - public function replicas(): array + public function replicas(): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/replica', $this->chronicleUri ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } private function authenticateAndSignMessage(MessageInterface $request): MessageInterface diff --git a/src/ApiInterface.php b/src/ApiInterface.php index 25ed5fc..e0b61f2 100644 --- a/src/ApiInterface.php +++ b/src/ApiInterface.php @@ -4,21 +4,22 @@ namespace Lookyman\Chronicle; +use Http\Promise\Promise; use ParagonIE\Sapient\CryptographyKeys\SigningPublicKey; interface ApiInterface extends CommonEndpointInterface { - public function index(): array; + public function index(): Promise; - public function register(SigningPublicKey $publicKey, string $comment = null): array; + public function register(SigningPublicKey $publicKey, string $comment = null): Promise; - public function revoke(string $clientId, SigningPublicKey $publicKey): array; + public function revoke(string $clientId, SigningPublicKey $publicKey): Promise; - public function publish(string $message): array; + public function publish(string $message): Promise; public function replica(string $source): CommonEndpointInterface; - public function replicas(): array; + public function replicas(): Promise; } diff --git a/src/CommonEndpointInterface.php b/src/CommonEndpointInterface.php index 85b8561..7f3e844 100644 --- a/src/CommonEndpointInterface.php +++ b/src/CommonEndpointInterface.php @@ -4,15 +4,17 @@ namespace Lookyman\Chronicle; +use Http\Promise\Promise; + interface CommonEndpointInterface { - public function lastHash(): array; + public function lastHash(): Promise; - public function lookup(string $hash): array; + public function lookup(string $hash): Promise; - public function since(string $hash): array; + public function since(string $hash): Promise; - public function export(): array; + public function export(): Promise; } diff --git a/src/Replica.php b/src/Replica.php index ee65c71..81c4996 100644 --- a/src/Replica.php +++ b/src/Replica.php @@ -4,15 +4,17 @@ namespace Lookyman\Chronicle; -use Http\Client\HttpClient; +use Http\Client\HttpAsyncClient; +use Http\Promise\Promise; use Interop\Http\Factory\RequestFactoryInterface; use ParagonIE\Sapient\CryptographyKeys\SigningPublicKey; +use Psr\Http\Message\ResponseInterface; final class Replica extends AbstractApi implements CommonEndpointInterface { /** - * @var HttpClient + * @var HttpAsyncClient */ private $client; @@ -32,7 +34,7 @@ final class Replica extends AbstractApi implements CommonEndpointInterface private $source; public function __construct( - HttpClient $client, + HttpAsyncClient $client, RequestFactoryInterface $requestFactory, string $chronicleUri, string $source, @@ -45,21 +47,23 @@ public function __construct( $this->source = $source; } - public function lastHash(): array + public function lastHash(): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/replica/%s/lasthash', $this->chronicleUri, \urlencode($this->source) ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function lookup(string $hash): array + public function lookup(string $hash): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/replica/%s/lookup/%s', @@ -67,12 +71,14 @@ public function lookup(string $hash): array \urlencode($this->source), \urlencode($hash) ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function since(string $hash): array + public function since(string $hash): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/replica/%s/since/%s', @@ -80,19 +86,23 @@ public function since(string $hash): array \urlencode($this->source), \urlencode($hash) ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } - public function export(): array + public function export(): Promise { - return $this->verifyAndReturnResponse($this->client->sendRequest($this->requestFactory->createRequest( + return $this->client->sendAsyncRequest($this->requestFactory->createRequest( 'GET', \sprintf( '%s/chronicle/replica/%s/export', $this->chronicleUri, \urlencode($this->source) ) - ))); + ))->then(function (ResponseInterface $response) { + return $this->verifyAndReturnResponse($response); + }); } } diff --git a/tests/ApiTest.php b/tests/ApiTest.php index 3ec09bd..1a64912 100644 --- a/tests/ApiTest.php +++ b/tests/ApiTest.php @@ -4,7 +4,8 @@ namespace Lookyman\Chronicle; -use Http\Client\HttpClient; +use Http\Client\HttpAsyncClient; +use Http\Promise\FulfilledPromise; use Interop\Http\Factory\RequestFactoryInterface; use PHPUnit\Framework\TestCase; use ParagonIE\ConstantTime\Base64UrlSafe; @@ -34,8 +35,10 @@ public function testLastHash() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -54,7 +57,7 @@ public function testLastHash() $publicKey ); - self::assertEquals(['result'], $api->lastHash()); + self::assertEquals(['result'], $api->lastHash()->wait()); } public function testLookup() @@ -69,8 +72,10 @@ public function testLookup() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -89,7 +94,7 @@ public function testLookup() $publicKey ); - self::assertEquals(['result'], $api->lookup('foo')); + self::assertEquals(['result'], $api->lookup('foo')->wait()); } public function testSince() @@ -104,8 +109,10 @@ public function testSince() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -124,7 +131,7 @@ public function testSince() $publicKey ); - self::assertEquals(['result'], $api->since('foo')); + self::assertEquals(['result'], $api->since('foo')->wait()); } public function testExport() @@ -139,8 +146,10 @@ public function testExport() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -159,7 +168,7 @@ public function testExport() $publicKey ); - self::assertEquals(['result'], $api->export()); + self::assertEquals(['result'], $api->export()->wait()); } public function testIndex() @@ -174,8 +183,10 @@ public function testIndex() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -194,7 +205,7 @@ public function testIndex() $publicKey ); - self::assertEquals(['result'], $api->index()); + self::assertEquals(['result'], $api->index()->wait()); } public function testRegister() @@ -227,8 +238,10 @@ public function testRegister() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -254,7 +267,7 @@ public function testRegister() self::assertEquals(['result'], $api->register( new SigningPublicKey((string) Base64UrlSafe::decode('aAtpZ1BH8GbmKbXx7IN7_pTN9fM9WwGiZmKUajsLi6Q=')), 'foo' - )); + )->wait()); } public function testRevoke() @@ -287,8 +300,10 @@ public function testRevoke() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -314,7 +329,7 @@ public function testRevoke() self::assertEquals(['result'], $api->revoke( 'foo', new SigningPublicKey((string) Base64UrlSafe::decode('aAtpZ1BH8GbmKbXx7IN7_pTN9fM9WwGiZmKUajsLi6Q=')) - )); + )->wait()); } public function testPublish() @@ -343,8 +358,10 @@ public function testPublish() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -367,12 +384,12 @@ public function testPublish() 'client' ); - self::assertEquals(['result'], $api->publish('foo')); + self::assertEquals(['result'], $api->publish('foo')->wait()); } public function testReplica() { - $client = $this->createMock(HttpClient::class); + $client = $this->createMock(HttpAsyncClient::class); $requestFactory = $this->createMock(RequestFactoryInterface::class); @@ -420,8 +437,10 @@ public function testReplicas() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -440,7 +459,7 @@ public function testReplicas() $publicKey ); - self::assertEquals(['result'], $api->replicas()); + self::assertEquals(['result'], $api->replicas()->wait()); } } diff --git a/tests/ReplicaTest.php b/tests/ReplicaTest.php index caf68a2..349f1eb 100644 --- a/tests/ReplicaTest.php +++ b/tests/ReplicaTest.php @@ -4,7 +4,8 @@ namespace Lookyman\Chronicle; -use Http\Client\HttpClient; +use Http\Client\HttpAsyncClient; +use Http\Promise\FulfilledPromise; use Interop\Http\Factory\RequestFactoryInterface; use PHPUnit\Framework\TestCase; use ParagonIE\ConstantTime\Base64UrlSafe; @@ -33,8 +34,10 @@ public function testLastHash() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -54,7 +57,7 @@ public function testLastHash() $publicKey ); - self::assertEquals(['result'], $replica->lastHash()); + self::assertEquals(['result'], $replica->lastHash()->wait()); } public function testLookup() @@ -69,8 +72,10 @@ public function testLookup() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -90,7 +95,7 @@ public function testLookup() $publicKey ); - self::assertEquals(['result'], $replica->lookup('foo')); + self::assertEquals(['result'], $replica->lookup('foo')->wait()); } public function testSince() @@ -105,8 +110,10 @@ public function testSince() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -126,7 +133,7 @@ public function testSince() $publicKey ); - self::assertEquals(['result'], $replica->since('foo')); + self::assertEquals(['result'], $replica->since('foo')->wait()); } public function testExport() @@ -141,8 +148,10 @@ public function testExport() $response->expects(self::once())->method('getHeader')->with(Sapient::HEADER_SIGNATURE_NAME) ->willReturn(['Ypkdmzl7uoEmsNf5htTSmRFWKYpQskL5p3ffMjEQq4oHrwrkhQfJ1Pu9v9NF7Mth5Foa6JfSsJLcveU33pUtAQ==']); - $client = $this->createMock(HttpClient::class); - $client->expects(self::once())->method('sendRequest')->with($request)->willReturn($response); + $promise = new FulfilledPromise($response); + + $client = $this->createMock(HttpAsyncClient::class); + $client->expects(self::once())->method('sendAsyncRequest')->with($request)->willReturn($promise); $requestFactory = $this->createMock(RequestFactoryInterface::class); $requestFactory->expects(self::once())->method('createRequest')->with( @@ -162,7 +171,7 @@ public function testExport() $publicKey ); - self::assertEquals(['result'], $replica->export()); + self::assertEquals(['result'], $replica->export()->wait()); } }