From 78a74cdd373732e5689f7d6415a85ab34e14fb46 Mon Sep 17 00:00:00 2001 From: Zach Date: Wed, 29 Sep 2021 15:59:13 -0500 Subject: [PATCH 1/3] added check for null response in the getAccountInfo method --- src/Exceptions/AccountNotFoundException.php | 10 ++++++++++ src/Solana.php | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/Exceptions/AccountNotFoundException.php diff --git a/src/Exceptions/AccountNotFoundException.php b/src/Exceptions/AccountNotFoundException.php new file mode 100644 index 0000000..4bc58e8 --- /dev/null +++ b/src/Exceptions/AccountNotFoundException.php @@ -0,0 +1,10 @@ +client->call('getAccountInfo', [$pubKey, ["encoding" => "jsonParsed"]])->json()['result']['value']; + $accountResponse = $this->client->call('getAccountInfo', [$pubKey, ["encoding" => "jsonParsed"]])->json()['result']['value']; + + if (! $accountResponse) { + throw new AccountNotFoundException("API Error: Account {$pubKey} not found."); + } + + return $accountResponse; } public function getBalance(string $pubKey): float From 84946b66229ee637df3ff8370def6fc418cbdd84 Mon Sep 17 00:00:00 2001 From: Zach Date: Wed, 29 Sep 2021 16:50:00 -0500 Subject: [PATCH 2/3] added orchestra testbench and guzzle. Now, we have ability to test Http client from within unit tests. --- composer.json | 2 ++ src/SolanaRpcClient.php | 4 +++- tests/SolanaTest.php | 26 +++++++++++++++++++++++++- tests/TestCase.php | 10 ++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tests/TestCase.php diff --git a/composer.json b/composer.json index 7032f73..bc12db6 100644 --- a/composer.json +++ b/composer.json @@ -22,10 +22,12 @@ ], "require": { "php": "^7.4 || ~8.0", + "guzzlehttp/guzzle": "^7.3", "illuminate/http": "~8.0" }, "require-dev": { "mockery/mockery": "^1.4", + "orchestra/testbench": "^6.0", "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "^3.5", "tightenco/tlint": "^5.0" diff --git a/src/SolanaRpcClient.php b/src/SolanaRpcClient.php index 30d4e2e..4f6b4ab 100644 --- a/src/SolanaRpcClient.php +++ b/src/SolanaRpcClient.php @@ -17,13 +17,15 @@ class SolanaRpcClient public const TESTNET_ENDPOINT = 'https://api.testnet.solana.com'; public const MAINNET_ENDPOINT = 'https://api.mainnet-beta.solana.com'; + public static $randomKeyOverrideForUnitTetsing = null; + protected $endpoint; protected $randomKey; public function __construct(string $endpoint) { $this->endpoint = $endpoint; - $this->randomKey = random_int(5, 25000); + $this->randomKey = static::$randomKeyOverrideForUnitTetsing ?? random_int(5, 25000); } public function call(string $method, array $params = []): Response diff --git a/tests/SolanaTest.php b/tests/SolanaTest.php index e4d7d2b..fc55844 100644 --- a/tests/SolanaTest.php +++ b/tests/SolanaTest.php @@ -3,8 +3,9 @@ namespace Tighten\SolanaPhpSdk\Tests; use Illuminate\Http\Client\Response; +use Illuminate\Support\Facades\Http; use Mockery as M; -use PHPUnit\Framework\TestCase; +use Tighten\SolanaPhpSdk\Exceptions\AccountNotFoundException; use Tighten\SolanaPhpSdk\Solana; use Tighten\SolanaPhpSdk\SolanaRpcClient; @@ -27,6 +28,29 @@ public function it_passes_undefined_calls_through_magically() $this->assertTrue(true); // Keep PHPUnit from squawking; there must be a better way? } + /** @test */ + public function it_will_throw_exception_when_rpc_account_response_is_null() + { + Http::fake([ + SolanaRpcClient::DEVNET_ENDPOINT => Http::response([ + 'jsonrpc' => '2.0', + 'result' => [ + 'context' => [ + 'slot' => 6440 + ], + 'value' => null, // no account data. + ], + 'id' => 4051, + ]), + ]); + + SolanaRpcClient::$randomKeyOverrideForUnitTetsing = 4051; + $solana = new Solana(new SolanaRpcClient(SolanaRpcClient::DEVNET_ENDPOINT)); + + $this->expectException(AccountNotFoundException::class); + $solana->getAccountInfo('abc123'); + } + protected function fakeResponse(): Response { return new Response(new class diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..9cb7176 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,10 @@ + Date: Fri, 8 Oct 2021 23:13:03 -0500 Subject: [PATCH 3/3] remove the random key override for unit tests. Using a getter to fetch the random number from unit test. That is much better :D --- src/SolanaRpcClient.php | 12 +++++++++--- tests/SolanaTest.php | 8 ++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/SolanaRpcClient.php b/src/SolanaRpcClient.php index 4f6b4ab..02e4e25 100644 --- a/src/SolanaRpcClient.php +++ b/src/SolanaRpcClient.php @@ -17,15 +17,13 @@ class SolanaRpcClient public const TESTNET_ENDPOINT = 'https://api.testnet.solana.com'; public const MAINNET_ENDPOINT = 'https://api.mainnet-beta.solana.com'; - public static $randomKeyOverrideForUnitTetsing = null; - protected $endpoint; protected $randomKey; public function __construct(string $endpoint) { $this->endpoint = $endpoint; - $this->randomKey = static::$randomKeyOverrideForUnitTetsing ?? random_int(5, 25000); + $this->randomKey = random_int(5, 25000); } public function call(string $method, array $params = []): Response @@ -68,4 +66,12 @@ protected function validateResponse(Response $response, string $method, array $p throw new GenericException('API Error: status code ' . $response->getStatusCode()); } } + + /** + * @return int + */ + public function getRandomKey(): int + { + return $this->randomKey; + } } diff --git a/tests/SolanaTest.php b/tests/SolanaTest.php index fc55844..0cca4d2 100644 --- a/tests/SolanaTest.php +++ b/tests/SolanaTest.php @@ -31,6 +31,9 @@ public function it_passes_undefined_calls_through_magically() /** @test */ public function it_will_throw_exception_when_rpc_account_response_is_null() { + $client = new SolanaRpcClient(SolanaRpcClient::DEVNET_ENDPOINT); + $expectedIdInHttpResponse = $client->getRandomKey(); + $solana = new Solana($client); Http::fake([ SolanaRpcClient::DEVNET_ENDPOINT => Http::response([ 'jsonrpc' => '2.0', @@ -40,13 +43,10 @@ public function it_will_throw_exception_when_rpc_account_response_is_null() ], 'value' => null, // no account data. ], - 'id' => 4051, + 'id' => $expectedIdInHttpResponse, ]), ]); - SolanaRpcClient::$randomKeyOverrideForUnitTetsing = 4051; - $solana = new Solana(new SolanaRpcClient(SolanaRpcClient::DEVNET_ENDPOINT)); - $this->expectException(AccountNotFoundException::class); $solana->getAccountInfo('abc123'); }