From 87ff887cd686847393d6ce86f6cf52d2a7b15dba Mon Sep 17 00:00:00 2001 From: yash30201 <54198301+yash30201@users.noreply.github.com> Date: Fri, 10 May 2024 11:32:12 +0000 Subject: [PATCH] Refactor all the remaining unit and snippets tests --- .../DatastoreOperationRefreshTrait.php | 47 -- .../tests/Snippet/DatastoreClientTest.php | 2 +- .../Snippet/DatastoreSessionHandlerTest.php | 14 +- Datastore/tests/Snippet/EntityTest.php | 20 +- .../Snippet/Query/AggregationQueryTest.php | 41 +- .../tests/Snippet/Query/GqlQueryTest.php | 31 +- Datastore/tests/Snippet/Query/QueryTest.php | 31 +- .../tests/Snippet/ReadOnlyTransactionTest.php | 26 +- Datastore/tests/Snippet/TransactionTest.php | 28 +- .../System/DatastoreMultipleDbTestCase.php | 2 +- .../System/DatastoreSessionHandlerTest.php | 4 +- .../System/QueryResultPaginationTest.php | 4 +- Datastore/tests/System/SaveAndModifyTest.php | 8 +- Datastore/tests/Unit/DatastoreClientTest.php | 370 ++++++----- Datastore/tests/Unit/OperationTest.php | 417 +++++++------ Datastore/tests/Unit/TransactionTest.php | 305 +++++----- .../tests/Unit/V1/DatastoreClientTest.php | 572 ------------------ 17 files changed, 668 insertions(+), 1254 deletions(-) delete mode 100644 Datastore/tests/Unit/V1/DatastoreClientTest.php diff --git a/Core/src/Testing/DatastoreOperationRefreshTrait.php b/Core/src/Testing/DatastoreOperationRefreshTrait.php index 2a46f56d776e..d96bc35a0328 100644 --- a/Core/src/Testing/DatastoreOperationRefreshTrait.php +++ b/Core/src/Testing/DatastoreOperationRefreshTrait.php @@ -75,53 +75,6 @@ public function refreshOperation($stub, RequestHandler $requestHandler, array $o return $stub; } - /** - * Helper method for Unit and Snippet test classes. This mocks the - * $requestHandler class property present in the Test Class with - * given arguments. - * - * @param string $methodName The method name to mock in RequestHandler::sendRequest - * @param array $params The parameters to look for in the - * array equivalent of rpc request. - * @param mixed $returnValue The value to be returned by sendRequest mock. - * @param null|int $shouldBeCalledTimes Adds a shouldBeCalled prophecy. Defaults to `null`, implying nothing is added. - * [ - * `0` => `shouldBeCalled`, - * Non zero positive integer $x => `shouldBeCalledTimes($x)` - * ] - */ - private function mockSendRequest($methodName, $params, $returnValue, $shouldBeCalledTimes = null) - { - $serializer = $this->getSerializer(); - - $prophecy = $this->requestHandler->sendRequest( - DatastoreClient::class, - $methodName, - Argument::that(function ($arg) use ($methodName, $params, $serializer) { - $requestName = ucfirst($methodName . 'Request'); - $x = explode('\\', get_class($arg)); - $argName = end($x); - - if ($requestName != $argName) { - return false; - } - $data = $serializer->encodeMessage($arg); - return array_replace_recursive($data, $params) == $data; - }), - Argument::cetera() - ); - - if (!is_null($shouldBeCalledTimes)) { - if ($shouldBeCalledTimes == 0) { - $prophecy->shouldBeCalled(); - } else { - $prophecy->shouldBeCalledTimes($shouldBeCalledTimes); - } - } - - $prophecy->willReturn($returnValue); - } - /** * @return Serializer */ diff --git a/Datastore/tests/Snippet/DatastoreClientTest.php b/Datastore/tests/Snippet/DatastoreClientTest.php index 670a1bcbf1e5..762dc6606dba 100644 --- a/Datastore/tests/Snippet/DatastoreClientTest.php +++ b/Datastore/tests/Snippet/DatastoreClientTest.php @@ -819,7 +819,7 @@ private function validateTransactionOptions($data, $type, array $options = []) } if (!empty((array) $options)) { - return $options === $data['transactionOptions'][$type]; + return $options == $data['transactionOptions'][$type]; } else { if (is_array($data['transactionOptions'][$type]) and isset($data['transactionOptions'][$type]['readTime'])) { diff --git a/Datastore/tests/Snippet/DatastoreSessionHandlerTest.php b/Datastore/tests/Snippet/DatastoreSessionHandlerTest.php index 39ba63d34070..27dfa55e8dd7 100644 --- a/Datastore/tests/Snippet/DatastoreSessionHandlerTest.php +++ b/Datastore/tests/Snippet/DatastoreSessionHandlerTest.php @@ -80,8 +80,8 @@ public function testClass() $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['keys'][0]['partitionId']['namespaceId'] === 'sessions' - && $data['keys'][0]['path'][0]['kind'] === 'PHPSESSID' + && $data['keys'][0]['partitionId']['namespaceId'] == 'sessions' + && $data['keys'][0]['path'][0]['kind'] == 'PHPSESSID' && isset($data['keys'][0]['path'][0]['name']); }), Argument::cetera() @@ -106,10 +106,10 @@ public function testClass() return isset($data['transaction']) && isset($data['mode']) - && $data['mutations'][0]['upsert']['key']['partitionId']['namespaceId'] === 'sessions' - && $data['mutations'][0]['upsert']['key']['path'][0]['kind'] === 'PHPSESSID' + && $data['mutations'][0]['upsert']['key']['partitionId']['namespaceId'] == 'sessions' + && $data['mutations'][0]['upsert']['key']['path'][0]['kind'] == 'PHPSESSID' && isset($data['mutations'][0]['upsert']['key']['path'][0]['name']) - && $data['mutations'][0]['upsert']['properties']['data']['stringValue'] === 'name|'.serialize('Bob') + && $data['mutations'][0]['upsert']['properties']['data']['stringValue'] == 'name|'.serialize('Bob') && isset($data['mutations'][0]['upsert']['properties']['t']); }), Argument::cetera() @@ -140,8 +140,8 @@ public function testClassErrorHandler() $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['keys'][0]['partitionId']['namespaceId'] === 'sessions' - && $data['keys'][0]['path'][0]['kind'] === 'PHPSESSID' + && $data['keys'][0]['partitionId']['namespaceId'] == 'sessions' + && $data['keys'][0]['path'][0]['kind'] == 'PHPSESSID' && isset($data['keys'][0]['path'][0]['name']); }), Argument::cetera() diff --git a/Datastore/tests/Snippet/EntityTest.php b/Datastore/tests/Snippet/EntityTest.php index 8bf42e50df02..91c115ed3120 100644 --- a/Datastore/tests/Snippet/EntityTest.php +++ b/Datastore/tests/Snippet/EntityTest.php @@ -46,7 +46,6 @@ class EntityTest extends SnippetTestCase private $options; private $entity; private $key; - private $serializer; private $requestHandler; public function setUp(): void @@ -68,23 +67,6 @@ public function setUp(): void $this->entity = new Entity($this->key, [], $this->options); $this->requestHandler = $this->prophesize(RequestHandler::class); - - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); } public function testClass() @@ -141,7 +123,7 @@ public function testClassEntityType() $operation = new Operation( $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), 'example_project', 'foo', new EntityMapper('example_project', false, false) diff --git a/Datastore/tests/Snippet/Query/AggregationQueryTest.php b/Datastore/tests/Snippet/Query/AggregationQueryTest.php index 9b4bf0c46d93..776b1bbdba41 100644 --- a/Datastore/tests/Snippet/Query/AggregationQueryTest.php +++ b/Datastore/tests/Snippet/Query/AggregationQueryTest.php @@ -28,6 +28,8 @@ use Google\Cloud\Datastore\Operation; use Google\Cloud\Datastore\Query\AggregationQuery; use Google\Cloud\Datastore\Query\AggregationQueryResult; +use Google\Cloud\Datastore\V1\Client\DatastoreClient as V1DatastoreClient; +use Google\Cloud\Datastore\V1\RunAggregationQueryRequest; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -43,33 +45,16 @@ class AggregationQueryTest extends SnippetTestCase private $datastore; private $operation; private $requestHandler; - private $serializer; public function setUp(): void { $mapper = new EntityMapper('my-awesome-project', true, false); $this->datastore = TestHelpers::stub(DatastoreClient::class, [], ['operation']); $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); $this->operation = TestHelpers::stub(Operation::class, [ $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), 'my-awesome-project', '', $mapper @@ -78,9 +63,12 @@ public function setUp(): void public function testClass() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runAggregationQuery', - [], + Argument::type(RunAggregationQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'aggregationResults' => [ @@ -92,8 +80,7 @@ public function testClass() ], 'readTime' => (new \DateTime())->format('Y-m-d\TH:i:s') .'.000001Z' ] - ], - 0 + ] ); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -111,9 +98,12 @@ public function testClass() public function testClassWithOverAggregation() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runAggregationQuery', - [], + Argument::type(RunAggregationQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'aggregationResults' => [ @@ -125,8 +115,7 @@ public function testClassWithOverAggregation() ], 'readTime' => (new \DateTime())->format('Y-m-d\TH:i:s') .'.000001Z' ] - ], - 0 + ] ); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); diff --git a/Datastore/tests/Snippet/Query/GqlQueryTest.php b/Datastore/tests/Snippet/Query/GqlQueryTest.php index 2dfbc5b783ef..6b37df53926d 100644 --- a/Datastore/tests/Snippet/Query/GqlQueryTest.php +++ b/Datastore/tests/Snippet/Query/GqlQueryTest.php @@ -29,6 +29,8 @@ use Google\Cloud\Datastore\EntityMapper; use Google\Cloud\Datastore\Operation; use Google\Cloud\Datastore\Query\GqlQuery; +use Google\Cloud\Datastore\V1\Client\DatastoreClient as V1DatastoreClient; +use Google\Cloud\Datastore\V1\RunQueryRequest; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -44,31 +46,14 @@ class GqlQueryTest extends SnippetTestCase private $datastore; private $operation; private $requestHandler; - private $serializer; public function setUp(): void { $this->datastore = TestHelpers::stub(DatastoreClient::class, [], ['operation']); $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); $this->operation = TestHelpers::stub(Operation::class, [ $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), 'my-awesome-project', '', new EntityMapper('my-awesome-project', true, false) @@ -77,9 +62,12 @@ public function setUp(): void public function testClass() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [], + Argument::type(RunQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'entityResults' => [ @@ -97,8 +85,7 @@ public function testClass() ] ] ] - ], - 0 + ] ); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); diff --git a/Datastore/tests/Snippet/Query/QueryTest.php b/Datastore/tests/Snippet/Query/QueryTest.php index 430bb07b9fac..cecc9db76c85 100644 --- a/Datastore/tests/Snippet/Query/QueryTest.php +++ b/Datastore/tests/Snippet/Query/QueryTest.php @@ -30,6 +30,8 @@ use Google\Cloud\Datastore\Operation; use Google\Cloud\Datastore\Query\Filter; use Google\Cloud\Datastore\Query\Query; +use Google\Cloud\Datastore\V1\Client\DatastoreClient as V1DatastoreClient; +use Google\Cloud\Datastore\V1\RunQueryRequest; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -46,7 +48,6 @@ class QueryTest extends SnippetTestCase private $operation; private $query; private $requestHandler; - private $serializer; public function setUp(): void { @@ -54,25 +55,9 @@ public function setUp(): void $this->datastore = TestHelpers::stub(DatastoreClient::class, [], ['operation']); $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); $this->operation = TestHelpers::stub(Operation::class, [ $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), 'my-awesome-project', '', $mapper @@ -83,9 +68,12 @@ public function setUp(): void public function testClass() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [], + Argument::type(RunQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'entityResults' => [ @@ -104,8 +92,7 @@ public function testClass() ], 'moreResults' => 'no' ] - ], - 0 + ] ); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); diff --git a/Datastore/tests/Snippet/ReadOnlyTransactionTest.php b/Datastore/tests/Snippet/ReadOnlyTransactionTest.php index 596f7455636d..ee403eaa6166 100644 --- a/Datastore/tests/Snippet/ReadOnlyTransactionTest.php +++ b/Datastore/tests/Snippet/ReadOnlyTransactionTest.php @@ -52,33 +52,15 @@ class ReadOnlyTransactionTest extends SnippetTestCase private $transaction; private $client; private $key; - private $serializer; private $requestHandler; public function setUp(): void { $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); - $operation = new Operation( $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), self::PROJECT, '', new EntityMapper(self::PROJECT, false, false) @@ -171,7 +153,7 @@ public function testLookup() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( @@ -215,7 +197,7 @@ public function testLookupBatch() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( @@ -279,7 +261,7 @@ public function testRunQuery() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( diff --git a/Datastore/tests/Snippet/TransactionTest.php b/Datastore/tests/Snippet/TransactionTest.php index 016bb32046b1..14999bd39ffb 100644 --- a/Datastore/tests/Snippet/TransactionTest.php +++ b/Datastore/tests/Snippet/TransactionTest.php @@ -56,33 +56,15 @@ class TransactionTest extends SnippetTestCase private $transaction; private $client; private $key; - private $serializer; private $requestHandler; public function setUp(): void { $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); - $operation = new Operation( $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), self::PROJECT, '', new EntityMapper(self::PROJECT, false, false) @@ -282,7 +264,7 @@ public function testLookup() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( @@ -326,7 +308,7 @@ public function testLookupBatch() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( @@ -390,7 +372,7 @@ public function testRunQuery() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( @@ -440,7 +422,7 @@ public function testRunAggregationQuery() Argument::that(function ($req) { $data = $this->getSerializer()->encodeMessage($req); return isset($data['readOptions']['transaction']) - && $data['readOptions']['transaction'] === self::TRANSACTION; + && $data['readOptions']['transaction'] == self::TRANSACTION; }), Argument::cetera() )->willReturn( diff --git a/Datastore/tests/System/DatastoreMultipleDbTestCase.php b/Datastore/tests/System/DatastoreMultipleDbTestCase.php index 6dc6faa83a01..a6deb1a46d61 100644 --- a/Datastore/tests/System/DatastoreMultipleDbTestCase.php +++ b/Datastore/tests/System/DatastoreMultipleDbTestCase.php @@ -118,7 +118,7 @@ private function checkTestDbExists($client) if (!array_key_exists('name', $database)) { continue; } - if ($database['name'] === $dbId) { + if ($database['name'] == $dbId) { return true; } } diff --git a/Datastore/tests/System/DatastoreSessionHandlerTest.php b/Datastore/tests/System/DatastoreSessionHandlerTest.php index a1263847eb79..261208c8adae 100644 --- a/Datastore/tests/System/DatastoreSessionHandlerTest.php +++ b/Datastore/tests/System/DatastoreSessionHandlerTest.php @@ -59,7 +59,7 @@ public function testSessionHandler() $keys = []; foreach ($res as $e) { if (!$hasEntity) { - $hasEntity = $e['data'] === $storedValue; + $hasEntity = $e['data'] == $storedValue; } self::$localDeletionQueue->add($e->key()); @@ -103,7 +103,7 @@ public function testMultipleDbSessionHandler() $hasEntity = false; foreach ($res as $e) { if (!$hasEntity) { - $hasEntity = $e['data'] === $storedValue; + $hasEntity = $e['data'] == $storedValue; } self::$localDeletionQueue->add($e->key()); diff --git a/Datastore/tests/System/QueryResultPaginationTest.php b/Datastore/tests/System/QueryResultPaginationTest.php index 2fa23d883a86..acf67f650e3a 100644 --- a/Datastore/tests/System/QueryResultPaginationTest.php +++ b/Datastore/tests/System/QueryResultPaginationTest.php @@ -54,7 +54,7 @@ public static function setUpBeforeClass(): void 'a' => rand(1, 10), ]); - if (count($set) === 100) { + if (count($set) == 100) { $client->insertBatch($set); $set = []; } @@ -80,7 +80,7 @@ public static function tearDownAfterClass(): void foreach ($client->runQuery($q) as $entity) { $set[] = $entity->key(); - if (count($set) === 100) { + if (count($set) == 100) { $client->deleteBatch($set); $set = []; } diff --git a/Datastore/tests/System/SaveAndModifyTest.php b/Datastore/tests/System/SaveAndModifyTest.php index c12b30a15b6d..e706b62ef6ed 100644 --- a/Datastore/tests/System/SaveAndModifyTest.php +++ b/Datastore/tests/System/SaveAndModifyTest.php @@ -188,10 +188,10 @@ public function testEmptyGeoPoint(DatastoreClient $client) $e = $client->lookup($key); $this->assertInstanceOf(GeoPoint::class, $e['geo']); $this->assertTrue( - $e['geo']->latitude() === null || $e['geo']->latitude() === 0.0 + $e['geo']->latitude() == null || $e['geo']->latitude() == 0.0 ); $this->assertTrue( - $e['geo']->longitude() === null || $e['geo']->longitude() === 0.0 + $e['geo']->longitude() == null || $e['geo']->longitude() == 0.0 ); $client->upsert($e); @@ -199,10 +199,10 @@ public function testEmptyGeoPoint(DatastoreClient $client) $e = $client->lookup($key); $this->assertInstanceOf(GeoPoint::class, $e['geo']); $this->assertTrue( - $e['geo']->latitude() === null || $e['geo']->latitude() === 0.0 + $e['geo']->latitude() == null || $e['geo']->latitude() == 0.0 ); $this->assertTrue( - $e['geo']->longitude() === null || $e['geo']->longitude() === 0.0 + $e['geo']->longitude() == null || $e['geo']->longitude() == 0.0 ); } } diff --git a/Datastore/tests/Unit/DatastoreClientTest.php b/Datastore/tests/Unit/DatastoreClientTest.php index d7bf1072074c..281b2f20c7bf 100644 --- a/Datastore/tests/Unit/DatastoreClientTest.php +++ b/Datastore/tests/Unit/DatastoreClientTest.php @@ -38,8 +38,18 @@ use Google\Cloud\Datastore\Query\QueryInterface; use Google\Cloud\Datastore\ReadOnlyTransaction; use Google\Cloud\Datastore\Transaction; +use Google\Cloud\Datastore\V1\AllocateIdsRequest; +use Google\Cloud\Datastore\V1\BeginTransactionRequest; +use Google\Cloud\Datastore\V1\Client\DatastoreClient as V1DatastoreClient; +use Google\Cloud\Datastore\V1\CommitRequest; use Google\Cloud\Datastore\V1\CommitRequest\Mode; +use Google\Cloud\Datastore\V1\LookupRequest; +use Google\Cloud\Datastore\V1\PartitionId; +use Google\Cloud\Datastore\V1\RunAggregationQueryRequest; +use Google\Cloud\Datastore\V1\RunQueryRequest; +use Google\Cloud\Datastore\V1\TransactionOptions; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; /** @@ -57,7 +67,6 @@ class DatastoreClientTest extends TestCase private $client; private $requestHandler; - private $serializer; public function setUp(): void { @@ -70,23 +79,6 @@ public function setUp(): void 'operation' ]); $this->requestHandler = $this->prophesize(RequestHandler::class); - - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); } public function testKeyIncomplete() @@ -188,12 +180,16 @@ public function testAllocateId($method, $batch = false) $keyWithId = clone $key; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$key->keyObject()]], - ['keys' => [$keyWithId->keyObject()]], - 0 - ); + Argument::that(function ($request) use ($key) { + $data = $this->getSerializer()->encodeMessage($request); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled() + ->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -221,14 +217,16 @@ public function allocateIdProvider() */ public function testTransaction($method, $type, $key) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'beginTransaction', - [ - 'projectId' => self::PROJECT, - 'transactionOptions' => [($method == 'transaction' ? 'readWrite' : 'readOnly') => []] - ], - ['transaction' => self::TRANSACTION] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['projectId'] == self::PROJECT + && isset($data['transactionOptions'][$key]); + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['transaction' => self::TRANSACTION]); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -242,22 +240,28 @@ public function testTransaction($method, $type, $key) */ public function testTransactionWithOptions($method, $type, $key) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'beginTransaction', - [ - 'projectId' => self::PROJECT, - 'transactionOptions' => [$key => []] - ], - ['transaction' => self::TRANSACTION] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['projectId'] == self::PROJECT + && isset($data['transactionOptions'][$key]); + }), + Argument::cetera() + )->shouldBeCalled() + ->willReturn(['transaction' => self::TRANSACTION]); // Make sure the correct transaction ID was injected. - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - ['readOptions' => ['transaction' => self::TRANSACTION]], - [], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['readOptions']['transaction'] == self::TRANSACTION; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -282,15 +286,17 @@ public function transactionProvider() */ public function testEntityMutations($method, $mutation, $key) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL && + array_replace_recursive($data['mutations'][0], [$method => $mutation]) + == $data['mutations'][0]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -307,15 +313,17 @@ public function testEntityMutations($method, $mutation, $key) */ public function testEntityMutationsBatch($method, $mutation, $key) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL && + array_replace_recursive($data['mutations'][0], [$method => $mutation]) + == $data['mutations'][0]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -339,23 +347,29 @@ public function mutationsProvider() */ public function testMutationsWithPartialKey($method, $mutation, $key, $id) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL && + array_replace_recursive($data['mutations'][0], [$method => $mutation]) + == $data['mutations'][0]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $keyWithId = clone $key; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$key->keyObject()]], - ['keys' => [$keyWithId->keyObject()]] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -370,23 +384,30 @@ public function testMutationsWithPartialKey($method, $mutation, $key, $id) */ public function testBatchMutationsWithPartialKey($method, $mutation, $key, $id) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL && + array_replace_recursive($data['mutations'][0], [$method => $mutation]) + == $data['mutations'][0]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $keyWithId = clone $key; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$key->keyObject()]], - ['keys' => [$keyWithId->keyObject()]] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + $x = array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -409,17 +430,19 @@ public function testSingleMutationConflict() { $this->expectException(\DomainException::class); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [], + Argument::type(CommitRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'mutationResults' => [ [ 'conflictDetected' => true ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -434,15 +457,17 @@ public function testDelete() { $key = $this->client->key('Person', 'John'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [['delete' => $key->keyObject()]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL + && array_replace_recursive($data['mutations'][0]['delete'],$key->keyObject()) + == $data['mutations'][0]['delete']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -457,15 +482,17 @@ public function testDeleteBatch() { $key = $this->client->key('Person', 'John'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [['delete' => $key->keyObject()]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL + && array_replace_recursive($data['mutations'][0]['delete'],$key->keyObject()) + == $data['mutations'][0]['delete']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -480,17 +507,22 @@ public function testLookup() { $key = $this->client->key('Person', 'John'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['keys' => [$key->keyObject()]], + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'found' => [ [ 'entity' => $this->entityArray($key) ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -507,17 +539,22 @@ public function testLookupMissing() { $key = $this->client->key('Person', 'John'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['keys' => [$key->keyObject()]], + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'missing' => [ [ 'entity' => $this->entityArray($key) ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -533,9 +570,15 @@ public function testLookupBatch() { $key = $this->client->key('Person', 'John'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['keys' => [$key->keyObject()]], + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'found' => [ [ @@ -550,8 +593,7 @@ public function testLookupBatch() 'deferred' => [ $key->keyObject() ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -570,17 +612,22 @@ public function testLookupBatchWithReadTime() $key = $this->client->key('Person', 'John'); $time = new Timestamp(new \DateTime()); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['readOptions' => ['readTime' => $time]], + Argument::that(function ($req) use ($time) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['readOptions']['readTime'] == $time; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'found' => [ [ 'entity' => $this->entityArray($key) ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -596,20 +643,23 @@ public function testLookupWithReadTime() $key = $this->client->key('Person', 'John'); $time = new Timestamp(new \DateTime()); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [ - 'keys' => [$key->keyObject()], - 'readOptions' => ['readTime' => $time] - ], + Argument::that(function ($req) use ($key, $time) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys'] + && $data['readOptions']['readTime'] == $time; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'found' => [ [ 'entity' => $this->entityArray($key) ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -640,12 +690,16 @@ public function testRunQuery() { $key = $this->client->key('Person', 'John'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'SELECT 1=1'] - ], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['gqlQuery']['queryString'] == 'SELECT 1=1'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'entityResults' => [ @@ -654,8 +708,7 @@ public function testRunQuery() ] ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -672,12 +725,16 @@ public function testRunQuery() public function testRunAggregationQuery() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runAggregationQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'AGGREGATE (COUNT(*)) over (SELECT 1=1)'], - ], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['gqlQuery']['queryString'] == 'AGGREGATE (COUNT(*)) over (SELECT 1=1)'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'aggregationResults' => [ @@ -687,8 +744,7 @@ public function testRunAggregationQuery() ], 'readTime' => (new \DateTime())->format('Y-m-d\TH:i:s') .'.000001Z' ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -711,12 +767,16 @@ public function testRunAggregationQuery() */ public function testAggregationQueryWithDifferentReturnTypes($response, $expected) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runAggregationQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'foo bar'], - ], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['gqlQuery']['queryString'] == 'foo bar'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'aggregationResults' => [ @@ -726,8 +786,7 @@ public function testAggregationQueryWithDifferentReturnTypes($response, $expecte ], 'readTime' => (new \DateTime())->format('Y-m-d\TH:i:s') .'.000001Z' ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ @@ -751,13 +810,17 @@ public function testRunQueryWithReadTime() $key = $this->client->key('Person', 'John'); $time = new Timestamp(new \DateTime()); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'SELECT 1=1'], - 'readOptions' => ['readTime' => $time] - ], + Argument::that(function ($req) use ($time) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['gqlQuery']['queryString'] == 'SELECT 1=1' + && $data['readOptions']['readTime'] == $time; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'entityResults' => [ @@ -766,8 +829,7 @@ public function testRunQueryWithReadTime() ] ] ] - ], - 0 + ] ); $this->refreshOperation($this->client, $this->requestHandler->reveal(), [ diff --git a/Datastore/tests/Unit/OperationTest.php b/Datastore/tests/Unit/OperationTest.php index 42fa70e9e4f0..a25bd7eee617 100644 --- a/Datastore/tests/Unit/OperationTest.php +++ b/Datastore/tests/Unit/OperationTest.php @@ -30,9 +30,10 @@ use Google\Cloud\Datastore\Query\GqlQuery; use Google\Cloud\Datastore\Query\Query; use Google\Cloud\Datastore\Query\QueryInterface; -use Google\Cloud\Datastore\V1\Client\DatastoreClient; +use Google\Cloud\Datastore\V1\Client\DatastoreClient as V1DatastoreClient; use Google\Cloud\Datastore\V1\CommitRequest\Mode; use Google\Cloud\Datastore\V1\LookupRequest; +use Google\Cloud\Datastore\V1\RunQueryRequest; use InvalidArgumentException; use PHPUnit\Framework\TestCase; use Prophecy\Argument; @@ -54,30 +55,13 @@ class OperationTest extends TestCase private $operation; private $requestHandler; - private $serializer; public function setUp(): void { $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); $this->operation = TestHelpers::stub(Operation::class, [ $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), self::PROJECT, null, new EntityMapper('foo', true, false), @@ -253,11 +237,15 @@ public function testAllocateIds() $keyWithId = clone $key; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$key->keyObject()]], - ['keys' => [$keyWithId->keyObject()]] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -280,12 +268,12 @@ public function testLookup() { $key = $this->operation->key('foo', 'Bar'); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - [], - 0 - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -297,11 +285,12 @@ public function testLookup() public function testLookupFound() { $body = json_decode(file_get_contents(Fixtures::ENTITY_BATCH_LOOKUP_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $body,] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $body,]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -322,11 +311,12 @@ public function testLookupMissing() { $body = json_decode(file_get_contents(Fixtures::ENTITY_BATCH_LOOKUP_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['missing' => $body,] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['missing' => $body,]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -345,11 +335,12 @@ public function testLookupDeferred() { $body = json_decode(file_get_contents(Fixtures::ENTITY_BATCH_LOOKUP_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['deferred' => [$body[0]['entity']['key']]] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['deferred' => [$body[0]['entity']['key']]]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -364,12 +355,16 @@ public function testLookupDeferred() public function testLookupWithReadOptionsFromTransaction() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['readOptions' => ['transaction' => 'foo']], - [], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['readOptions']['transaction'] == 'foo'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $k = new Key('test-project', [ @@ -381,12 +376,15 @@ public function testLookupWithReadOptionsFromTransaction() public function testLookupWithReadOptionsFromReadConsistency() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['readOptions' => ['readConsistency' => 123]], - [], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['readOptions']['readConsistency'] == 123; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $k = new Key('test-project', [ @@ -426,11 +424,13 @@ public function testLookupWithSort() ]); } - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $data['entities']] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $data['entities']]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $res = $this->operation->lookup($keys, [ @@ -455,14 +455,15 @@ public function testLookupWithoutSort() ]); } - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - [ - 'found' => $data['entities'], - 'missing' => $data['missing'], - ] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn([ + 'found' => $data['entities'], + 'missing' => $data['missing'], + ]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $res = $this->operation->lookup($keys); @@ -490,11 +491,13 @@ public function testLookupWithSortAndMissingKey() ]); } - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $data['entities'],] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $data['entities'],]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $res = $this->operation->lookup($keys, [ @@ -527,11 +530,13 @@ public function testLookupInvalidKey() public function testRunQuery() { $queryResult = json_decode(file_get_contents(Fixtures::QUERY_RESULTS_FIXTURE()), true); - $this->mockSendRequest( + + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [], - $queryResult['notPaged'] - ); + Argument::type(RunQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn($queryResult['notPaged']); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -559,23 +564,23 @@ public function testRunQueryPaged($query) $outerThis = $this; $this->requestHandler->sendRequest( - DatastoreClient::class, + V1DatastoreClient::class, 'runQuery', Argument::cetera() - )->will(function ($args, $mock) use ($queryResult, $outerThis) { - // The 2nd call will return the 2nd page of results! - $mock->sendRequest( - DatastoreClient::class, - 'runQuery', - Argument::that(function ($arg) use ($queryResult, $outerThis) { - $data = $outerThis->serializer->encodeMessage($arg); - $x = $data['query']['startCursor'] === $queryResult['paged'][0]['batch']['endCursor']; - return $data['query']['startCursor'] === $queryResult['paged'][0]['batch']['endCursor']; - }), - Argument::any() - )->willReturn($queryResult['paged'][1]); - return $queryResult['paged'][0]; - }); + )->will(function ($args, $mock) use ($queryResult, $outerThis) { + // The 2nd call will return the 2nd page of results! + $mock->sendRequest( + V1DatastoreClient::class, + 'runQuery', + Argument::that(function ($arg) use ($queryResult, $outerThis) { + $data = $outerThis->getSerializer()->encodeMessage($arg); + return $data['query']['startCursor'] == $queryResult['paged'][0]['batch']['endCursor']; + }), + Argument::any() + )->willReturn($queryResult['paged'][1]); + return $queryResult['paged'][0]; + } + ); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -602,11 +607,12 @@ public function queries() public function testRunQueryNoResults() { $queryResult = json_decode(file_get_contents(Fixtures::QUERY_RESULTS_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [], - $queryResult['noResults'] - ); + Argument::type(RunQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn($queryResult['noResults']); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -625,12 +631,12 @@ public function testRunQueryNoResults() public function testRunQueryWithReadOptionsFromTransaction() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [], - [], - 0 - ); + Argument::type(RunQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -644,12 +650,12 @@ public function testRunQueryWithReadOptionsFromTransaction() public function testRunQueryWithReadOptionsFromReadConsistency() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [], - [], - 0 - ); + Argument::type(RunQueryRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -664,7 +670,7 @@ public function testRunQueryWithReadOptionsFromReadConsistency() public function testRunQueryWithoutReadOptions() { $this->requestHandler->sendRequest( - DatastoreClient::class, + V1DatastoreClient::class, 'runQuery', Argument::that(function ($req) { return !$req->hasReadOptions(); @@ -684,12 +690,15 @@ public function testRunQueryWithoutReadOptions() public function testRunQueryWithDatabaseIdOverride() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - ['databaseId' => 'otherDatabaseId'], - [], - 1 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['databaseId'] == 'otherDatabaseId'; + }), + Argument::cetera() + )->shouldBeCalledTimes(1)->willReturn([]); $mapper = new EntityMapper('foo', true, false); $query = new Query($mapper); @@ -703,15 +712,15 @@ public function testRunQueryWithDatabaseIdOverride() public function testCommit() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::NON_TRANSACTIONAL, - 'mutations' => [] - ], - ['foo'], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::NON_TRANSACTIONAL; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['foo']); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -720,15 +729,15 @@ public function testCommit() public function testCommitInTransaction() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [] - ], - ['foo'], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['mode'] == Mode::TRANSACTIONAL; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['foo']); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -740,7 +749,7 @@ public function testCommitInTransaction() public function testCommitWithMutation() { $this->requestHandler->sendRequest( - DatastoreClient::class, + V1DatastoreClient::class, 'commit', Argument::that(fn ($arg) => (count($arg->getMutations()) == 1)), Argument::any() @@ -758,12 +767,15 @@ public function testCommitWithMutation() public function testCommitWithDatabaseIdOverride() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - ['databaseId' => 'otherDatabaseId'], - [], - 1 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['databaseId'] == 'otherDatabaseId'; + }), + Argument::cetera() + )->shouldBeCalledTimes(1)->willReturn([]); $this->operation->commit( [], @@ -773,12 +785,16 @@ public function testCommitWithDatabaseIdOverride() public function testRollback() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'rollback', - ['projectId' => self::PROJECT, 'transaction' => 'bar'], - null, - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['projectId'] == self::PROJECT + && $data['transaction'] == 'bar'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(null); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -794,11 +810,15 @@ public function testAllocateIdsToEntities() $keyWithId = clone $partialKey; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$partialKey->keyObject()]], - ['keys' => [$keyWithId->keyObject()]] - ); + Argument::that(function ($req) use ($partialKey) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$partialKey->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -821,7 +841,7 @@ public function testMutate() $id = 12345; $this->requestHandler->sendRequest( - DatastoreClient::class, + V1DatastoreClient::class, 'commit', Argument::that( fn ($arg) => (count($arg->getMutations()) == 1 && $arg->getMutations()[0]->hasInsert()) @@ -840,11 +860,16 @@ public function testMutate() public function testMutateWithBaseVersion() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - ['mutations' => [['baseVersion' => 1]]], - 'foo' - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['mutations'], [['baseVersion' => 1]]) + == $data['mutations']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn('foo'); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -860,12 +885,11 @@ public function testMutateWithBaseVersion() public function testMutateWithKey() { - $otherThis = $this; $this->requestHandler->sendRequest( - DatastoreClient::class, + V1DatastoreClient::class, 'commit', - Argument::that(function ($arg) use ($otherThis) { - $data = $otherThis->serializer->encodeMessage($arg); + Argument::that(function ($arg) { + $data = $this->getSerializer()->encodeMessage($arg); $x = isset($data['mutations'][0]['delete']['path']); return isset($data['mutations'][0]['delete']['path']); }), @@ -921,11 +945,13 @@ public function testMapEntityResult() { $res = json_decode(file_get_contents(Fixtures::ENTITY_RESULT_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $res,] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $res,]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $key = $this->operation->key('Person', 12345); @@ -942,11 +968,13 @@ public function testMapEntityResultWithoutProperties() { $res = json_decode(file_get_contents(Fixtures::ENTITY_RESULT_NO_PROPERTIES_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $res,] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $res,]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $key = $this->operation->key('Person', 12345); @@ -962,11 +990,13 @@ public function testMapEntityResultArrayOfClassNames() { $res = json_decode(file_get_contents(Fixtures::ENTITY_RESULT_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $res,] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $res,]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $key = $this->operation->key('Person', 12345); @@ -986,11 +1016,13 @@ public function testMapEntityResultArrayOfClassNamesMissingKindMapItem() $res = json_decode(file_get_contents(Fixtures::ENTITY_RESULT_FIXTURE()), true); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [], - ['found' => $res,] - ); + Argument::type(LookupRequest::class), + Argument::cetera() + )->shouldBeCalled()->willReturn(['found' => $res,]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $key = $this->operation->key('Person', 12345); @@ -1004,12 +1036,16 @@ public function testMapEntityResultArrayOfClassNamesMissingKindMapItem() public function testTransactionInReadOptions() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['readOptions' => ['transaction' => '1234']], - [], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['readOptions']['transaction'] == '1234'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); + $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); $key = $this->operation->key('Person', 12345); @@ -1036,12 +1072,15 @@ public function testNonTransactionalReadOptions() public function testReadConsistencyInReadOptions() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['readOptions' => ['readConsistency' => 123]], - [], - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['readOptions']['readConsistency'] == 123; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -1060,11 +1099,15 @@ public function testInvalidBatchType() public function testBeginTransactionWithDatabaseIdOverride() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'beginTransaction', - ['databaseId' => 'otherDatabaseId'], - ['transaction' => 'valid_test_transaction'] - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['databaseId'] == 'otherDatabaseId'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['transaction' => 'valid_test_transaction']); $transactionId = $this->operation->beginTransaction( [], @@ -1076,12 +1119,15 @@ public function testBeginTransactionWithDatabaseIdOverride() public function testAllocateIdsWithDatabaseIdOverride() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['databaseId' => 'otherDatabaseId'], - [], - 1 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['databaseId'] == 'otherDatabaseId'; + }), + Argument::cetera() + )->shouldBeCalledTimes(1)->willReturn([]); $this->operation->___setProperty('requestHandler', $this->requestHandler->reveal()); @@ -1093,12 +1139,15 @@ public function testAllocateIdsWithDatabaseIdOverride() public function testLookupWithDatabaseIdOverride() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['databaseId' => 'otherDatabaseId'], - [], - 1 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['databaseId'] == 'otherDatabaseId'; + }), + Argument::cetera() + )->shouldBeCalledTimes(1)->willReturn([]); $this->operation->lookup( [], diff --git a/Datastore/tests/Unit/TransactionTest.php b/Datastore/tests/Unit/TransactionTest.php index de21427076db..7d28f0c0e245 100644 --- a/Datastore/tests/Unit/TransactionTest.php +++ b/Datastore/tests/Unit/TransactionTest.php @@ -33,7 +33,14 @@ use Google\Cloud\Datastore\Query\QueryInterface; use Google\Cloud\Datastore\ReadOnlyTransaction; use Google\Cloud\Datastore\Transaction; +use Google\Cloud\Datastore\V1\AllocateIdsRequest; +use Google\Cloud\Datastore\V1\Client\DatastoreClient as V1DatastoreClient; +use Google\Cloud\Datastore\V1\CommitRequest; use Google\Cloud\Datastore\V1\CommitRequest\Mode; +use Google\Cloud\Datastore\V1\LookupRequest; +use Google\Cloud\Datastore\V1\RollbackRequest; +use Google\Cloud\Datastore\V1\RunAggregationQueryRequest; +use Google\Cloud\Datastore\V1\RunQueryRequest; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -57,33 +64,15 @@ class TransactionTest extends TestCase private $readOnly; private $key; private $entity; - private $serializer; private $requestHandler; public function setUp(): void { $this->requestHandler = $this->prophesize(RequestHandler::class); - $this->serializer = new Serializer([], [ - 'google.protobuf.Value' => function ($v) { - return $this->flattenValue($v); - }, - 'google.protobuf.Timestamp' => function ($v) { - return $this->formatTimestampFromApi($v); - } - ], [], [ - 'google.protobuf.Timestamp' => function ($v) { - if (is_string($v)) { - $dt = new \DateTime($v); - return ['seconds' => $dt->format('U')]; - } - return $v; - } - ]); - $op = new Operation( $this->requestHandler->reveal(), - $this->serializer, + $this->getSerializer(), self::PROJECT, null, new EntityMapper(self::PROJECT, false, false) @@ -106,20 +95,24 @@ public function setUp(): void */ public function testLookup(callable $transaction) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - [ - 'readOptions' => ['transaction' => self::TRANSACTION], - 'keys' => [$this->key->keyObject()], - ], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return isset($data['readOptions']['transaction']) + && $data['readOptions']['transaction'] == self::TRANSACTION + && array_replace_recursive($data['keys'], [$this->key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'found' => [ [ 'entity' => $this->entityArray($this->key) ] ] - ], - 0 + ] ); $transaction = $transaction(); @@ -137,17 +130,22 @@ public function testLookup(callable $transaction) */ public function testLookupMissing(callable $transaction) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['keys' => [$this->key->keyObject()]], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$this->key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'missing' => [ [ 'entity' => $this->entityArray($this->key) ] ] - ], - 0 + ] ); $transaction = $transaction(); @@ -164,9 +162,15 @@ public function testLookupMissing(callable $transaction) */ public function testLookupBatch(callable $transaction) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'lookup', - ['keys' => [$this->key->keyObject()]], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$this->key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'found' => [ [ @@ -181,8 +185,7 @@ public function testLookupBatch(callable $transaction) 'deferred' => [ $this->key->keyObject() ] - ], - 0 + ] ); $transaction = $transaction(); @@ -196,44 +199,21 @@ public function testLookupBatch(callable $transaction) $this->assertInstanceOf(Key::class, $res['deferred'][0]); } - /** - * @dataProvider transactionProvider - */ - public function testLookupBatchWithReadTime(callable $transaction) - { - $time = new Timestamp(new \DateTime()); - $this->mockSendRequest( - 'lookup', - ['readOptions' => ['readTime' => $time]], - [ - 'found' => [ - [ - 'entity' => $this->entityArray($this->key) - ] - ] - ], - 0 - ); - - $transaction = $transaction(); - $this->refreshOperation($transaction, $this->requestHandler->reveal(), [ - 'projectId' => self::PROJECT - ]); - - $res = $transaction->lookupBatch([$this->key], ['readTime' => $time]); - } - /** * @dataProvider transactionProvider */ public function testRunQuery(callable $transaction) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'SELECT 1=1'] - ], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['gqlQuery']['queryString'] == 'SELECT 1=1'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'entityResults' => [ @@ -242,8 +222,7 @@ public function testRunQuery(callable $transaction) ] ] ] - ], - 0 + ] ); $transaction = $transaction(); @@ -264,12 +243,16 @@ public function testRunQuery(callable $transaction) */ public function testRunAggregationQuery(callable $transaction) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runAggregationQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'AGGREGATE (COUNT(*)) over (SELECT 1=1)'], - ], + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['gqlQuery']['queryString'] == 'AGGREGATE (COUNT(*)) over (SELECT 1=1)'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'aggregationResults' => [ @@ -279,8 +262,7 @@ public function testRunAggregationQuery(callable $transaction) ], 'readTime' => (new \DateTime())->format('Y-m-d\TH:i:s') .'.000001Z' ] - ], - 0 + ] ); $transaction = $transaction(); @@ -303,13 +285,17 @@ public function testRunQueryWithReadTime() { $time = new Timestamp(new \DateTime()); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'runQuery', - [ - 'partitionId' => ['projectId' => self::PROJECT], - 'gqlQuery' => ['queryString' => 'SELECT 1=1'], - 'readOptions' => ['readTime' => $time] - ], + Argument::that(function ($req) use ($time) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['partitionId']['projectId'] == self::PROJECT + && $data['readOptions']['readTime'] == $time + && $data['gqlQuery']['queryString'] == 'SELECT 1=1'; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn( [ 'batch' => [ 'entityResults' => [ @@ -318,8 +304,7 @@ public function testRunQueryWithReadTime() ] ] ] - ], - 0 + ] ); $transaction = $this->readOnly; @@ -340,7 +325,15 @@ public function testRunQueryWithReadTime() */ public function testRollback(callable $transaction) { - $this->mockSendRequest('rollback', ['transaction' => self::TRANSACTION], [], 0); + $this->requestHandler->sendRequest( + V1DatastoreClient::class, + 'rollback', + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn([]); $transaction = $transaction(); $this->refreshOperation($transaction, $this->requestHandler->reveal(), [ @@ -355,16 +348,17 @@ public function testRollback(callable $transaction) */ public function testEntityMutations($method, $mutation, $key) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'transaction' => self::TRANSACTION, - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION + && $data['mode'] == Mode::TRANSACTIONAL + && $data['mutations'][0] = [$method => $mutation]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->transaction, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -381,16 +375,17 @@ public function testEntityMutations($method, $mutation, $key) */ public function testEntityMutationsBatch($method, $mutation, $key) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'transaction' => self::TRANSACTION, - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION + && $data['mode'] == Mode::TRANSACTIONAL + && $data['mutations'][0] = [$method => $mutation]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->transaction, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -414,24 +409,29 @@ public function mutationsProvider() */ public function testMutationsWithPartialKey($method, $mutation, $key, $id) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'transaction' => self::TRANSACTION, - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION + && $data['mode'] == Mode::TRANSACTIONAL + && $data['mutations'][0] = [$method => $mutation]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $keyWithId = clone $key; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$key->keyObject()]], - ['keys' => [$keyWithId->keyObject()]] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->refreshOperation($this->transaction, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -449,24 +449,29 @@ public function testMutationsWithPartialKey($method, $mutation, $key, $id) */ public function testBatchMutationsWithPartialKey($method, $mutation, $key, $id) { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'transaction' => self::TRANSACTION, - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [[$method => $mutation]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) use ($method, $mutation) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION + && $data['mode'] == Mode::TRANSACTIONAL + && $data['mutations'][0] = [$method => $mutation]; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $keyWithId = clone $key; $keyWithId->setLastElementIdentifier($id); - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'allocateIds', - ['keys' => [$key->keyObject()]], - ['keys' => [$keyWithId->keyObject()]] - ); + Argument::that(function ($req) use ($key) { + $data = $this->getSerializer()->encodeMessage($req); + return array_replace_recursive($data['keys'], [$key->keyObject()]) == $data['keys']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn(['keys' => [$keyWithId->keyObject()]]); $this->refreshOperation($this->transaction, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -490,16 +495,20 @@ public function partialKeyMutationsProvider() public function testDelete() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'transaction' => self::TRANSACTION, - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [['delete' => $this->key->keyObject()]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION + && $data['mode'] == Mode::TRANSACTIONAL + && array_replace_recursive( + $data['mutations'][0]['delete'], + $this->key->keyObject() + ) == $data['mutations'][0]['delete']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->transaction, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT @@ -514,16 +523,20 @@ public function testDelete() public function testDeleteBatch() { - $this->mockSendRequest( + $this->requestHandler->sendRequest( + V1DatastoreClient::class, 'commit', - [ - 'transaction' => self::TRANSACTION, - 'mode' => Mode::TRANSACTIONAL, - 'mutations' => [['delete' => $this->key->keyObject()]] - ], - $this->commitResponse(), - 0 - ); + Argument::that(function ($req) { + $data = $this->getSerializer()->encodeMessage($req); + return $data['transaction'] == self::TRANSACTION + && $data['mode'] == Mode::TRANSACTIONAL + && array_replace_recursive( + $data['mutations'][0]['delete'], + $this->key->keyObject() + ) == $data['mutations'][0]['delete']; + }), + Argument::cetera() + )->shouldBeCalled()->willReturn($this->commitResponse()); $this->refreshOperation($this->transaction, $this->requestHandler->reveal(), [ 'projectId' => self::PROJECT diff --git a/Datastore/tests/Unit/V1/DatastoreClientTest.php b/Datastore/tests/Unit/V1/DatastoreClientTest.php deleted file mode 100644 index 566a17821645..000000000000 --- a/Datastore/tests/Unit/V1/DatastoreClientTest.php +++ /dev/null @@ -1,572 +0,0 @@ -getMockBuilder(CredentialsWrapper::class)->disableOriginalConstructor()->getMock(); - } - - /** @return DatastoreClient */ - private function createClient(array $options = []) - { - $options += [ - 'credentials' => $this->createCredentials(), - ]; - return new DatastoreClient($options); - } - - /** @test */ - public function allocateIdsTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $expectedResponse = new AllocateIdsResponse(); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $keys = []; - $response = $gapicClient->allocateIds($projectId, $keys); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/AllocateIds', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $actualValue = $actualRequestObject->getKeys(); - $this->assertProtobufEquals($keys, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function allocateIdsExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - $keys = []; - try { - $gapicClient->allocateIds($projectId, $keys); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function beginTransactionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $transaction = '-34'; - $expectedResponse = new BeginTransactionResponse(); - $expectedResponse->setTransaction($transaction); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $response = $gapicClient->beginTransaction($projectId); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/BeginTransaction', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function beginTransactionExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - try { - $gapicClient->beginTransaction($projectId); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function commitTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $indexUpdates = 1425228195; - $expectedResponse = new CommitResponse(); - $expectedResponse->setIndexUpdates($indexUpdates); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $mode = Mode::MODE_UNSPECIFIED; - $mutations = []; - $response = $gapicClient->commit($projectId, $mode, $mutations); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/Commit', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $actualValue = $actualRequestObject->getMode(); - $this->assertProtobufEquals($mode, $actualValue); - $actualValue = $actualRequestObject->getMutations(); - $this->assertProtobufEquals($mutations, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function commitExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - $mode = Mode::MODE_UNSPECIFIED; - $mutations = []; - try { - $gapicClient->commit($projectId, $mode, $mutations); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function lookupTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $transaction = '-34'; - $expectedResponse = new LookupResponse(); - $expectedResponse->setTransaction($transaction); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $keys = []; - $response = $gapicClient->lookup($projectId, $keys); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/Lookup', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $actualValue = $actualRequestObject->getKeys(); - $this->assertProtobufEquals($keys, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function lookupExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - $keys = []; - try { - $gapicClient->lookup($projectId, $keys); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function reserveIdsTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $expectedResponse = new ReserveIdsResponse(); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $keys = []; - $response = $gapicClient->reserveIds($projectId, $keys); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/ReserveIds', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $actualValue = $actualRequestObject->getKeys(); - $this->assertProtobufEquals($keys, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function reserveIdsExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - $keys = []; - try { - $gapicClient->reserveIds($projectId, $keys); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function rollbackTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $expectedResponse = new RollbackResponse(); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $transaction = '-34'; - $response = $gapicClient->rollback($projectId, $transaction); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/Rollback', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $actualValue = $actualRequestObject->getTransaction(); - $this->assertProtobufEquals($transaction, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function rollbackExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - $transaction = '-34'; - try { - $gapicClient->rollback($projectId, $transaction); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function runAggregationQueryTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $transaction = '-34'; - $expectedResponse = new RunAggregationQueryResponse(); - $expectedResponse->setTransaction($transaction); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $response = $gapicClient->runAggregationQuery($projectId); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/RunAggregationQuery', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function runAggregationQueryExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - try { - $gapicClient->runAggregationQuery($projectId); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function runQueryTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - // Mock response - $transaction = '-34'; - $expectedResponse = new RunQueryResponse(); - $expectedResponse->setTransaction($transaction); - $transport->addResponse($expectedResponse); - // Mock request - $projectId = 'projectId-1969970175'; - $partitionId = new PartitionId(); - $response = $gapicClient->runQuery($projectId, $partitionId); - $this->assertEquals($expectedResponse, $response); - $actualRequests = $transport->popReceivedCalls(); - $this->assertSame(1, count($actualRequests)); - $actualFuncCall = $actualRequests[0]->getFuncCall(); - $actualRequestObject = $actualRequests[0]->getRequestObject(); - $this->assertSame('/google.datastore.v1.Datastore/RunQuery', $actualFuncCall); - $actualValue = $actualRequestObject->getProjectId(); - $this->assertProtobufEquals($projectId, $actualValue); - $actualValue = $actualRequestObject->getPartitionId(); - $this->assertProtobufEquals($partitionId, $actualValue); - $this->assertTrue($transport->isExhausted()); - } - - /** @test */ - public function runQueryExceptionTest() - { - $transport = $this->createTransport(); - $gapicClient = $this->createClient([ - 'transport' => $transport, - ]); - $this->assertTrue($transport->isExhausted()); - $status = new stdClass(); - $status->code = Code::DATA_LOSS; - $status->details = 'internal error'; - $expectedExceptionMessage = json_encode([ - 'message' => 'internal error', - 'code' => Code::DATA_LOSS, - 'status' => 'DATA_LOSS', - 'details' => [], - ], JSON_PRETTY_PRINT); - $transport->addResponse(null, $status); - // Mock request - $projectId = 'projectId-1969970175'; - $partitionId = new PartitionId(); - try { - $gapicClient->runQuery($projectId, $partitionId); - // If the $gapicClient method call did not throw, fail the test - $this->fail('Expected an ApiException, but no exception was thrown.'); - } catch (ApiException $ex) { - $this->assertEquals($status->code, $ex->getCode()); - $this->assertEquals($expectedExceptionMessage, $ex->getMessage()); - } - // Call popReceivedCalls to ensure the stub is exhausted - $transport->popReceivedCalls(); - $this->assertTrue($transport->isExhausted()); - } -}