From 44d85989b63574c0cf9924daacaaba294e9b830e Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Tue, 8 Oct 2024 00:06:17 +0200 Subject: [PATCH 01/16] Changed config name from responseSizeDecoderSwitch to jsonStreamDecoderThreshold (#32) --- docs/arangodb-client.md | 4 ++-- src/HandlesJson.php | 2 +- src/Http/HttpClientConfig.php | 4 ++-- tests/ArangoClientTest.php | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/arangodb-client.md b/docs/arangodb-client.md index fe1e293..12cafe6 100644 --- a/docs/arangodb-client.md +++ b/docs/arangodb-client.md @@ -13,7 +13,7 @@ Upon creation, you can alter the default configuration of the client. The follow * username = null * password = null * database = '_system' -* responseSizeDecoderSwitch = 1 * 1024 * 1024 +* jsonStreamDecoderThreshold = 1 * 1024 * 1024 ``` $config = [ @@ -31,7 +31,7 @@ JSON response decoding is normally done by the default json_decode method. This is optimized for speed and can take a large amount of memory; up to ~ 20x of the JSON size. Therefor we use halaxa/json-machine to stream decode for responses larger than 1MB. -You can alter this cutoff by setting the `responseSizeDecoderSwitch` to a different size in **Bytes**. +You can alter this cutoff by setting the `jsonStreamDecoderThreshold` to a different size in **Bytes**. This removed any memory issues at the cost of speed. diff --git a/src/HandlesJson.php b/src/HandlesJson.php index 65a299f..cbba428 100644 --- a/src/HandlesJson.php +++ b/src/HandlesJson.php @@ -38,7 +38,7 @@ public function jsonEncode(mixed $data): string protected function decodeJsonResponse(ResponseInterface $response): stdClass { $contentLength = $response->getHeaderLine('Content-Length'); - $sizeSwitch = $this->getConfig('responseSizeDecoderSwitch'); + $sizeSwitch = $this->getConfig('jsonStreamDecoderThreshold'); if ($contentLength < $sizeSwitch) { return json_decode($response->getBody()->getContents(), false, 512, JSON_THROW_ON_ERROR); } diff --git a/src/Http/HttpClientConfig.php b/src/Http/HttpClientConfig.php index 6197e3f..b40d806 100644 --- a/src/Http/HttpClientConfig.php +++ b/src/Http/HttpClientConfig.php @@ -40,11 +40,11 @@ class HttpClientConfig extends DataTransferObject /** * Small responses are decoded with json_decode. This is fast but memory intensive. * Large responses are decoded with Halaxa/json-machine stream decoder. - * $responseSizeDecoderSwitch is the response length cutoff in bytes which determines which decoder is used. + * $jsonStreamDecoderThreshold is the response length cutoff in bytes which determines which decoder is used. * * @var int */ - public int $responseSizeDecoderSwitch = 1 * 1024 * 1024; // Default 1 MB + public int $jsonStreamDecoderThreshold = 1 * 1024 * 1024; // Default 1 MB /** * @return array|string|numeric|bool|null> diff --git a/tests/ArangoClientTest.php b/tests/ArangoClientTest.php index 58fd2c2..2f81718 100644 --- a/tests/ArangoClientTest.php +++ b/tests/ArangoClientTest.php @@ -31,7 +31,7 @@ public function testGetConfig() 'username' => 'root', 'password' => null, 'database' => $this->testDatabaseName, - 'responseSizeDecoderSwitch' => 1048576, + 'jsonStreamDecoderThreshold' => 1048576, ]; $config = $this->arangoClient->getConfig(); From 162a0fd6e080faa97b0b16e0e743761f217fae1a Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:18:57 +0200 Subject: [PATCH 02/16] PHPUnit to Pest Converter (#33) * Add Pest dependencies * Add base Pest file * Convert test cases * Remove non-compound imports * Adopt expectation API * Optimize uses * Use Pest test runner * Migrated tests from Phpunit to Pest --------- Co-authored-by: Shift --- .github/workflows/run-tests.yml | 2 +- composer.json | 15 +- phpunit.xml | 2 +- tests/AdminManagerTest.php | 65 ++- tests/ArangoClientTest.php | 384 ++++++++--------- tests/ExceptionsTest.php | 35 +- tests/MonitorManagerTest.php | 64 ++- tests/Pest.php | 52 +++ tests/SchemaManagerAnalyzersTest.php | 144 +++---- tests/SchemaManagerCollectionsTest.php | 295 ++++++------- tests/SchemaManagerDatabasesTest.php | 79 ++-- tests/SchemaManagerGraphsTest.php | 558 ++++++++++++------------- tests/SchemaManagerIndexesTest.php | 159 ++++--- tests/SchemaManagerUsersTest.php | 223 +++++----- tests/SchemaManagerViewsTest.php | 157 +++---- tests/StatementTest.php | 222 ++++------ tests/StreamTransactionsTest.php | 107 +++++ tests/SupportsTransactionsTest.php | 121 ------ tests/TestCase.php | 46 +- tests/TransactionManagerTest.php | 244 +++++------ 20 files changed, 1403 insertions(+), 1571 deletions(-) create mode 100644 tests/Pest.php create mode 100644 tests/StreamTransactionsTest.php delete mode 100644 tests/SupportsTransactionsTest.php diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 3e88eb8..646bf37 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,7 +13,7 @@ jobs: matrix: os: [ubuntu-latest] arangodb: ["3.10", 3.11, 3.12] - php: [8.1, 8.2, 8.3] + php: [8.2, 8.3] stability: [prefer-stable] name: P${{ matrix.php }} - A${{ matrix.arangodb }} - ${{ matrix.stability }} diff --git a/composer.json b/composer.json index c9f6469..e5b86ca 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } ], "minimum-stability": "dev", - "prefer-stable" : true, + "prefer-stable": true, "require": { "php": "^8.1", "ext-curl": "*", @@ -29,9 +29,9 @@ "mockery/mockery": "^1.4", "phpmd/phpmd": "^2.9", "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^9.5", "rector/rector": "^0.14.8", - "scrutinizer/ocular": "^1.8" + "scrutinizer/ocular": "^1.8", + "pestphp/pest": "^2.2" }, "autoload": { "psr-4": { @@ -45,11 +45,14 @@ }, "scripts": { "analyse": "vendor/bin/phpstan analyse", - "test": "vendor/bin/phpunit", - "test:coverage": "vendor/bin/phpunit --coverage-clover clover.xml --whitelist src", + "test": "vendor/bin/pest", + "test:coverage": "vendor/bin/pest --coverage-clover clover.xml", "style": "vendor/bin/pint" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true + } } } diff --git a/phpunit.xml b/phpunit.xml index 3e91546..e12801e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,6 +16,6 @@ - + diff --git a/tests/AdminManagerTest.php b/tests/AdminManagerTest.php index 5d0a8e7..8d00a17 100644 --- a/tests/AdminManagerTest.php +++ b/tests/AdminManagerTest.php @@ -2,42 +2,33 @@ declare(strict_types=1); -namespace Tests; - use ArangoClient\Admin\AdminManager; -class AdminManagerTest extends TestCase -{ - protected AdminManager $adminManager; - - protected function setUp(): void - { - parent::setUp(); - - $this->adminManager = new AdminManager($this->arangoClient); - } - - public function testGetVersion() - { - $result = $this->adminManager->getVersion(); - - $this->assertSame('arango', $result->server); - $this->assertSame('community', $result->license); - $this->assertIsString($result->version); - } - - public function testGetVersionWithDetails() - { - $result = $this->adminManager->getVersion(true); - - $this->assertSame('arango', $result->server); - $this->assertSame('community', $result->license); - $this->assertIsString($result->version); - } - - public function testGetRunningTransactions() - { - $transactions = $this->adminManager->getRunningTransactions(); - $this->assertEmpty($transactions); - } -} +uses(Tests\TestCase::class); + +beforeEach(function () { + $this->adminManager = new AdminManager($this->arangoClient); +}); + + +test('get version', function () { + $result = $this->adminManager->getVersion(); + + expect($result->server)->toBe('arango'); + expect($result->license)->toBe('community'); + expect($result->version)->toBeString(); +}); + +test('get version with details', function () { + $result = $this->adminManager->getVersion(true); + + expect($result->server)->toBe('arango'); + expect($result->license)->toBe('community'); + expect($result->version)->toBeString(); +}); + +test('get running transactions', function () { + $transactions = $this->adminManager->getRunningTransactions(); + + expect($transactions)->toBeEmpty(); +}); diff --git a/tests/ArangoClientTest.php b/tests/ArangoClientTest.php index 2f81718..0187280 100644 --- a/tests/ArangoClientTest.php +++ b/tests/ArangoClientTest.php @@ -2,8 +2,6 @@ declare(strict_types=1); -namespace Tests; - use ArangoClient\Admin\AdminManager; use ArangoClient\ArangoClient; use ArangoClient\Schema\SchemaManager; @@ -13,258 +11,226 @@ use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7\Response; -use Mockery; -use stdClass; - -class ArangoClientTest extends TestCase -{ - public function testGetConfig() - { - $defaultConfig = [ - 'endpoint' => 'http://localhost:8529', - 'host' => null, - 'port' => null, - 'version' => 1.1, - 'connection' => 'Keep-Alive', - 'allow_redirects' => false, - 'connect_timeout' => 0.0, - 'username' => 'root', - 'password' => null, - 'database' => $this->testDatabaseName, - 'jsonStreamDecoderThreshold' => 1048576, - ]; - - $config = $this->arangoClient->getConfig(); - $this->assertSame($defaultConfig, $config); - } - public function testGetConfigWithEndpointWithoutHostPort() - { - $config = [ - 'endpoint' => 'http://localhost:8529', - 'username' => 'root', - ]; +uses(Tests\TestCase::class); + +test('get config', function () { + $defaultConfig = [ + 'endpoint' => 'http://localhost:8529', + 'host' => null, + 'port' => null, + 'version' => 1.1, + 'connection' => 'Keep-Alive', + 'allow_redirects' => false, + 'connect_timeout' => 0.0, + 'username' => 'root', + 'password' => null, + 'database' => $this->testDatabaseName, + 'jsonStreamDecoderThreshold' => 1048576, + ]; + + $config = $this->arangoClient->getConfig(); + expect($config)->toBe($defaultConfig); +}); + +test('get config with endpoint without host port', function () { + $config = [ + 'endpoint' => 'http://localhost:8529', + 'username' => 'root', + ]; + + $returnedConfig = $this->arangoClient->getConfig(); + expect($returnedConfig['endpoint'])->toBe($config['endpoint']); +}); + +test('client with host port config', function () { + $config = [ + 'host' => 'http://127.0.0.1', + 'port' => '1234', + 'username' => 'root', + ]; + $client = new ArangoClient($config); + $retrievedConfig = $client->getConfig(); + + expect($retrievedConfig['endpoint'])->toEqual('http://127.0.0.1:1234'); +}); + +test('config with alien properties', function () { + $config = [ + 'name' => 'arangodb', + 'driver' => 'arangodb', + 'host' => 'http://127.0.0.1', + 'port' => '1234', + 'username' => 'root', + ]; + $client = new ArangoClient($config); + $retrievedConfig = $client->getConfig(); - $returnedConfig = $this->arangoClient->getConfig(); - $this->assertSame($config['endpoint'], $returnedConfig['endpoint']); - } + $this->assertArrayNotHasKey('name', $retrievedConfig); + $this->assertArrayNotHasKey('driver', $retrievedConfig); +}); - public function testClientWithHostPortConfig() - { - $config = [ - 'host' => 'http://127.0.0.1', - 'port' => '1234', - 'username' => 'root', - ]; - $client = new ArangoClient($config); - $retrievedConfig = $client->getConfig(); - - $this->assertEquals('http://127.0.0.1:1234', $retrievedConfig['endpoint']); - } +test('set and get http client', function () { + $oldClient = $this->arangoClient->getHttpClient(); - public function testConfigWithAlienProperties() - { - $config = [ - 'name' => 'arangodb', - 'driver' => 'arangodb', - 'host' => 'http://127.0.0.1', - 'port' => '1234', - 'username' => 'root', - ]; - $client = new ArangoClient($config); - $retrievedConfig = $client->getConfig(); - - $this->assertArrayNotHasKey('name', $retrievedConfig); - $this->assertArrayNotHasKey('driver', $retrievedConfig); - } + $newClient = Mockery::mock(Client::class); + $this->arangoClient->setHttpClient($newClient); + $retrievedClient = $this->arangoClient->getHttpClient(); - public function testSetAndGetHttpClient() - { - $oldClient = $this->arangoClient->getHttpClient(); + expect($oldClient)->toBeInstanceOf(Client::class); + expect($retrievedClient::class)->toEqual($newClient::class); +}); - $newClient = Mockery::mock(Client::class); - $this->arangoClient->setHttpClient($newClient); - $retrievedClient = $this->arangoClient->getHttpClient(); +test('request', function () { + $result = $this->arangoClient->request('get', '/_api/version', []); - $this->assertInstanceOf(Client::class, $oldClient); - $this->assertEquals($newClient::class, $retrievedClient::class); - } + expect($result->server)->toBe('arango'); + expect($result->license)->toBe('community'); + expect($result->version)->toBeString(); +}); - public function testRequest() - { - $result = $this->arangoClient->request('get', '/_api/version', []); +test('get user', function () { + $user = $this->arangoClient->getUser(); + expect($user)->toBe('root'); +}); - $this->assertSame('arango', $result->server); - $this->assertSame('community', $result->license); - $this->assertIsString($result->version); - } +test('set and get database name', function () { + $database = $this->arangoClient->getDatabase(); + expect($database)->toBe($this->testDatabaseName); + + $newDatabaseName = 'ArangoClientDB'; + $this->arangoClient->setDatabase($newDatabaseName); + + $database = $this->arangoClient->getDatabase(); + expect($database)->toBe($newDatabaseName); +}); - public function testGetUser() - { - $user = $this->arangoClient->getUser(); - $this->assertSame('root', $user); +test('database name is used in requests', function () { + $database = 'some_database'; + if (!$this->arangoClient->schema()->hasDatabase($database)) { + $this->arangoClient->schema()->createDatabase($database); } - public function testSetAndGetDatabaseName() - { - $database = $this->arangoClient->getDatabase(); - $this->assertSame($this->testDatabaseName, $database); + $uri = '/_api/collection'; - $newDatabaseName = 'ArangoClientDB'; - $this->arangoClient->setDatabase($newDatabaseName); + $container = []; + $history = Middleware::history($container); + $mock = new MockHandler([ + new Response(200, ['X-Foo' => 'Bar'], '{}'), + ]); + $handlerStack = HandlerStack::create($mock); + $handlerStack->push($history); - $database = $this->arangoClient->getDatabase(); - $this->assertSame($newDatabaseName, $database); - } + $this->arangoClient->setDatabase($database); - public function testDatabaseNameIsUsedInRequests() - { - $database = 'some_database'; - if (!$this->arangoClient->schema()->hasDatabase($database)) { - $this->arangoClient->schema()->createDatabase($database); - } + $this->arangoClient->request('get', $uri, ['handler' => $handlerStack]); - $uri = '/_api/collection'; + foreach ($container as $transaction) { + expect($transaction['request']->getUri()->getPath())->toBe('/_db/' . $database . $uri); + } - $container = []; - $history = Middleware::history($container); - $mock = new MockHandler([ - new Response(200, ['X-Foo' => 'Bar'], '{}'), - ]); - $handlerStack = HandlerStack::create($mock); - $handlerStack->push($history); + $this->arangoClient->schema()->deleteDatabase($database); +}); - $this->arangoClient->setDatabase($database); +test('schema', function () { + $result = $this->arangoClient->schema(); + expect($result)->toBeInstanceOf(SchemaManager::class); - $this->arangoClient->request('get', $uri, ['handler' => $handlerStack]); + $database = $this->arangoClient->schema()->getCurrentDatabase(); - foreach ($container as $transaction) { - $this->assertSame('/_db/' . $database . $uri, $transaction['request']->getUri()->getPath()); - } + $this->assertObjectHasProperty('name', $database); +}); - $this->arangoClient->schema()->deleteDatabase($database); - } +test('admin', function () { + $result = $this->arangoClient->admin(); + expect($result)->toBeInstanceOf(AdminManager::class); - public function testSchema() - { - $result = $this->arangoClient->schema(); - $this->assertInstanceOf(SchemaManager::class, $result); + $version = $this->arangoClient->admin()->getVersion(); - $database = $this->arangoClient->schema()->getCurrentDatabase(); + $this->assertObjectHasProperty('version', $version); +}); - $this->assertObjectHasProperty('name', $database); - } +test('prepare', function () { + $statement = $this->arangoClient->prepare('FOR doc IN users RETURN doc'); - public function testAdmin() - { - $result = $this->arangoClient->admin(); - $this->assertInstanceOf(AdminManager::class, $result); + expect($statement)->toBeInstanceOf(Statement::class); +}); - $version = $this->arangoClient->admin()->getVersion(); +test('connection protocol version', function () { + checkHttp2Support(); - $this->assertObjectHasProperty('version', $version); - } + $uri = '/_api/version'; - public function testPrepare() - { - $statement = $this->arangoClient->prepare('FOR doc IN users RETURN doc'); + $options = []; + $options['version'] = 2; + $response = $this->arangoClient->debugRequest('get', $uri, $options); - $this->assertInstanceOf(Statement::class, $statement); - } + expect($response->getProtocolVersion())->toEqual(2); +}); - public function testConnectionProtocolVersion() - { - $this->checkHttp2Support(); +test('connection protocol version with default setting', function () { + checkHttp2Support(); - $uri = '/_api/version'; + $uri = '/_api/version'; - $options = []; - $options['version'] = 2; - $response = $this->arangoClient->debugRequest('get', $uri, $options); + $client = new ArangoClient(['username' => 'root', 'version' => 2.0]); - $this->assertEquals(2, $response->getProtocolVersion()); - } + $options = []; + $options['version'] = 2; + $response = $this->arangoClient->debugRequest('get', $uri, $options); - public function testConnectionProtocolVersionWithDefaultSetting() - { - $this->checkHttp2Support(); + expect($response->getProtocolVersion())->toEqual(2); +}); - $uri = '/_api/version'; +test('json encode', function () { + $results = $this->arangoClient->jsonEncode([]); - $client = new ArangoClient(['username' => 'root', 'version' => 2.0]); + expect($results)->toBe('{}'); +}); - $options = []; - $options['version'] = 2; - $response = $this->arangoClient->debugRequest('get', $uri, $options); +test('json encode empty array', function () { + $results = $this->arangoClient->jsonEncode([]); - $this->assertEquals(2, $response->getProtocolVersion()); - } + expect($results)->toBe('{}'); +}); - public function testJsonEncode() - { - $results = $this->arangoClient->jsonEncode([]); +test('json encode empty string', function () { + $results = $this->arangoClient->jsonEncode(''); - $this->assertSame('{}', $results); - } + expect($results)->toBe('""'); +}); - public function testJsonEncodeEmptyArray() - { - $results = $this->arangoClient->jsonEncode([]); +test('json encode invalid data', function () { + $data = []; + $data[] = "\xB1\x31"; + $this->expectExceptionCode(JSON_ERROR_UTF8); + $this->arangoClient->jsonEncode($data); +}); - $this->assertSame('{}', $results); +test('response data matches request data', function () { + $collection = 'users'; + if (!$this->schemaManager->hasCollection($collection)) { + $this->schemaManager->createCollection($collection); } + $location = new stdClass(); + $location->address = 'Voughtstreet 10'; + $location->city = 'New York'; - public function testJsonEncodeEmptyString() - { - $results = $this->arangoClient->jsonEncode(''); + $user = new stdClass(); + $user->name = 'Soldier Boy'; + $user->location = $location; - $this->assertSame('""', $results); - } + $insertQuery = 'INSERT ' . json_encode($user, JSON_THROW_ON_ERROR) . ' INTO ' . $collection . ' RETURN NEW'; + $insertStatement = $this->arangoClient->prepare($insertQuery); + $insertStatement->execute(); + $insertResult = $insertStatement->fetchAll(); - public function testJsonEncodeInvalidData() - { - $data = []; - $data[] = "\xB1\x31"; - $this->expectExceptionCode(JSON_ERROR_UTF8); - $this->arangoClient->jsonEncode($data); - } + $query = 'FOR doc IN ' . $collection . ' RETURN doc'; + $statement = $this->arangoClient->prepare($query); + $statement->execute(); + $users = $statement->fetchAll(); - public function testResponseDataMatchesRequestData() - { - $collection = 'users'; - if (!$this->schemaManager->hasCollection($collection)) { - $this->schemaManager->createCollection($collection); - } - $location = new stdClass(); - $location->address = 'Voughtstreet 10'; - $location->city = 'New York'; - - $user = new stdClass(); - $user->name = 'Soldier Boy'; - $user->location = $location; - - $insertQuery = 'INSERT ' . json_encode($user, JSON_THROW_ON_ERROR) . ' INTO ' . $collection . ' RETURN NEW'; - $insertStatement = $this->arangoClient->prepare($insertQuery); - $insertStatement->execute(); - $insertResult = $insertStatement->fetchAll(); - - $query = 'FOR doc IN ' . $collection . ' RETURN doc'; - $statement = $this->arangoClient->prepare($query); - $statement->execute(); - $users = $statement->fetchAll(); - - $this->assertEquals($insertResult[0], $users[0]); - - $this->schemaManager->deleteCollection($collection); - } + expect($users[0])->toEqual($insertResult[0]); - protected function checkHttp2Support() - { - // First assert that CURL supports http2! - if (!curl_version()['features'] || CURL_VERSION_HTTP2 === 0) { - $this->markTestSkipped('The installed version of CURL does not support the HTTP2 protocol.'); - } - // HTTP/2 is only supported by ArangoDB 3.7 and up. - $this->skipTestOnArangoVersions('3.7'); - } -} + $this->schemaManager->deleteCollection($collection); +}); diff --git a/tests/ExceptionsTest.php b/tests/ExceptionsTest.php index 5a122a2..668aca1 100644 --- a/tests/ExceptionsTest.php +++ b/tests/ExceptionsTest.php @@ -2,27 +2,22 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class ExceptionsTest extends TestCase -{ - public function test409ConflictException() - { - $database = 'test_arangodb_php_existing_database'; - if (!$this->schemaManager->hasDatabase($database)) { - $this->schemaManager->createDatabase($database); - } - - $this->expectExceptionCode(409); +test('test409 conflict exception', function () { + $database = 'test_arangodb_php_existing_database'; + if (!$this->schemaManager->hasDatabase($database)) { $this->schemaManager->createDatabase($database); - - $this->schemaManager->deleteDatabase($database); } - public function testCallsToNoneExistingDbThrow() - { - $this->arangoClient->setDatabase('NoneExistingDb'); - $this->expectExceptionCode(404); - $this->schemaManager->hasCollection('dummy'); - } -} + $this->expectExceptionCode(409); + $this->schemaManager->createDatabase($database); + + $this->schemaManager->deleteDatabase($database); +}); + +test('calls to none existing db throw', function () { + $this->arangoClient->setDatabase('NoneExistingDb'); + $this->expectExceptionCode(404); + $this->schemaManager->hasCollection('dummy'); +}); diff --git a/tests/MonitorManagerTest.php b/tests/MonitorManagerTest.php index c5cb8fc..4f941db 100644 --- a/tests/MonitorManagerTest.php +++ b/tests/MonitorManagerTest.php @@ -2,25 +2,21 @@ declare(strict_types=1); -namespace Tests; - use ArangoClient\Prometheus\Prometheus; -class MonitorManagerTest extends TestCase -{ - public function testGetMetrics() - { - $result = $this->arangoClient->monitor()->getMetrics(); - $this->assertIsObject($result); - $this->assertEquals("gauge", $result->arangodb_agency_cache_callback_number->type); - $this->assertCount(1, $result->arangodb_agency_cache_callback_number->labels); - } +uses(Tests\TestCase::class); + +test('get metrics', function () { + $result = $this->arangoClient->monitor()->getMetrics(); + expect($result)->toBeObject(); + expect($result->arangodb_agency_cache_callback_number->type)->toEqual("gauge"); + expect($result->arangodb_agency_cache_callback_number->labels)->toHaveCount(1); +}); - public function testSummaryMetric() - { - $prometheus = new Prometheus(); +test('summary metric', function () { + $prometheus = new Prometheus(); - $rawMetrics = '# HELP prometheus_rule_evaluation_duration_seconds The duration for a rule to execute. + $rawMetrics = '# HELP prometheus_rule_evaluation_duration_seconds The duration for a rule to execute. # TYPE prometheus_rule_evaluation_duration_seconds summary prometheus_rule_evaluation_duration_seconds{quantile="0.5"} 6.4853e-05 prometheus_rule_evaluation_duration_seconds{quantile="0.9"} 0.00010102 @@ -29,15 +25,14 @@ public function testSummaryMetric() prometheus_rule_evaluation_duration_seconds_count 1.112293682e+09'; - $result = $prometheus->parseText($rawMetrics); - $this->assertIsObject($result); - } + $result = $prometheus->parseText($rawMetrics); + expect($result)->toBeObject(); +}); - public function testHistorgramParsing() - { - $prometheus = new Prometheus(); +test('historgram parsing', function () { + $prometheus = new Prometheus(); - $rawMetrics = '# HELP arangodb_aql_query_time Execution time histogram for all AQL queries [s] + $rawMetrics = '# HELP arangodb_aql_query_time Execution time histogram for all AQL queries [s] # TYPE arangodb_aql_query_time histogram arangodb_aql_query_time_bucket{role="SINGLE",le="0.000095"} 36 2211753600 arangodb_aql_query_time_bucket{role="SINGLE",le="0.000191"} 157 2211753601 @@ -63,22 +58,19 @@ public function testHistorgramParsing() arangodb_aql_query_time_sum{role="SINGLE"} 0.035180 '; - $result = $prometheus->parseText($rawMetrics); - $this->assertCount(20, $result->arangodb_aql_query_time->buckets); - $this->assertEquals(177, $result->arangodb_aql_query_time->count); - $this->assertEquals(0.03518, $result->arangodb_aql_query_time->sum); - } + $result = $prometheus->parseText($rawMetrics); + expect($result->arangodb_aql_query_time->buckets)->toHaveCount(20); + expect($result->arangodb_aql_query_time->count)->toEqual(177); + expect($result->arangodb_aql_query_time->sum)->toEqual(0.03518); +}); - public function testTimestampParsing() - { - $prometheus = new Prometheus(); +test('timestamp parsing', function () { + $prometheus = new Prometheus(); - $rawMetrics = '# HELP arangodb_aql_local_query_memory_limit_reached_total Number of local AQL query memory limit violations + $rawMetrics = '# HELP arangodb_aql_local_query_memory_limit_reached_total Number of local AQL query memory limit violations # TYPE arangodb_aql_local_query_memory_limit_reached_total counter arangodb_aql_local_query_memory_limit_reached_total{role="SINGLE"} 0 2211753600'; - $result = $prometheus->parseText($rawMetrics); - $this->assertIsObject($result); - $this->assertEquals(2211753600, $result->arangodb_aql_local_query_memory_limit_reached_total->timestamp); - } -} + $result = $prometheus->parseText($rawMetrics); + expect($result->arangodb_aql_local_query_memory_limit_reached_total->timestamp)->toEqual(2211753600); +}); diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..ee45215 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,52 @@ +markTestSkipped('The installed version of CURL does not support the HTTP2 protocol.'); + } + // HTTP/2 is only supported by ArangoDB 3.7 and up. + test()->skipTestOnArangoVersions('3.7'); +} diff --git a/tests/SchemaManagerAnalyzersTest.php b/tests/SchemaManagerAnalyzersTest.php index 790d605..0195370 100644 --- a/tests/SchemaManagerAnalyzersTest.php +++ b/tests/SchemaManagerAnalyzersTest.php @@ -2,107 +2,85 @@ declare(strict_types=1); +uses(Tests\TestCase::class); -class SchemaManagerAnalyzersTest extends \Tests\TestCase -{ - protected array $analyzer = [ - 'name' => 'testAnalyzerBasics', - 'type' => 'identity', - ]; - - protected function setUp(): void - { - \Tests\TestCase::setUp(); - - if (!$this->schemaManager->hasAnalyzer($this->analyzer['name'])) { - $this->schemaManager->createAnalyzer($this->analyzer); - } +beforeEach(function () { + if (!$this->schemaManager->hasAnalyzer($this->analyzer['name'])) { + $this->schemaManager->createAnalyzer($this->analyzer); } +}); - protected function tearDown(): void - { - \Tests\TestCase::tearDown(); - - if ($this->schemaManager->hasAnalyzer($this->analyzer['name'])) { - $this->schemaManager->deleteAnalyzer($this->analyzer['name']); - } +afterEach(function () { + if ($this->schemaManager->hasAnalyzer($this->analyzer['name'])) { + $this->schemaManager->deleteAnalyzer($this->analyzer['name']); } +}); - public function testGetAnalyzers() - { - $analyzers = $this->schemaManager->getAnalyzers(); +test('get analyzers', function () { + $analyzers = $this->schemaManager->getAnalyzers(); - $customAnalyzer = end($analyzers); + $customAnalyzer = end($analyzers); - $this->assertSame('arangodb_php_client__test::' . $this->analyzer['name'], $customAnalyzer->name); - } + expect($customAnalyzer->name)->toBe('arangodb_php_client__test::' . $this->analyzer['name']); +}); - public function testGetAnalyzer() - { - $analyzer = $this->schemaManager->getAnalyzer($this->analyzer['name']); +test('get analyzer', function () { + $analyzer = $this->schemaManager->getAnalyzer($this->analyzer['name']); - $this->assertSame('arangodb_php_client__test::' . $this->analyzer['name'], $analyzer->name); - $this->assertObjectHasProperty('type', $analyzer); - } + expect($analyzer->name)->toBe('arangodb_php_client__test::' . $this->analyzer['name']); + $this->assertObjectHasProperty('type', $analyzer); +}); - public function testGetAnalyzerWithFullName() - { - $analyzer = $this->schemaManager->getAnalyzer('arangodb_php_client__test::' . $this->analyzer['name']); +test('get analyzer with full name', function () { + $analyzer = $this->schemaManager->getAnalyzer('arangodb_php_client__test::' . $this->analyzer['name']); - $this->assertSame('arangodb_php_client__test::' . $this->analyzer['name'], $analyzer->name); - $this->assertObjectHasProperty('type', $analyzer); - } + expect($analyzer->name)->toBe('arangodb_php_client__test::' . $this->analyzer['name']); + $this->assertObjectHasProperty('type', $analyzer); +}); +test('has analyzer', function () { + $result = $this->schemaManager->hasAnalyzer($this->analyzer['name']); + expect($result)->toBeTrue(); - public function testHasAnalyzer() - { - $result = $this->schemaManager->hasAnalyzer($this->analyzer['name']); - $this->assertTrue($result); - - $result = $this->schemaManager->hasAnalyzer('someNoneExistingAnalyzer'); - $this->assertFalse($result); - } + $result = $this->schemaManager->hasAnalyzer('someNoneExistingAnalyzer'); + expect($result)->toBeFalse(); +}); - public function testReplaceAnalyzer() - { - $newAnalyzerProps = [ - 'name' => 'newAnalyzer', - 'type' => 'identity', - ]; - ; - $newAnalyzer = $this->schemaManager->replaceAnalyzer($this->analyzer['name'], $newAnalyzerProps); +test('replace analyzer', function () { + $newAnalyzerProps = [ + 'name' => 'newAnalyzer', + 'type' => 'identity', + ]; + ; + $newAnalyzer = $this->schemaManager->replaceAnalyzer($this->analyzer['name'], $newAnalyzerProps); - $this->assertSame('arangodb_php_client__test::' . $this->analyzer['name'], $newAnalyzer->name); - } + expect($newAnalyzer->name)->toBe('arangodb_php_client__test::' . $this->analyzer['name']); +}); - public function testCreateAndDeleteAnalyzer() - { - $analyzer = [ - 'name' => 'coolnewanalyzer', - 'type' => 'identity', - ]; - $created = $this->schemaManager->createAnalyzer($analyzer); - $this->assertObjectHasProperty('name', $created); - $this->assertSame('arangodb_php_client__test::' . $analyzer['name'], $created->name); - - $deleted = $this->schemaManager->deleteAnalyzer($analyzer['name']); - $this->assertTrue($deleted); - } +test('create and delete analyzer', function () { + $analyzer = [ + 'name' => 'coolnewanalyzer', + 'type' => 'identity', + ]; + $created = $this->schemaManager->createAnalyzer($analyzer); + $this->assertObjectHasProperty('name', $created); + expect($created->name)->toBe('arangodb_php_client__test::' . $analyzer['name']); - public function testDeleteWithFullName() - { - $analyzer = [ - 'name' => 'coolnewanalyzer', - 'type' => 'identity', - ]; - $created = $this->schemaManager->createAnalyzer($analyzer); + $deleted = $this->schemaManager->deleteAnalyzer($analyzer['name']); + expect($deleted)->toBeTrue(); +}); - $fullName = 'arangodb_php_client__test::' . $analyzer['name']; +test('delete with full name', function () { + $analyzer = [ + 'name' => 'coolnewanalyzer', + 'type' => 'identity', + ]; + $this->schemaManager->createAnalyzer($analyzer); - $deleted = $this->schemaManager->deleteAnalyzer($fullName); + $fullName = 'arangodb_php_client__test::' . $analyzer['name']; - $hasAnalyzer = $this->schemaManager->hasAnalyzer($fullName); - $this->assertFalse($hasAnalyzer); - } + $this->schemaManager->deleteAnalyzer($fullName); -} + $hasAnalyzer = $this->schemaManager->hasAnalyzer($fullName); + expect($hasAnalyzer)->toBeFalse(); +}); diff --git a/tests/SchemaManagerCollectionsTest.php b/tests/SchemaManagerCollectionsTest.php index 055bd02..f913ddd 100644 --- a/tests/SchemaManagerCollectionsTest.php +++ b/tests/SchemaManagerCollectionsTest.php @@ -2,216 +2,193 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class SchemaManagerCollectionsTest extends TestCase -{ - public function testGetCollectionsBeforeVersion38() - { - $this->skipTestOnArangoVersions('3.8', '>='); - $result = $this->schemaManager->getCollections(); +test('get collections', function () { + $result = $this->schemaManager->getCollections(); - $this->assertLessThanOrEqual(count($result), 10); - $this->assertIsObject($result[0]); - } + expect(8)->toBeLessThanOrEqual(count($result)); + expect($result[0])->toBeObject(); +}); - public function testGetCollections() - { - $this->skipTestOnArangoVersions('3.8', '<'); - $result = $this->schemaManager->getCollections(); +test('get collections without system', function () { + $result = $this->schemaManager->getCollections(true); - $this->assertLessThanOrEqual(count($result), 8); - $this->assertIsObject($result[0]); - } + expect($result)->toBeEmpty(); +}); - public function testGetCollectionsWithoutSystem() - { - $result = $this->schemaManager->getCollections(true); +test('get collection', function () { + $collections = $this->schemaManager->getCollections(); - $this->assertEmpty($result); - } + $result = $this->schemaManager->getCollection($collections[0]->name); - public function testGetCollection() - { - $collections = $this->schemaManager->getCollections(); + expect($result)->toBeObject(); + expect((array) $result)->toHaveKeys(['globallyUniqueId', 'isSystem', 'status', 'type', 'name', 'id']); +}); - $result = $this->schemaManager->getCollection($collections[0]->name); +test('has collection', function () { + $result = $this->schemaManager->hasCollection('_graphs'); + expect($result)->toBeTrue(); - $this->assertIsObject($result); - $this->assertObjectHasProperty('name', $result); - $this->assertObjectHasProperty('isSystem', $result); - } + $result = $this->schemaManager->hasCollection('someNoneExistingCollection'); + expect($result)->toBeFalse(); +}); - public function testHasCollection() - { - $result = $this->schemaManager->hasCollection('_graphs'); - $this->assertTrue($result); +test('get collection properties', function () { + $collections = $this->schemaManager->getCollections(); - $result = $this->schemaManager->hasCollection('someNoneExistingCollection'); - $this->assertFalse($result); - } + $result = $this->schemaManager->getCollectionProperties($collections[0]->name); - public function testGetCollectionProperties() - { - $collections = $this->schemaManager->getCollections(); + expect($result)->toBeObject(); + $this->assertObjectHasProperty('name', $result); + $this->assertObjectHasProperty('isSystem', $result); + $this->assertObjectHasProperty('statusString', $result); + $this->assertObjectHasProperty('keyOptions', $result); +}); - $result = $this->schemaManager->getCollectionProperties($collections[0]->name); +test('get collection with document count', function () { + $collections = $this->schemaManager->getCollections(); - $this->assertIsObject($result); - $this->assertObjectHasProperty('name', $result); - $this->assertObjectHasProperty('isSystem', $result); - $this->assertObjectHasProperty('statusString', $result); - $this->assertObjectHasProperty('keyOptions', $result); - } + $result = $this->schemaManager->getCollectionWithDocumentCount($collections[0]->name); - public function testGetCollectionWithDocumentCount() - { - $collections = $this->schemaManager->getCollections(); + $this->assertObjectHasProperty('name', $result); + $this->assertObjectHasProperty('isSystem', $result); + $this->assertObjectHasProperty('statusString', $result); + $this->assertObjectHasProperty('keyOptions', $result); + $this->assertObjectHasProperty('count', $result); + expect($result->count)->toBeNumeric(); +}); - $result = $this->schemaManager->getCollectionWithDocumentCount($collections[0]->name); +test('get collection document count', function () { + $collections = $this->schemaManager->getCollections(); - $this->assertObjectHasProperty('name', $result); - $this->assertObjectHasProperty('isSystem', $result); - $this->assertObjectHasProperty('statusString', $result); - $this->assertObjectHasProperty('keyOptions', $result); - $this->assertObjectHasProperty('count', $result); - $this->assertIsNumeric($result->count); - } + $result = $this->schemaManager->getCollectionDocumentCount($collections[0]->name); - public function testGetCollectionDocumentCount() - { - $collections = $this->schemaManager->getCollections(); + expect($result)->toBeNumeric(); +}); - $result = $this->schemaManager->getCollectionDocumentCount($collections[0]->name); +test('get collection statistics', function () { + $collections = $this->schemaManager->getCollections(); - $this->assertIsNumeric($result); - } + $result = $this->schemaManager->getCollectionStatistics($collections[0]->name); - public function testGetCollectionStatistics() - { - $collections = $this->schemaManager->getCollections(); + $this->assertObjectHasProperty('figures', $result); +}); - $result = $this->schemaManager->getCollectionStatistics($collections[0]->name); +test('get collection statistics with details', function () { + $collections = $this->schemaManager->getCollections(); - $this->assertObjectHasProperty('figures', $result); - } + $result = $this->schemaManager->getCollectionStatistics($collections[0]->name, true); - public function testGetCollectionStatisticsWithDetails() - { - $collections = $this->schemaManager->getCollections(); + $this->assertObjectHasProperty('figures', $result); +}); - $result = $this->schemaManager->getCollectionStatistics($collections[0]->name, true); +test('update collection', function () { + $collection = 'users'; + $config = []; - $this->assertObjectHasProperty('figures', $result); + if (!$this->schemaManager->hasCollection($collection)) { + $this->schemaManager->createCollection($collection, $config); } - public function testUpdateCollection() - { - $collection = 'users'; - $config = []; + $newConfig = ['waitForSync' => true]; + $result = $this->schemaManager->updateCollection($collection, $newConfig); + expect($result->waitForSync)->toBeTrue(); - if (!$this->schemaManager->hasCollection($collection)) { - $this->schemaManager->createCollection($collection, $config); - } + $this->schemaManager->deleteCollection($collection); +}); - $newConfig = ['waitForSync' => true]; - $result = $this->schemaManager->updateCollection($collection, $newConfig); - $this->assertTrue($result->waitForSync); +test('rename collection', function () { + $collection = 'users'; + $newName = 'characters'; + $config = []; - $this->schemaManager->deleteCollection($collection); + if (!$this->schemaManager->hasCollection($collection)) { + $this->schemaManager->createCollection($collection, $config); + } + if ($this->schemaManager->hasCollection($newName)) { + $this->schemaManager->deleteCollection($newName); } - public function testRenameCollection() - { - $collection = 'users'; - $newName = 'characters'; - $config = []; - - if (!$this->schemaManager->hasCollection($collection)) { - $this->schemaManager->createCollection($collection, $config); - } - if ($this->schemaManager->hasCollection($newName)) { - $this->schemaManager->deleteCollection($newName); - } + $result = $this->schemaManager->renameCollection($collection, $newName); + expect($result->name)->toBe($newName); - $result = $this->schemaManager->renameCollection($collection, $newName); - $this->assertSame($newName, $result->name); + $this->schemaManager->deleteCollection($newName); +}); - $this->schemaManager->deleteCollection($newName); +test('truncate collection', function () { + $collection = 'users'; + if (!$this->schemaManager->hasCollection($collection)) { + $this->schemaManager->createCollection($collection); } - public function testTruncateCollection() - { - $collection = 'users'; - if (!$this->schemaManager->hasCollection($collection)) { - $this->schemaManager->createCollection($collection); - } - $this->assertSame(0, $this->schemaManager->getCollectionWithDocumentCount($collection)->count); - $query = 'FOR i IN 1..10 - INSERT { - _key: CONCAT("test", i), - name: "test", - foobar: true - } INTO ' . $collection . ' OPTIONS { ignoreErrors: true }'; - $statement = $this->arangoClient->prepare($query); - $statement->execute(); - - $this->assertSame(0, count($statement->fetchAll())); - - $this->schemaManager->truncateCollection($collection); - - $this->assertSame(0, $this->schemaManager->getCollectionWithDocumentCount($collection)->count); - $this->schemaManager->deleteCollection($collection); - } + expect($this->schemaManager->getCollectionWithDocumentCount($collection)->count)->toBe(0); + + $query = 'FOR i IN 1..10 + INSERT { + _key: CONCAT("test", i), + name: "test", + foobar: true + } INTO ' . $collection . ' OPTIONS { ignoreErrors: true }'; + $statement = $this->arangoClient->prepare($query); + $statement->execute(); + + expect(count($statement->fetchAll()))->toBe(0); - public function testCreateAndDeleteCollection() - { - $collection = 'users'; - $options = []; + $this->schemaManager->truncateCollection($collection); - if (!$this->schemaManager->hasCollection($collection)) { - $result = $this->schemaManager->createCollection($collection, $options); - $this->assertEquals($collection, $result->name); - } + expect($this->schemaManager->getCollectionWithDocumentCount($collection)->count)->toBe(0); - $result = $this->schemaManager->deleteCollection($collection); - $this->assertTrue($result); - $this->assertFalse($this->schemaManager->hasCollection($collection)); + if ($this->schemaManager->hasCollection($collection)) { + $this->schemaManager->deleteCollection($collection); } - public function testCreateCollectionWithOptions() - { - $collection = 'users'; - $options = ['waitForSync' => true]; +}); + +test('create and delete collection', function () { + $collection = 'users'; + $options = []; - if (!$this->schemaManager->hasCollection($collection)) { - $result = $this->schemaManager->createCollection($collection, $options, 1, 1); - } + if (!$this->schemaManager->hasCollection($collection)) { + $result = $this->schemaManager->createCollection($collection, $options); + expect($result->name)->toEqual($collection); + } - $collectionProperties = $this->schemaManager->getCollectionProperties('users'); - $this->assertTrue($collectionProperties->waitForSync); + $result = $this->schemaManager->deleteCollection($collection); + expect($result)->toBeTrue(); + expect($this->schemaManager->hasCollection($collection))->toBeFalse(); +}); - // $waitForSyncReplication & $enforceReplicationFactor are not listed in the properties, so the lack of - // of an exception somewhat tests these options... +test('create collection with options', function () { + $collection = 'users'; + $options = ['waitForSync' => true]; - $result = $this->schemaManager->deleteCollection($collection); - $this->assertTrue($result); - $this->assertFalse($this->schemaManager->hasCollection($collection)); + if (!$this->schemaManager->hasCollection($collection)) { + $result = $this->schemaManager->createCollection($collection, $options, 1, 1); } - public function testCreateEdgeCollection() - { - $collection = 'relationships'; + $collectionProperties = $this->schemaManager->getCollectionProperties('users'); + expect($collectionProperties->waitForSync)->toBeTrue(); - if ($this->schemaManager->hasCollection($collection)) { - $this->schemaManager->deleteCollection($collection); - } + // $waitForSyncReplication & $enforceReplicationFactor are not listed in the properties, so the lack of + // of an exception somewhat tests these options... - $result = $this->schemaManager->createEdgeCollection($collection); + $result = $this->schemaManager->deleteCollection($collection); + expect($result)->toBeTrue(); + expect($this->schemaManager->hasCollection($collection))->toBeFalse(); +}); - $this->assertEquals($collection, $result->name); - $this->assertSame(3, $result->type); +test('create edge collection', function () { + $collection = 'relationships'; + if ($this->schemaManager->hasCollection($collection)) { $this->schemaManager->deleteCollection($collection); } -} + + $result = $this->schemaManager->createEdgeCollection($collection); + + expect($result->name)->toEqual($collection); + expect($result->type)->toBe(3); + + $this->schemaManager->deleteCollection($collection); +}); diff --git a/tests/SchemaManagerDatabasesTest.php b/tests/SchemaManagerDatabasesTest.php index 2184c24..8525c32 100644 --- a/tests/SchemaManagerDatabasesTest.php +++ b/tests/SchemaManagerDatabasesTest.php @@ -2,58 +2,49 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class SchemaManagerDatabasesTest extends TestCase -{ - protected function setUp(): void - { - parent::setUp(); - } +beforeEach(function () {}); - public function testGetDatabase() - { - $this->arangoClient->setDatabase('_system'); - $result = $this->schemaManager->getCurrentDatabase(); - $this->assertSame('1', $result->id); - $this->assertSame('_system', $result->name); - $this->assertSame(true, $result->isSystem); - $this->assertSame('none', $result->path); - } +test('get database', function () { + $this->arangoClient->setDatabase('_system'); + $result = $this->schemaManager->getCurrentDatabase(); - public function testGetDatabases() - { - $result = $this->schemaManager->getDatabases(); + expect($result->id)->toBe('1'); + expect($result->name)->toBe('_system'); + expect($result->isSystem)->toBe(true); + expect($result->path)->toBe('none'); +}); - $this->assertLessThanOrEqual(count($result), 2); - foreach ($result as $database) { - $this->assertIsString($database); - } - } +test('get databases', function () { + $result = $this->schemaManager->getDatabases(); - public function testCreateAndDeleteDatabase() - { - $database = 'arangodb_php_client_database__test'; - $existingDatabases = $this->schemaManager->getDatabases(); + expect(2)->toBeLessThanOrEqual(count($result)); + foreach ($result as $database) { + expect($database)->toBeString(); + } +}); - if (!in_array($database, $existingDatabases)) { - $result = $this->schemaManager->createDatabase($database); - $this->assertTrue($result); - } +test('create and delete database', function () { + $database = 'arangodb_php_client_database__test'; + $existingDatabases = $this->schemaManager->getDatabases(); - $result = $this->schemaManager->deleteDatabase($database); - $this->assertTrue($result); - $existingDatabases = $this->schemaManager->getDatabases(); - $this->assertNotContains($database, $existingDatabases); + if (!in_array($database, $existingDatabases)) { + $result = $this->schemaManager->createDatabase($database); + expect($result)->toBeTrue(); } - public function testHasDatabase() - { - $check = $this->schemaManager->hasDatabase('someNoneExistingDatabase'); - $this->assertFalse($check); + $result = $this->schemaManager->deleteDatabase($database); + expect($result)->toBeTrue(); + $existingDatabases = $this->schemaManager->getDatabases(); + $this->assertNotContains($database, $existingDatabases); +}); - $check = $this->schemaManager->hasDatabase($this->testDatabaseName); - $this->assertTrue($check); - } -} +test('has database', function () { + $check = $this->schemaManager->hasDatabase('someNoneExistingDatabase'); + expect($check)->toBeFalse(); + + $check = $this->schemaManager->hasDatabase($this->testDatabaseName); + expect($check)->toBeTrue(); +}); diff --git a/tests/SchemaManagerGraphsTest.php b/tests/SchemaManagerGraphsTest.php index 21b569c..c937f3e 100644 --- a/tests/SchemaManagerGraphsTest.php +++ b/tests/SchemaManagerGraphsTest.php @@ -2,24 +2,98 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class SchemaManagerGraphsTest extends TestCase -{ - public function testCreateAndDeleteGraph() - { - $result = $this->schemaManager->createGraph('locations', [], true); - $this->assertSame('_graphs/locations', $result->_id); +test('create and delete graph', function () { + $result = $this->schemaManager->createGraph('locations', [], true); + expect($result->_id)->toBe('_graphs/locations'); - $result = $this->schemaManager->deleteGraph('locations'); - $this->assertTrue($result); + $result = $this->schemaManager->deleteGraph('locations'); + expect($result)->toBeTrue(); +}); + +test('create graph with edges', function () { + if (!$this->schemaManager->hasCollection('characters')) { + $this->schemaManager->createCollection('characters'); } + $result = $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], + ], + ], + 'orphanCollections' => [ + 'orphanVertices', + ], + ], + true, + ); + expect(is_countable($result->edgeDefinitions) ? count($result->edgeDefinitions) : 0)->toEqual(1); + expect('_graphs/relations')->toEqual($result->_id); + + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('characters'); + $this->schemaManager->deleteCollection('orphanVertices'); +}); + +test('get graphs no results', function () { + $result = $this->schemaManager->getGraphs(); + + expect(count($result))->toBeLessThanOrEqual(0); +}); + +test('get graphs with results', function () { + if (!$this->schemaManager->hasGraph('characters')) { + $this->schemaManager->createGraph('characters'); + } + if (!$this->schemaManager->hasGraph('locations')) { + $this->schemaManager->createGraph('locations'); + } + + $result = $this->schemaManager->getGraphs(); + + expect(count($result))->toEqual(2); + expect($result[0]->_key)->toEqual('characters'); + expect($result[1]->_key)->toEqual('locations'); + + $this->schemaManager->deleteGraph('characters'); + $this->schemaManager->deleteGraph('locations'); +}); + +test('has graph', function () { + if (!$this->schemaManager->hasGraph('locations')) { + $this->schemaManager->createGraph('locations'); + } + $result = $this->schemaManager->hasGraph('locations'); + expect($result)->toBeTrue(); + + $this->schemaManager->deleteGraph('locations'); + $result = $this->schemaManager->hasGraph('locations'); + expect($result)->toBeFalse(); +}); + +test('get graph', function () { + if (!$this->schemaManager->hasGraph('locations')) { + $this->schemaManager->createGraph('locations'); + } + + $result = $this->schemaManager->getGraph('locations'); + + expect($result->_key)->toEqual('locations'); - public function testCreateGraphWithEdges() - { - if (!$this->schemaManager->hasCollection('characters')) { - $this->schemaManager->createCollection('characters'); - } + $this->schemaManager->deleteGraph('locations'); +}); + +test('get graph vertices', function () { + if (!$this->schemaManager->hasCollection('characters')) { + $this->schemaManager->createCollection('characters'); + } + if (!$this->schemaManager->hasGraph('relations')) { $result = $this->schemaManager->createGraph( 'relations', [ @@ -36,314 +110,224 @@ public function testCreateGraphWithEdges() ], true, ); - $this->assertEquals(1, is_countable($result->edgeDefinitions) ? count($result->edgeDefinitions) : 0); - $this->assertEquals($result->_id, '_graphs/relations'); - - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('characters'); - $this->schemaManager->deleteCollection('orphanVertices'); } - public function testGetGraphsNoResults() - { - $result = $this->schemaManager->getGraphs(); - - $this->assertLessThanOrEqual(0, count($result)); - } + $results = $this->schemaManager->getGraphVertices('relations'); - public function testGetGraphsWithResults() - { - if (!$this->schemaManager->hasGraph('characters')) { - $this->schemaManager->createGraph('characters'); - } - if (!$this->schemaManager->hasGraph('locations')) { - $this->schemaManager->createGraph('locations'); - } + expect(count($results))->toEqual(2); + expect('characters')->toEqual($results[0]); + expect('orphanVertices')->toEqual($results[1]); - $result = $this->schemaManager->getGraphs(); + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('characters'); + $this->schemaManager->deleteCollection('orphanVertices'); +}); - $this->assertEquals(2, count($result)); - $this->assertEquals('characters', $result[0]->_key); - $this->assertEquals('locations', $result[1]->_key); - - $this->schemaManager->deleteGraph('characters'); - $this->schemaManager->deleteGraph('locations'); - } - - public function testHasGraph() - { - if (!$this->schemaManager->hasGraph('locations')) { - $this->schemaManager->createGraph('locations'); - } - $result = $this->schemaManager->hasGraph('locations'); - $this->assertTrue($result); - - $this->schemaManager->deleteGraph('locations'); - $result = $this->schemaManager->hasGraph('locations'); - $this->assertFalse($result); - } - - public function testGetGraph() - { - if (!$this->schemaManager->hasGraph('locations')) { - $this->schemaManager->createGraph('locations'); - } - - $result = $this->schemaManager->getGraph('locations'); - - $this->assertEquals('locations', $result->_key); - - $this->schemaManager->deleteGraph('locations'); - } - - public function testGetGraphVertices() - { - if (!$this->schemaManager->hasCollection('characters')) { - $this->schemaManager->createCollection('characters'); - } - if (!$this->schemaManager->hasGraph('relations')) { - $result = $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], - ], - 'orphanCollections' => [ - 'orphanVertices', +test('add graph vertex', function () { + if (!$this->schemaManager->hasGraph('relations')) { + $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], ], ], - true, - ); - } + 'orphanCollections' => [ + 'orphanVertices', + ], + ], + false, + ); + } + $newVertex = 'houses'; - $results = $this->schemaManager->getGraphVertices('relations'); + $result = $this->schemaManager->addGraphVertex('relations', $newVertex); - $this->assertEquals(2, count($results)); - $this->assertEquals($results[0], 'characters'); - $this->assertEquals($results[1], 'orphanVertices'); + expect($result->orphanCollections)->toContain('orphanVertices'); + expect($result->orphanCollections)->toContain($newVertex); - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('characters'); - $this->schemaManager->deleteCollection('orphanVertices'); - } + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('characters'); + $this->schemaManager->deleteCollection('orphanVertices'); + $this->schemaManager->deleteCollection($newVertex); +}); - public function testAddGraphVertex() - { - if (!$this->schemaManager->hasGraph('relations')) { - $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], - ], - 'orphanCollections' => [ - 'orphanVertices', +test('remove graph vertex', function () { + if (!$this->schemaManager->hasGraph('relations')) { + $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], ], ], - false, - ); - } - $newVertex = 'houses'; - - $result = $this->schemaManager->addGraphVertex('relations', $newVertex); - - $this->assertContains('orphanVertices', $result->orphanCollections); - $this->assertContains($newVertex, $result->orphanCollections); - - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('characters'); - $this->schemaManager->deleteCollection('orphanVertices'); - $this->schemaManager->deleteCollection($newVertex); + 'orphanCollections' => [ + 'orphanVertices', + ], + ], + false, + ); } - public function testRemoveGraphVertex() - { - if (!$this->schemaManager->hasGraph('relations')) { - $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], - ], - 'orphanCollections' => [ - 'orphanVertices', - ], - ], - false, - ); - } + $result = $this->schemaManager->removeGraphVertex('relations', 'orphanVertices', true); - $result = $this->schemaManager->removeGraphVertex('relations', 'orphanVertices', true); + $this->assertNotContains('orphanVertices', $result->orphanCollections); - $this->assertNotContains('orphanVertices', $result->orphanCollections); + $checkDropped = $this->schemaManager->hasCollection('orphanVertices'); + expect($checkDropped)->toBeFalse(); - $checkDropped = $this->schemaManager->hasCollection('orphanVertices'); - $this->assertFalse($checkDropped); + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('characters'); +}); - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('characters'); +test('get graph edges', function () { + if (!$this->schemaManager->hasCollection('characters')) { + $this->schemaManager->createCollection('characters'); } - - public function testGetGraphEdges() - { - if (!$this->schemaManager->hasCollection('characters')) { - $this->schemaManager->createCollection('characters'); - } - if (!$this->schemaManager->hasGraph('relations')) { - $result = $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], - ], - 'orphanCollections' => [ - 'orphanVertices', + if (!$this->schemaManager->hasGraph('relations')) { + $result = $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], ], ], - true, - ); - } + 'orphanCollections' => [ + 'orphanVertices', + ], + ], + true, + ); + } - $results = $this->schemaManager->getGraphEdges('relations'); + $results = $this->schemaManager->getGraphEdges('relations'); - $this->assertEquals(1, count($results)); - $this->assertEquals($results[0], 'children'); + expect(count($results))->toEqual(1); + expect('children')->toEqual($results[0]); - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('characters'); - $this->schemaManager->deleteCollection('orphanVertices'); - } + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('characters'); + $this->schemaManager->deleteCollection('orphanVertices'); +}); - public function testAddGraphEdge() - { - if (!$this->schemaManager->hasGraph('relations')) { - $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], +test('add graph edge', function () { + if (!$this->schemaManager->hasGraph('relations')) { + $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], ], ], - false, - ); - } - $newEdge = [ - 'collection' => 'vassals', - 'from' => ['characters'], - 'to' => ['houses'], - ]; - - $result = $this->schemaManager->addGraphEdge('relations', $newEdge); - - $this->assertEquals($newEdge['collection'], $result->edgeDefinitions[1]->collection); - - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('characters'); - $this->schemaManager->deleteCollection('vassals'); - $this->schemaManager->deleteCollection('houses'); + ], + false, + ); } - - public function testReplaceGraphEdge() - { - if (!$this->schemaManager->hasGraph('relations')) { - $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], + $newEdge = [ + 'collection' => 'vassals', + 'from' => ['characters'], + 'to' => ['houses'], + ]; + + $result = $this->schemaManager->addGraphEdge('relations', $newEdge); + + expect($result->edgeDefinitions[1]->collection)->toEqual($newEdge['collection']); + + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('characters'); + $this->schemaManager->deleteCollection('vassals'); + $this->schemaManager->deleteCollection('houses'); +}); + +test('replace graph edge', function () { + if (!$this->schemaManager->hasGraph('relations')) { + $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], ], ], - ); - } - - $newEdge = [ - 'collection' => 'children', - 'from' => ['houses'], - 'to' => ['houses'], - ]; - - $result = $this->schemaManager->replaceGraphEdge( - 'relations', - 'children', - $newEdge, - false, - true, + ], ); - - $this->assertEquals($newEdge['collection'], $result->edgeDefinitions[0]->collection); - - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('houses'); - $this->schemaManager->deleteCollection('characters'); } - public function testRemoveGraphEdge() - { - if (!$this->schemaManager->hasGraph('relations')) { - $this->schemaManager->createGraph( - 'relations', - [ - 'edgeDefinitions' => [ - [ - 'collection' => 'children', - 'from' => ['characters'], - 'to' => ['characters'], - ], - [ - 'collection' => 'vassals', - 'from' => ['houses'], - 'to' => ['houses'], - ], + $newEdge = [ + 'collection' => 'children', + 'from' => ['houses'], + 'to' => ['houses'], + ]; + + $result = $this->schemaManager->replaceGraphEdge( + 'relations', + 'children', + $newEdge, + false, + true, + ); + + expect($result->edgeDefinitions[0]->collection)->toEqual($newEdge['collection']); + + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('houses'); + $this->schemaManager->deleteCollection('characters'); +}); + +test('remove graph edge', function () { + if (!$this->schemaManager->hasGraph('relations')) { + $this->schemaManager->createGraph( + 'relations', + [ + 'edgeDefinitions' => [ + [ + 'collection' => 'children', + 'from' => ['characters'], + 'to' => ['characters'], + ], + [ + 'collection' => 'vassals', + 'from' => ['houses'], + 'to' => ['houses'], ], ], - ); - } - - $result = $this->schemaManager->removeGraphEdge( - 'relations', - 'children', - true, - true, + ], ); - - $this->assertEquals(1, is_countable($result->edgeDefinitions) ? count($result->edgeDefinitions) : 0); - $this->assertEquals('vassals', $result->edgeDefinitions[0]->collection); - - $this->schemaManager->deleteGraph('relations'); - $this->schemaManager->deleteCollection('children'); - $this->schemaManager->deleteCollection('houses'); - $this->schemaManager->deleteCollection('characters'); - $this->schemaManager->deleteCollection('vassals'); } -} + + $result = $this->schemaManager->removeGraphEdge( + 'relations', + 'children', + true, + true, + ); + + expect(is_countable($result->edgeDefinitions) ? count($result->edgeDefinitions) : 0)->toEqual(1); + expect($result->edgeDefinitions[0]->collection)->toEqual('vassals'); + + $this->schemaManager->deleteGraph('relations'); + $this->schemaManager->deleteCollection('children'); + $this->schemaManager->deleteCollection('houses'); + $this->schemaManager->deleteCollection('characters'); + $this->schemaManager->deleteCollection('vassals'); +}); diff --git a/tests/SchemaManagerIndexesTest.php b/tests/SchemaManagerIndexesTest.php index 6bb94c4..5061391 100644 --- a/tests/SchemaManagerIndexesTest.php +++ b/tests/SchemaManagerIndexesTest.php @@ -2,94 +2,79 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class SchemaManagerIndexesTest extends TestCase -{ - protected string $collection = 'users'; - - protected function setUp(): void - { - parent::setUp(); - - if (!$this->schemaManager->hasCollection($this->collection)) { - $this->schemaManager->createCollection($this->collection); - } - } - - protected function tearDown(): void - { - parent::tearDown(); - - if ($this->schemaManager->hasCollection($this->collection)) { - $this->schemaManager->deleteCollection($this->collection); - } - } - - public function testGetIndexes() - { - $indexes = $this->schemaManager->getIndexes($this->collection); - - $this->assertIsObject($indexes[0]); - $this->assertObjectHasProperty('name', $indexes[0]); - $this->assertSame('primary', $indexes[0]->name); - } - - public function testGetIndex() - { - $indexes = $this->schemaManager->getIndexes($this->collection); - $indexId = $indexes[0]->id; - - $index = $this->schemaManager->getIndex($indexId); - - $this->assertObjectHasProperty('name', $index); - $this->assertObjectHasProperty('id', $index); - $this->assertObjectHasProperty('fields', $index); - } - - public function testGetIndexByName() - { - $indexes = $this->schemaManager->getIndexes($this->collection); - $indexName = $indexes[0]->name; - - $index = $this->schemaManager->getIndexByName($this->collection, $indexName); - - $this->assertSame($indexName, $index->name); - } - - public function testCreateIndex() - { - $index = [ - 'name' => 'email_persistent_unique', - 'type' => 'persistent', - 'fields' => ['profile.email'], - 'unique' => true, - 'sparse' => false, - ]; - $created = $this->schemaManager->createIndex($this->collection, $index); - $result = $this->schemaManager->getIndexByName($this->collection, 'email_persistent_unique'); - - $this->assertSame($index['name'], $result->name); - $this->assertSame($index['fields'][0], $result->fields[0]); - $this->assertSame($index['unique'], $result->unique); - $this->assertSame($index['sparse'], $result->sparse); +beforeEach(function () { + if (!$this->schemaManager->hasCollection($this->collection)) { + $this->schemaManager->createCollection($this->collection); } +}); - public function testDeleteIndex() - { - $index = [ - 'name' => 'email_persistent_unique', - 'type' => 'persistent', - 'fields' => ['profile.email'], - 'unique' => true, - 'sparse' => false, - ]; - $created = $this->schemaManager->createIndex($this->collection, $index); - $found = $this->schemaManager->getIndexByName($this->collection, 'email_persistent_unique'); - - $deleted = $this->schemaManager->deleteIndex($found->id); - $this->assertEquals($created->id, $deleted->id); - $searchForDeleted = $this->schemaManager->getIndexByName($this->collection, 'email_persistent_unique'); - $this->assertFalse($searchForDeleted); +afterEach(function () { + if ($this->schemaManager->hasCollection($this->collection)) { + $this->schemaManager->deleteCollection($this->collection); } -} +}); + + +test('get indexes', function () { + $indexes = $this->schemaManager->getIndexes($this->collection); + + expect($indexes[0])->toBeObject(); + $this->assertObjectHasProperty('name', $indexes[0]); + expect($indexes[0]->name)->toBe('primary'); +}); + +test('get index', function () { + $indexes = $this->schemaManager->getIndexes($this->collection); + $indexId = $indexes[0]->id; + + $index = $this->schemaManager->getIndex($indexId); + + $this->assertObjectHasProperty('name', $index); + $this->assertObjectHasProperty('id', $index); + $this->assertObjectHasProperty('fields', $index); +}); + +test('get index by name', function () { + $indexes = $this->schemaManager->getIndexes($this->collection); + $indexName = $indexes[0]->name; + + $index = $this->schemaManager->getIndexByName($this->collection, $indexName); + + expect($index->name)->toBe($indexName); +}); + +test('create index', function () { + $index = [ + 'name' => 'email_persistent_unique', + 'type' => 'persistent', + 'fields' => ['profile.email'], + 'unique' => true, + 'sparse' => false, + ]; + $created = $this->schemaManager->createIndex($this->collection, $index); + $result = $this->schemaManager->getIndexByName($this->collection, 'email_persistent_unique'); + + expect($result->name)->toBe($index['name']); + expect($result->fields[0])->toBe($index['fields'][0]); + expect($result->unique)->toBe($index['unique']); + expect($result->sparse)->toBe($index['sparse']); +}); + +test('delete index', function () { + $index = [ + 'name' => 'email_persistent_unique', + 'type' => 'persistent', + 'fields' => ['profile.email'], + 'unique' => true, + 'sparse' => false, + ]; + $created = $this->schemaManager->createIndex($this->collection, $index); + $found = $this->schemaManager->getIndexByName($this->collection, 'email_persistent_unique'); + + $deleted = $this->schemaManager->deleteIndex($found->id); + expect($deleted->id)->toEqual($created->id); + $searchForDeleted = $this->schemaManager->getIndexByName($this->collection, 'email_persistent_unique'); + expect($searchForDeleted)->toBeFalse(); +}); diff --git a/tests/SchemaManagerUsersTest.php b/tests/SchemaManagerUsersTest.php index 311fbd7..8c10af9 100644 --- a/tests/SchemaManagerUsersTest.php +++ b/tests/SchemaManagerUsersTest.php @@ -2,156 +2,123 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class SchemaManagerUsersTest extends TestCase -{ - protected string $userName = 'kimiko'; +beforeEach(function () { + $user = [ + 'user' => $this->userName, + 'password' => 'yee random pw', + ]; - protected string $accessDatabase = 'arangodb_php_client_access__test'; - - protected function setUp(): void - { - parent::setUp(); - - $user = [ - 'user' => $this->userName, - 'password' => 'yee random pw', - ]; - - if (!$this->schemaManager->hasUser($this->userName)) { - $this->schemaManager->createUser($user); - } - } - - protected function tearDown(): void - { - parent::tearDown(); - - if ($this->schemaManager->hasUser($this->userName)) { - $this->schemaManager->deleteUser($this->userName); - } - } - - public function testGetUser() - { - $name = 'root'; - $user = $this->schemaManager->getUser($name); - - $this->assertSame($name, $user->user); - } - - public function testGetUsers() - { - $users = $this->schemaManager->getUsers(); - $this->assertIsArray($users); - $this->assertObjectHasProperty('user', $users[0]); + if (!$this->schemaManager->hasUser($this->userName)) { + $this->schemaManager->createUser($user); } +}); - public function testHasUser() - { - $result = $this->schemaManager->hasUser('root'); - $this->assertTrue($result); - - $result = $this->schemaManager->hasUser('nonExistingUser'); - $this->assertFalse($result); +afterEach(function () { + if ($this->schemaManager->hasUser($this->userName)) { + $this->schemaManager->deleteUser($this->userName); } - - public function testCreateAndDeleteUser() - { - $user = [ - 'user' => 'admin', - 'passwd' => 'highly secretive password', - 'active' => true, - 'extra' => [ - 'profile' => [ - 'name' => 'Billy Butcher', - ], +}); + + +test('get user', function () { + $name = 'root'; + $user = $this->schemaManager->getUser($name); + + expect($user->user)->toBe($name); +}); + +test('get users', function () { + $users = $this->schemaManager->getUsers(); + expect($users)->toBeArray(); + $this->assertObjectHasProperty('user', $users[0]); +}); + +test('has user', function () { + $result = $this->schemaManager->hasUser('root'); + expect($result)->toBeTrue(); + + $result = $this->schemaManager->hasUser('nonExistingUser'); + expect($result)->toBeFalse(); +}); + +test('create and delete user', function () { + $user = [ + 'user' => 'admin', + 'passwd' => 'highly secretive password', + 'active' => true, + 'extra' => [ + 'profile' => [ + 'name' => 'Billy Butcher', ], - ]; - if ($this->schemaManager->hasUser($user['user'])) { - $this->schemaManager->deleteUser($user['user']); - } - - $created = $this->schemaManager->createUser($user); - $this->assertSame($user['user'], $created->user); - + ], + ]; + if ($this->schemaManager->hasUser($user['user'])) { $this->schemaManager->deleteUser($user['user']); - $checkDeleted = $this->schemaManager->hasUser($user['user']); - $this->assertFalse($checkDeleted); } - public function testUpdateUser() - { - $newUserData = [ - 'user' => $this->userName, - 'active' => false, - ]; - $updated = $this->schemaManager->updateUser($this->userName, $newUserData); + $created = $this->schemaManager->createUser($user); + expect($created->user)->toBe($user['user']); - $this->assertSame($newUserData['user'], $updated->user); - } + $this->schemaManager->deleteUser($user['user']); + $checkDeleted = $this->schemaManager->hasUser($user['user']); + expect($checkDeleted)->toBeFalse(); +}); - public function testReplaceUser() - { - $newUserData = [ - 'user' => 'newUserName', - 'active' => false, - ]; - $replaced = $this->schemaManager->replaceUser($this->userName, $newUserData); +test('update user', function () { + $newUserData = [ + 'user' => $this->userName, + 'active' => false, + ]; + $updated = $this->schemaManager->updateUser($this->userName, $newUserData); - $this->assertSame($this->userName, $replaced->user); - } + expect($updated->user)->toBe($newUserData['user']); +}); - public function testGetDatabaseAccessLevel() - { - $accessLevel = $this->schemaManager->getDatabaseAccessLevel('root', '_system'); +test('replace user', function () { + $newUserData = [ + 'user' => 'newUserName', + 'active' => false, + ]; + $replaced = $this->schemaManager->replaceUser($this->userName, $newUserData); - $this->assertSame('rw', $accessLevel); - } + expect($replaced->user)->toBe($this->userName); +}); - public function testSetDatabaseAccessLevel() - { - $this->setUpAccessTest(); - $grant = 'rw'; +test('get database access level', function () { + $accessLevel = $this->schemaManager->getDatabaseAccessLevel('root', '_system'); - $results = $this->schemaManager->setDatabaseAccessLevel($this->userName, $this->accessDatabase, $grant); - $accessLevel = $this->schemaManager->getDatabaseAccessLevel($this->userName, $this->accessDatabase); + expect($accessLevel)->toBe('rw'); +}); - $this->assertObjectHasProperty($this->accessDatabase, $results); - $this->assertSame($grant, $results->{$this->accessDatabase}); - $this->assertSame($grant, $accessLevel); +test('set database access level', function () { + $this->setUpAccessTest(); + $grant = 'rw'; - $this->tearDownAccessTest(); - } + $results = $this->schemaManager->setDatabaseAccessLevel($this->userName, $this->accessDatabase, $grant); + $accessLevel = $this->schemaManager->getDatabaseAccessLevel($this->userName, $this->accessDatabase); - public function testClearDatabaseAccessLevel() - { - $this->setUpAccessTest(); - $grant = 'rw'; + $this->assertObjectHasProperty($this->accessDatabase, $results); + expect($results->{$this->accessDatabase})->toBe($grant); + expect($accessLevel)->toBe($grant); - $this->schemaManager->setDatabaseAccessLevel($this->userName, $this->accessDatabase, $grant); - $accessLevel = $this->schemaManager->getDatabaseAccessLevel($this->userName, $this->accessDatabase); - $this->assertSame($grant, $accessLevel); + $this->tearDownAccessTest(); +}); - $result = $this->schemaManager->clearDatabaseAccessLevel($this->userName, $this->accessDatabase); - $accessLevel = $this->schemaManager->getDatabaseAccessLevel($this->userName, $this->accessDatabase); +test('clear database access level', function () { + $this->setUpAccessTest(); + $grant = 'rw'; - $this->assertTrue($result); - $this->assertSame('none', $accessLevel); + $this->schemaManager->setDatabaseAccessLevel($this->userName, $this->accessDatabase, $grant); + $accessLevel = $this->schemaManager->getDatabaseAccessLevel($this->userName, $this->accessDatabase); + expect($accessLevel)->toBe($grant); - $this->tearDownAccessTest(); - } + $result = $this->schemaManager->clearDatabaseAccessLevel($this->userName, $this->accessDatabase); + $accessLevel = $this->schemaManager->getDatabaseAccessLevel($this->userName, $this->accessDatabase); - protected function setUpAccessTest() - { - if (!$this->schemaManager->hasDatabase($this->accessDatabase)) { - $this->schemaManager->createDatabase($this->accessDatabase); - } - } + expect($result)->toBeTrue(); + expect($accessLevel)->toBe('none'); - protected function tearDownAccessTest() - { - $this->schemaManager->deleteDatabase($this->accessDatabase); - } -} + $this->tearDownAccessTest(); +}); diff --git a/tests/SchemaManagerViewsTest.php b/tests/SchemaManagerViewsTest.php index 5519c5a..5ed96ad 100644 --- a/tests/SchemaManagerViewsTest.php +++ b/tests/SchemaManagerViewsTest.php @@ -2,111 +2,90 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -class SchemaManagerViewsTest extends TestCase -{ - protected array $view = [ - 'name' => 'testViewBasics', - 'type' => 'arangosearch', - ]; - - protected function setUp(): void - { - parent::setUp(); +beforeEach(function () { + if (!$this->schemaManager->hasView($this->view['name'])) { + $this->schemaManager->createView($this->view); + } +}); - if (!$this->schemaManager->hasView($this->view['name'])) { - $this->schemaManager->createView($this->view); - } +afterEach(function () { + if ($this->schemaManager->hasView($this->view['name'])) { + $this->schemaManager->deleteView($this->view['name']); } +}); - protected function tearDown(): void - { - parent::tearDown(); - if ($this->schemaManager->hasView($this->view['name'])) { - $this->schemaManager->deleteView($this->view['name']); - } - } +test('get views', function () { + $views = $this->schemaManager->getViews(); - public function testGetViews() - { - $views = $this->schemaManager->getViews(); + expect($views[0]->name)->toBe($this->view['name']); +}); - $this->assertSame($this->view['name'], $views[0]->name); - } +test('get view', function () { + $view = $this->schemaManager->getView($this->view['name']); - public function testGetView() - { - $view = $this->schemaManager->getView($this->view['name']); + expect($view->name)->toBe($this->view['name']); + $this->assertObjectHasProperty('type', $view); + $this->assertObjectHasProperty('links', $view); +}); - $this->assertSame($this->view['name'], $view->name); - $this->assertObjectHasProperty('type', $view); - $this->assertObjectHasProperty('links', $view); - } +test('get view properties', function () { + $view = $this->schemaManager->getViewProperties($this->view['name']); - public function testGetViewProperties() - { - $view = $this->schemaManager->getViewProperties($this->view['name']); + expect($view->name)->toBe($this->view['name']); + $this->assertObjectHasProperty('type', $view); + $this->assertObjectHasProperty('links', $view); +}); - $this->assertSame($this->view['name'], $view->name); - $this->assertObjectHasProperty('type', $view); - $this->assertObjectHasProperty('links', $view); - } +test('has view', function () { + $result = $this->schemaManager->hasView($this->view['name']); + expect($result)->toBeTrue(); - public function testHasView() - { - $result = $this->schemaManager->hasView($this->view['name']); - $this->assertTrue($result); + $result = $this->schemaManager->hasView('someNoneExistingView'); + expect($result)->toBeFalse(); +}); - $result = $this->schemaManager->hasView('someNoneExistingView'); - $this->assertFalse($result); - } +test('rename view', function () { + $newName = 'newName'; + $result = $this->schemaManager->renameView($this->view['name'], $newName); + expect($result->name)->toBe($newName); - public function testRenameView() - { - $newName = 'newName'; - $result = $this->schemaManager->renameView($this->view['name'], $newName); - $this->assertSame($newName, $result->name); + $this->schemaManager->deleteView($newName); +}); - $this->schemaManager->deleteView($newName); - } +test('update view', function () { + $newViewProps = [ + 'cleanupIntervalStep' => 3, + 'primarySort' => 'email', + ]; + $result = $this->schemaManager->updateView($this->view['name'], $newViewProps); - public function testUpdateView() - { - $newViewProps = [ - 'cleanupIntervalStep' => 3, - 'primarySort' => 'email', - ]; - $result = $this->schemaManager->updateView($this->view['name'], $newViewProps); + expect($result->cleanupIntervalStep)->toBe(3); +}); - $this->assertSame(3, $result->cleanupIntervalStep); - } +test('replace view', function () { + $newViewProps = [ + 'primarySort' => [[ + 'field' => 'email', + 'direction' => 'desc', + ]], + ]; + $newView = $this->schemaManager->replaceView($this->view['name'], $newViewProps); - public function testReplaceView() - { - $newViewProps = [ - 'primarySort' => [[ - 'field' => 'email', - 'direction' => 'desc', - ]], - ]; - $newView = $this->schemaManager->replaceView($this->view['name'], $newViewProps); - - $this->assertSame($newViewProps['primarySort'][0]['field'], $newView->primarySort[0]->field); - $this->assertFalse($newView->primarySort[0]->asc); - } + expect($newView->primarySort[0]->field)->toBe($newViewProps['primarySort'][0]['field']); + expect($newView->primarySort[0]->asc)->toBeFalse(); +}); - public function testCreateAndDeleteView() - { - $view = [ - 'name' => 'coolnewview', - ]; - $created = $this->schemaManager->createView($view); - $this->assertObjectHasProperty('name', $created); - $this->assertSame($view['name'], $created->name); - - $deleted = $this->schemaManager->deleteView($view['name']); - $this->assertTrue($deleted); - } -} +test('create and delete view', function () { + $view = [ + 'name' => 'coolnewview', + ]; + $created = $this->schemaManager->createView($view); + $this->assertObjectHasProperty('name', $created); + expect($created->name)->toBe($view['name']); + + $deleted = $this->schemaManager->deleteView($view['name']); + expect($deleted)->toBeTrue(); +}); diff --git a/tests/StatementTest.php b/tests/StatementTest.php index e58cf0c..8a6ed9e 100644 --- a/tests/StatementTest.php +++ b/tests/StatementTest.php @@ -2,162 +2,122 @@ declare(strict_types=1); -namespace Tests; +uses(Tests\TestCase::class); -use Traversable; - -class StatementTest extends TestCase -{ - protected Traversable $statement; - - protected string $collection = 'users'; - - protected function setUp(): void - { - parent::setUp(); - - if (!$this->schemaManager->hasCollection($this->collection)) { - $this->schemaManager->createCollection($this->collection); - } - $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; - - $this->statement = $this->arangoClient->prepare($query); +beforeEach(function () { + if (!$this->schemaManager->hasCollection($this->collection)) { + $this->schemaManager->createCollection($this->collection); } + $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; - protected function tearDown(): void - { - parent::tearDown(); + $this->statement = $this->arangoClient->prepare($query); +}); - if ($this->schemaManager->hasCollection($this->collection)) { - $this->schemaManager->deleteCollection($this->collection); - } +afterEach(function () { + if ($this->schemaManager->hasCollection($this->collection)) { + $this->schemaManager->deleteCollection($this->collection); } +}); - protected function generateTestDocuments(): void - { - $query = 'FOR i IN 1..10 - INSERT { - _key: CONCAT("test", i), - name: "test", - foobar: true - } INTO ' . $this->collection . ' OPTIONS { ignoreErrors: true }'; +test('set and get query', function () { + $query = 'FOR doc IN ' . $this->collection . ' LIMIT 1 RETURN doc'; - $statement = $this->arangoClient->prepare($query); + $statement = $this->statement->setQuery($query); - $statement->execute(); - } + expect($statement->getQuery())->toBe($query); +}); - public function testSetAndGetQuery() - { - $query = 'FOR doc IN ' . $this->collection . ' LIMIT 1 RETURN doc'; +test('explain', function () { + $explanation = $this->statement->explain(); - $statement = $this->statement->setQuery($query); + $this->assertObjectHasProperty('plan', $explanation); +}); - $this->assertSame($query, $statement->getQuery()); - } +test('parse', function () { + $parsed = $this->statement->parse(); - public function testExplain() - { - $explanation = $this->statement->explain(); + $this->assertObjectHasProperty('ast', $parsed); +}); - $this->assertObjectHasProperty('plan', $explanation); - } +test('profile', function () { + $profile = $this->statement->profile(); + $this->assertObjectHasProperty('stats', $profile); + $this->assertObjectHasProperty('profile', $profile); +}); - public function testParse() - { - $parsed = $this->statement->parse(); +test('profile mode two', function () { + $profile = $this->statement->profile(2); - $this->assertObjectHasProperty('ast', $parsed); - } + $this->assertObjectHasProperty('stats', $profile); + $this->assertObjectHasProperty('profile', $profile); + $this->assertObjectHasProperty('plan', $profile); +}); - public function testProfile() - { - $profile = $this->statement->profile(); - $this->assertObjectHasProperty('stats', $profile); - $this->assertObjectHasProperty('profile', $profile); - } +test('get count', function () { + $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; + $options = ['count' => true]; + $statement = $this->arangoClient->prepare($query, [], $options); + $statement->execute(); - public function testProfileModeTwo() - { - $profile = $this->statement->profile(2); + expect($statement->getCount())->toBe(0); +}); - $this->assertObjectHasProperty('stats', $profile); - $this->assertObjectHasProperty('profile', $profile); - $this->assertObjectHasProperty('plan', $profile); - } +test('get count not set', function () { + $this->statement->execute(); - public function testGetCount() - { - $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; - $options = ['count' => true]; - $statement = $this->arangoClient->prepare($query, [], $options); - $statement->execute(); + expect($this->statement->getCount())->toBeNull(); +}); - $this->assertSame(0, $statement->getCount()); - } - - public function testGetCountNotSet() - { - $this->statement->execute(); - - $this->assertNull($this->statement->getCount()); - } - - public function testFetchAll() - { - $this->generateTestDocuments(); +test('fetch all', function () { + $this->generateTestDocuments(); - $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; - $this->statement->setQuery($query); - $executed = $this->statement->execute(); - $this->assertTrue($executed); + $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; + $this->statement->setQuery($query); + $executed = $this->statement->execute(); + expect($executed)->toBeTrue(); - $results = $this->statement->fetchAll(); - $this->assertEquals(10, is_countable($results) ? count($results) : 0); - $this->assertSame('test1', $results[0]->_key); - } - - public function testResultsGreaterThanBatchSize() - { - $this->generateTestDocuments(); + $results = $this->statement->fetchAll(); + expect(is_countable($results) ? count($results) : 0)->toEqual(10); + expect($results[0]->_key)->toBe('test1'); +}); - // Retrieve data in batches of 2 - $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; - $options = ['batchSize' => 2]; - $statement = $this->arangoClient->prepare($query, [], $options); - $executed = $statement->execute(); - $this->assertTrue($executed); - $results = $statement->fetchAll(); +test('results greater than batch size', function () { + $this->generateTestDocuments(); - $this->assertEquals(10, count($results)); - $this->assertSame('test1', $results[0]->_key); - } - - public function testStatementIsIterable() - { - $this->generateTestDocuments(); - $this->statement->execute(); - - $count = 0; - foreach ($this->statement as $document) { - $this->assertObjectHasProperty('foobar', $document); - $count++; - } - $this->assertEquals(10, $count); - } + // Retrieve data in batches of 2 + $query = 'FOR doc IN ' . $this->collection . ' RETURN doc'; + $options = ['batchSize' => 2]; + $statement = $this->arangoClient->prepare($query, [], $options); + $executed = $statement->execute(); + expect($executed)->toBeTrue(); + $results = $statement->fetchAll(); - public function testGetWritesExecuted(): void - { - $query = 'FOR i IN 1..10 - INSERT { - _key: CONCAT("test", i), - name: "test", - foobar: true - } INTO ' . $this->collection . ' OPTIONS { ignoreErrors: true }'; + expect(count($results))->toEqual(10); + expect($results[0]->_key)->toBe('test1'); +}); - $statement = $this->arangoClient->prepare($query); - $statement->execute(); +test('statement is iterable', function () { + $this->generateTestDocuments(); + $this->statement->execute(); - $this->assertSame(10, $statement->getWritesExecuted()); + $count = 0; + foreach ($this->statement as $document) { + $this->assertObjectHasProperty('foobar', $document); + $count++; } -} + expect($count)->toEqual(10); +}); + +test('get writes executed', function () { + $query = 'FOR i IN 1..10 + INSERT { + _key: CONCAT("test", i), + name: "test", + foobar: true + } INTO ' . $this->collection . ' OPTIONS { ignoreErrors: true }'; + + $statement = $this->arangoClient->prepare($query); + $statement->execute(); + + expect($statement->getWritesExecuted())->toBe(10); +}); diff --git a/tests/StreamTransactionsTest.php b/tests/StreamTransactionsTest.php new file mode 100644 index 0000000..f225b20 --- /dev/null +++ b/tests/StreamTransactionsTest.php @@ -0,0 +1,107 @@ +arangoClient->transactions(); + expect($transactionManager)->toBeInstanceOf(TransactionManager::class); +}); + +test('begin transaction', function () { + $transactionId = $this->arangoClient->beginTransaction(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + expect($runningTransactions[0]->id)->toBe($transactionId); + + $this->arangoClient->abort(); +}); + +test('begin', function () { + $transactionId = $this->arangoClient->begin(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + $latestTransaction = end($runningTransactions); + expect($latestTransaction->id)->toBe($transactionId); + + $this->arangoClient->abort(); +}); + +test('abort', function () { + $transactionId = $this->arangoClient->beginTransaction(); + $aborted = $this->arangoClient->abort(); + expect($aborted)->toBeTrue(); + + $transactionsListedInManager = $this->arangoClient->transactions()->getTransactions(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + + $this->assertArrayNotHasKey($transactionId, $transactionsListedInManager); + expect(array_search($transactionId, array_column($runningTransactions, 'id')))->toBeFalse(); +}); + +test('roll back', function () { + $transactionId = $this->arangoClient->beginTransaction(); + $aborted = $this->arangoClient->rollBack(); + expect($aborted)->toBeTrue(); + + $transactionsListedInManager = $this->arangoClient->transactions()->getTransactions(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + + $this->assertArrayNotHasKey($transactionId, $transactionsListedInManager); + expect(array_search($transactionId, array_column($runningTransactions, 'id')))->toBeFalse(); +}); + +test('commit', function () { + if (!$this->arangoClient->schema()->hasCollection('Users')) { + $this->arangoClient->schema()->createCollection('Users'); + } + if (!$this->arangoClient->schema()->hasCollection('Customers')) { + $this->arangoClient->schema()->createCollection('Customers'); + } + + $collections = [ + 'write' => [ + 'Users', + 'Customers', + ], + ]; + + $this->arangoClient->beginTransaction($collections); + + $insertQuery = 'FOR i IN 1..10 + INSERT { + _key: CONCAT("test", i), + name: "test", + foobar: true + } INTO Users OPTIONS { ignoreErrors: true }'; + $insertStatement = $this->arangoClient->prepare($insertQuery); + $insertStatement->execute(); + + $getQuery = 'for user in Users RETURN user'; + $getStatement = $this->arangoClient->prepare($getQuery); + $getStatement->execute(); + + expect(count($getStatement->fetchAll()))->toEqual(10); + + $this->arangoClient->commit(); + + $getQuery = 'for user in Users RETURN user'; + $getStatement = $this->arangoClient->prepare($getQuery); + $getStatement->execute(); + + expect(count($getStatement->fetchAll()))->toEqual(10); + + $this->arangoClient->schema()->deleteCollection('Users'); + $this->arangoClient->schema()->deleteCollection('Customers'); +}); + +test('transaction manager setter and getter', function () { + $oldTransactionManager = $this->arangoClient->getTransactionManager(); + $newTransactionManager = new TransactionManager($this->arangoClient); + $this->arangoClient->setTransactionManager($newTransactionManager); + $retrievedNewTransactionManager = $this->arangoClient->getTransactionManager(); + + expect($oldTransactionManager)->toBeNull(); + expect(spl_object_id($retrievedNewTransactionManager))->toEqual(spl_object_id($newTransactionManager)); +}); diff --git a/tests/SupportsTransactionsTest.php b/tests/SupportsTransactionsTest.php deleted file mode 100644 index 8a87889..0000000 --- a/tests/SupportsTransactionsTest.php +++ /dev/null @@ -1,121 +0,0 @@ -arangoClient->transactions(); - $this->assertInstanceOf(TransactionManager::class, $transactionManager); - } - - public function testBeginTransaction() - { - $transactionId = $this->arangoClient->beginTransaction(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - $this->assertSame($transactionId, $runningTransactions[0]->id); - - $this->arangoClient->abort(); - } - - public function testBegin() - { - $transactionId = $this->arangoClient->begin(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - $this->assertSame($transactionId, $runningTransactions[0]->id); - - $this->arangoClient->abort(); - } - - public function testAbort() - { - $transactionId = $this->arangoClient->beginTransaction(); - $aborted = $this->arangoClient->abort(); - $this->assertTrue($aborted); - - $transactionsListedInManager = $this->arangoClient->transactions()->getTransactions(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - - $this->assertArrayNotHasKey($transactionId, $transactionsListedInManager); - $this->assertFalse(array_search($transactionId, array_column($runningTransactions, 'id'))); - } - - public function testRollBack() - { - $transactionId = $this->arangoClient->beginTransaction(); - $aborted = $this->arangoClient->rollBack(); - $this->assertTrue($aborted); - - $transactionsListedInManager = $this->arangoClient->transactions()->getTransactions(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - - $this->assertArrayNotHasKey($transactionId, $transactionsListedInManager); - $this->assertFalse(array_search($transactionId, array_column($runningTransactions, 'id'))); - } - - public function testCommit() - { - if (!$this->arangoClient->schema()->hasCollection('Users')) { - $this->arangoClient->schema()->createCollection('Users'); - } - if (!$this->arangoClient->schema()->hasCollection('Customers')) { - $this->arangoClient->schema()->createCollection('Customers'); - } - - $collections = [ - 'write' => [ - 'Users', - 'Customers', - ], - ]; - - $this->arangoClient->beginTransaction($collections); - - $insertQuery = 'FOR i IN 1..10 - INSERT { - _key: CONCAT("test", i), - name: "test", - foobar: true - } INTO Users OPTIONS { ignoreErrors: true }'; - $insertStatement = $this->arangoClient->prepare($insertQuery); - $insertStatement->execute(); - - $getQuery = 'for user in Users RETURN user'; - $getStatement = $this->arangoClient->prepare($getQuery); - $getStatement->execute(); - - $this->assertEquals(10, count($getStatement->fetchAll())); - - $this->arangoClient->commit(); - - $getQuery = 'for user in Users RETURN user'; - $getStatement = $this->arangoClient->prepare($getQuery); - $getStatement->execute(); - - $this->assertEquals(10, count($getStatement->fetchAll())); - - $this->arangoClient->schema()->deleteCollection('Users'); - $this->arangoClient->schema()->deleteCollection('Customers'); - } - - public function testTransactionManagerSetterAndGetter() - { - $oldTransactionManager = $this->arangoClient->getTransactionManager(); - $newTransactionManager = new TransactionManager($this->arangoClient); - $this->arangoClient->setTransactionManager($newTransactionManager); - $retrievedNewTransactionManager = $this->arangoClient->getTransactionManager(); - - $this->assertNull($oldTransactionManager); - $this->assertEquals(spl_object_id($newTransactionManager), spl_object_id($retrievedNewTransactionManager)); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index 4ae930a..57be3d3 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -22,6 +22,24 @@ abstract class TestCase extends PhpUnitTestCase protected string $testDatabaseName = 'arangodb_php_client__test'; + protected string $accessDatabase = 'arangodb_php_client_access__test'; + + protected array $analyzer = [ + 'name' => 'testAnalyzerBasics', + 'type' => 'identity', + ]; + + protected string $collection = 'users'; + + protected \Traversable $statement; + + protected string $userName = 'kimiko'; + + protected array $view = [ + 'name' => 'testViewBasics', + 'type' => 'arangosearch', + ]; + protected function setUp(): void { $this->arangoClient = new ArangoClient([ @@ -44,7 +62,33 @@ protected function createTestDatabase() } } - protected function skipTestOnArangoVersions(string $version, string $operator = '<') + public function setUpAccessTest() + { + if (!$this->schemaManager->hasDatabase($this->accessDatabase)) { + $this->schemaManager->createDatabase($this->accessDatabase); + } + } + + public function tearDownAccessTest() + { + $this->schemaManager->deleteDatabase($this->accessDatabase); + } + + public function generateTestDocuments(): void + { + $query = 'FOR i IN 1..10 + INSERT { + _key: CONCAT("test", i), + name: "test", + foobar: true + } INTO ' . $this->collection . ' OPTIONS { ignoreErrors: true }'; + + $statement = $this->arangoClient->prepare($query); + + $statement->execute(); + } + + public function skipTestOnArangoVersions(string $version, string $operator = '<') { if (version_compare(getenv('ARANGODB_VERSION'), $version, $operator)) { $this->markTestSkipped('This test does not support ArangoDB versions before ' . $version); diff --git a/tests/TransactionManagerTest.php b/tests/TransactionManagerTest.php index bc7c269..0199bb8 100644 --- a/tests/TransactionManagerTest.php +++ b/tests/TransactionManagerTest.php @@ -2,165 +2,147 @@ declare(strict_types=1); -namespace Tests; - use ArangoClient\Transactions\TransactionManager; -class TransactionManagerTest extends TestCase -{ - protected TransactionManager $transactionManager; +uses(Tests\TestCase::class); +beforeEach(function () { + $this->transactionManager = new TransactionManager($this->arangoClient); +}); - protected function setUp(): void - { - parent::setUp(); - $this->transactionManager = new TransactionManager($this->arangoClient); - } +test('begin', function () { + $transactionId = $this->transactionManager->begin(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + expect($runningTransactions[0]->id)->toBe($transactionId); - public function testBegin() - { - $transactionId = $this->transactionManager->begin(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - $this->assertSame($transactionId, $runningTransactions[0]->id); + $this->transactionManager->abort(); +}); - $this->transactionManager->abort(); - } +test('get transactions', function () { + $transactions = []; + $begunTransactions = $this->transactionManager->getTransactions(); + expect($begunTransactions)->toBeEmpty(); - public function testGetTransactions() - { - $transactions = []; - $begunTransactions = $this->transactionManager->getTransactions(); - $this->assertEmpty($begunTransactions); + $id = $this->transactionManager->begin(); + $transactions[$id] = $id; + $id = $this->transactionManager->begin(); + $transactions[$id] = $id; - $id = $this->transactionManager->begin(); - $transactions[$id] = $id; - $id = $this->transactionManager->begin(); - $transactions[$id] = $id; + $begunTransactions = $this->transactionManager->getTransactions(); - $begunTransactions = $this->transactionManager->getTransactions(); + expect($begunTransactions)->toBe($transactions); +}); - $this->assertSame($transactions, $begunTransactions); - } +test('get transaction', function () { + $transactions = []; + $transactions[] = $this->transactionManager->begin(); + $transactions[] = $this->transactionManager->begin(); - public function testGetTransaction() - { - $transactions = []; - $transactions[] = $this->transactionManager->begin(); - $transactions[] = $this->transactionManager->begin(); + $lastTransaction = $this->transactionManager->getTransaction(); - $lastTransaction = $this->transactionManager->getTransaction(); + expect($lastTransaction)->toBe($transactions[1]); +}); - $this->assertSame($transactions[1], $lastTransaction); - } +test('get transaction before begin', function () { + $this->expectExceptionCode(404); + $this->transactionManager->getTransaction(); +}); - public function testGetTransactionBeforeBegin() - { - $this->expectExceptionCode(404); - $this->transactionManager->getTransaction(); +test('begin multiple transactions', function () { + $transactions = []; + $transactions[] = $this->transactionManager->begin(); + $transactions[] = $this->transactionManager->begin(); + + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + $transactionsListedInManager = $this->transactionManager->getTransactions(); + + foreach ($transactions as $key => $id) { + expect($transactionsListedInManager)->toContain($id); + $this->assertNotFalse(array_search($id, array_column($runningTransactions, 'id'))); } + expect(count($transactionsListedInManager))->toEqual(count($transactions)); - public function testBeginMultipleTransactions() - { - $transactions = []; - $transactions[] = $this->transactionManager->begin(); - $transactions[] = $this->transactionManager->begin(); + $this->transactionManager->abortRunningTransactions(); +}); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - $transactionsListedInManager = $this->transactionManager->getTransactions(); +test('abort', function () { + $transactionId = $this->transactionManager->begin(); + $aborted = $this->transactionManager->abort(); + expect($aborted)->toBeTrue(); - foreach ($transactions as $key => $id) { - $this->assertContains($id, $transactionsListedInManager); - $this->assertNotFalse(array_search($id, array_column($runningTransactions, 'id'))); - } - $this->assertEquals(count($transactions), count($transactionsListedInManager)); + $transactionsListedInManager = $this->transactionManager->getTransactions(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); - $this->transactionManager->abortRunningTransactions(); - } + $this->assertArrayNotHasKey($transactionId, $transactionsListedInManager); + expect(array_search($transactionId, array_column($runningTransactions, 'id')))->toBeFalse(); +}); - public function testAbort() - { - $transactionId = $this->transactionManager->begin(); - $aborted = $this->transactionManager->abort(); - $this->assertTrue($aborted); +test('abort before commit', function () { + $this->expectExceptionCode(404); + $this->transactionManager->abort(); +}); - $transactionsListedInManager = $this->transactionManager->getTransactions(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); +test('abort wrong id', function () { + $this->expectExceptionCode(404); + $this->transactionManager->abort('nonExistingTransaction'); +}); - $this->assertArrayNotHasKey($transactionId, $transactionsListedInManager); - $this->assertFalse(array_search($transactionId, array_column($runningTransactions, 'id'))); - } +test('abort running transactions', function () { + $transactions = []; + $transactions[] = $this->transactionManager->begin(); + $transactions[] = $this->transactionManager->begin(); - public function testAbortBeforeCommit() - { - $this->expectExceptionCode(404); - $this->transactionManager->abort(); + $this->transactionManager->abortRunningTransactions(); + + $transactionsListedInManager = $this->transactionManager->getTransactions(); + $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + + expect($transactionsListedInManager)->toBeEmpty(); + foreach ($transactions as $id) { + expect(array_search($id, array_column($runningTransactions, 'id')))->toBeFalse(); } +}); - public function testAbortWrongId() - { - $this->expectExceptionCode(404); - $this->transactionManager->abort('nonExistingTransaction'); +test('commit', function () { + if (!$this->arangoClient->schema()->hasCollection('Users')) { + $this->arangoClient->schema()->createCollection('Users'); + } + if (!$this->arangoClient->schema()->hasCollection('Customers')) { + $this->arangoClient->schema()->createCollection('Customers'); } - public function testAbortRunningTransactions() - { - $transactions = []; - $transactions[] = $this->transactionManager->begin(); - $transactions[] = $this->transactionManager->begin(); + $collections = [ + 'write' => [ + 'Users', + 'Customers', + ], + ]; - $this->transactionManager->abortRunningTransactions(); + $this->transactionManager->begin($collections); - $transactionsListedInManager = $this->transactionManager->getTransactions(); - $runningTransactions = $this->arangoClient->admin()->getRunningTransactions(); + $insertQuery = 'FOR i IN 1..10 + INSERT { + _key: CONCAT("test", i), + name: "test", + foobar: true + } INTO Users OPTIONS { ignoreErrors: true }'; + $insertStatement = $this->arangoClient->prepare($insertQuery); + $insertStatement->execute(); - $this->assertEmpty($transactionsListedInManager); - foreach ($transactions as $id) { - $this->assertFalse(array_search($id, array_column($runningTransactions, 'id'))); - } - } + $getQuery = 'for user in Users RETURN user'; + $getStatement = $this->arangoClient->prepare($getQuery); + $getStatement->execute(); - public function testCommit() - { - if (!$this->arangoClient->schema()->hasCollection('Users')) { - $this->arangoClient->schema()->createCollection('Users'); - } - if (!$this->arangoClient->schema()->hasCollection('Customers')) { - $this->arangoClient->schema()->createCollection('Customers'); - } - - $collections = [ - 'write' => [ - 'Users', - 'Customers', - ], - ]; - - $this->transactionManager->begin($collections); - - $insertQuery = 'FOR i IN 1..10 - INSERT { - _key: CONCAT("test", i), - name: "test", - foobar: true - } INTO Users OPTIONS { ignoreErrors: true }'; - $insertStatement = $this->arangoClient->prepare($insertQuery); - $insertStatement->execute(); - - $getQuery = 'for user in Users RETURN user'; - $getStatement = $this->arangoClient->prepare($getQuery); - $getStatement->execute(); - - $this->assertEquals(10, count($getStatement->fetchAll())); - - $this->transactionManager->commit(); - - $getQuery = 'for user in Users RETURN user'; - $getStatement = $this->arangoClient->prepare($getQuery); - $getStatement->execute(); - - $this->assertEquals(10, count($getStatement->fetchAll())); - - $this->arangoClient->schema()->deleteCollection('Users'); - $this->arangoClient->schema()->deleteCollection('Customers'); - } -} + expect(count($getStatement->fetchAll()))->toEqual(10); + + $this->transactionManager->commit(); + + $getQuery = 'for user in Users RETURN user'; + $getStatement = $this->arangoClient->prepare($getQuery); + $getStatement->execute(); + + expect(count($getStatement->fetchAll()))->toEqual(10); + + $this->arangoClient->schema()->deleteCollection('Users'); + $this->arangoClient->schema()->deleteCollection('Customers'); +}); From 1cdd846ddd219887c79eea6397d7bf0dcfacc437 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:40:21 +0100 Subject: [PATCH 03/16] Feature: Added getCurrentConnections to MonitorManager.php (#35) --- src/Monitor/MonitorManager.php | 7 +++++++ tests/MonitorManagerTest.php | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/Monitor/MonitorManager.php b/src/Monitor/MonitorManager.php index 0ab0f0d..772cec1 100644 --- a/src/Monitor/MonitorManager.php +++ b/src/Monitor/MonitorManager.php @@ -17,4 +17,11 @@ public function getMetrics(): \stdClass return $this->arangoClient->request('get', $uri); } + + public function getCurrentConnections(): int + { + $metrics = $this->getMetrics(); + + return $metrics->arangodb_http1_connections_total->value + $metrics->arangodb_http2_connections_total->value; + } } diff --git a/tests/MonitorManagerTest.php b/tests/MonitorManagerTest.php index 4f941db..23d9dea 100644 --- a/tests/MonitorManagerTest.php +++ b/tests/MonitorManagerTest.php @@ -74,3 +74,10 @@ $result = $prometheus->parseText($rawMetrics); expect($result->arangodb_aql_local_query_memory_limit_reached_total->timestamp)->toEqual(2211753600); }); + +test('getCurrentConnections', function () { + $result = $this->arangoClient->monitor()->getCurrentConnections(); + + expect($result)->toBeInt(); + expect($result)->toBeGreaterThan(0); +}); From 3e0610464fa9e696c86d51bb17c45bd2972e1a58 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:54:36 +0100 Subject: [PATCH 04/16] Document getCurrentConnections monitor method Docs: Document getCurrentConnections monitor method --- docs/monitor-manager.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/monitor-manager.md b/docs/monitor-manager.md index db22c57..649e6e1 100644 --- a/docs/monitor-manager.md +++ b/docs/monitor-manager.md @@ -10,4 +10,12 @@ Get Prometheus metrics of the server ``` $arangoClient->monitor()->getMetrics(); -``` \ No newline at end of file +``` + + +### getCurrentConnections(): int +Get the total number of active connections (HTTP/1.1 & HTTP/2 combined) + +``` +$arangoClient->monitor()->getCurrentConnections(); +``` From 28dbf190312ab9a9474d3aa96093395ab977d9c9 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sat, 23 Nov 2024 11:49:30 +0100 Subject: [PATCH 05/16] Chore/php84 support (#36) * Feature: Added getCurrentConnections to MonitorManager.php * Migrated configuration * Added php8.4 to the matrix Removed ArangoDB 3.10 from the matrix * Fixed deprecations --- .github/workflows/run-tests.yml | 4 +-- phpunit.xml | 33 ++++++++++------------- src/ArangoClient.php | 4 +-- src/Prometheus/Metric.php | 1 + src/Transactions/SupportsTransactions.php | 10 +++---- src/Transactions/TransactionManager.php | 8 +++--- 6 files changed, 28 insertions(+), 32 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 646bf37..7a475d2 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -12,8 +12,8 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - arangodb: ["3.10", 3.11, 3.12] - php: [8.2, 8.3] + arangodb: [3.11, 3.12] + php: [8.2, 8.3, 8.4] stability: [prefer-stable] name: P${{ matrix.php }} - A${{ matrix.arangodb }} - ${{ matrix.stability }} diff --git a/phpunit.xml b/phpunit.xml index e12801e..9a7472c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,21 +1,16 @@ - - - - tests - - - - - tests - - - - - + + + + tests + + + + + + + + tests + + diff --git a/src/ArangoClient.php b/src/ArangoClient.php index 9f69e35..e5d42e7 100644 --- a/src/ArangoClient.php +++ b/src/ArangoClient.php @@ -42,7 +42,7 @@ class ArangoClient * * @throws UnknownProperties */ - public function __construct(array $config = [], GuzzleClient $httpClient = null) + public function __construct(array $config = [], ?GuzzleClient $httpClient = null) { $config['endpoint'] = $this->generateEndpoint($config); $this->config = new HttpClientConfig($config); @@ -196,7 +196,7 @@ public function prepare( /** * @return mixed */ - public function getConfig(string $value = null): mixed + public function getConfig(?string $value = null): mixed { if ($value) { return $this->config->$value; diff --git a/src/Prometheus/Metric.php b/src/Prometheus/Metric.php index 72a8173..dd170fb 100644 --- a/src/Prometheus/Metric.php +++ b/src/Prometheus/Metric.php @@ -25,5 +25,6 @@ public function __construct( public int|float|null $value = null, public ?array $buckets = [], public ?array $labels = [], + public null|int $timestamp = null, ) {} } diff --git a/src/Transactions/SupportsTransactions.php b/src/Transactions/SupportsTransactions.php index 127be4b..2d852e3 100644 --- a/src/Transactions/SupportsTransactions.php +++ b/src/Transactions/SupportsTransactions.php @@ -53,7 +53,7 @@ public function beginTransaction(array $collections = [], array $options = []): * * @throws ArangoException */ - public function abort(string $id = null): bool + public function abort(?string $id = null): bool { return $this->transactions()->abort($id); } @@ -64,7 +64,7 @@ public function abort(string $id = null): bool * * @throws ArangoException */ - public function rollBack(string $id = null): bool + public function rollBack(?string $id = null): bool { return $this->transactions()->abort($id); } @@ -75,7 +75,7 @@ public function rollBack(string $id = null): bool * * @throws ArangoException */ - public function commit(string $id = null): bool + public function commit(?string $id = null): bool { return $this->transactions()->commit($id); } @@ -89,8 +89,8 @@ public function transactionAwareRequest( string $method, string $uri, array|HttpRequestOptions $options = [], - string $database = null, - int $transactionId = null, + ?string $database = null, + ?int $transactionId = null, ): stdClass { if (is_array($options)) { $options = $this->prepareRequestOptions($options); diff --git a/src/Transactions/TransactionManager.php b/src/Transactions/TransactionManager.php index 97aa04f..872e0c8 100644 --- a/src/Transactions/TransactionManager.php +++ b/src/Transactions/TransactionManager.php @@ -37,7 +37,7 @@ public function getTransactions(): array /** * @throws ArangoException */ - public function getTransaction(string $id = null): string + public function getTransaction(?string $id = null): string { $this->validateId($id); @@ -72,7 +72,7 @@ public function begin(array $collections = [], array $options = []): string /** * @throws ArangoException */ - public function commit(string $id = null): bool + public function commit(?string $id = null): bool { $id = $this->getTransaction($id); @@ -87,7 +87,7 @@ public function commit(string $id = null): bool /** * @throws ArangoException */ - public function abort(string $id = null): bool + public function abort(?string $id = null): bool { $id = $this->getTransaction($id); @@ -102,7 +102,7 @@ public function abort(string $id = null): bool /** * @throws ArangoException */ - protected function validateId(string $id = null): bool + protected function validateId(?string $id = null): bool { if ( empty($this->transactions) From df102aa1208d9bc5f345e423e51e01211f21cc3a Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sat, 23 Nov 2024 11:50:45 +0100 Subject: [PATCH 06/16] Fixed typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fb02aa3..e03df63 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ $client->transactions()->begin(['write' => ['users', 'teams']]); 2) [AQL query statements](docs/statements.md) 3) [Admin manager](docs/admin-manager.md) 4) [Monitor manager](docs/monitor-manager.md) -5Schema manager +5) Schema manager 1) [Database schema](docs/schema-databases.md) 2) [User schema](docs/schema-users.md) 3) [Collection schema](docs/schema-collections.md) @@ -105,4 +105,4 @@ $client->transactions()->begin(['write' => ['users', 'teams']]); ## Related packages * [AQL query builder](https://github.com/LaravelFreelancerNL/fluentaql) -* [ArangoDB Laravel Driver](https://github.com/LaravelFreelancerNL/laravel-arangodb) \ No newline at end of file +* [ArangoDB Laravel Driver](https://github.com/LaravelFreelancerNL/laravel-arangodb) From 0eb3900feb796077eba8a352283f2a95a090bac9 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:27:01 +0100 Subject: [PATCH 07/16] Typo fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e03df63..0816999 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ $client->transactions()->begin(['write' => ['users', 'teams']]); 5) [Graph schema](docs/schema-graphs.md) 6) [View schema](docs/schema-views.md) 7) [Analyzer schema](docs/schema-analyzers.md) -6[Transaction manager](docs/transaction-manager.md) +6) [Transaction manager](docs/transaction-manager.md) ## Related packages * [AQL query builder](https://github.com/LaravelFreelancerNL/fluentaql) From 76c9d50450a1cf1a310b265b083db0c6a7a89c29 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Tue, 26 Nov 2024 00:23:27 +0100 Subject: [PATCH 08/16] Added deleteAllAnalyzers to SchemaManager. (#37) --- docs/schema-analyzers.md | 9 +++++++++ src/Schema/ManagesAnalyzers.php | 28 ++++++++++++++++++++++++++++ tests/SchemaManagerAnalyzersTest.php | 20 ++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/docs/schema-analyzers.md b/docs/schema-analyzers.md index b7f9d22..e901b84 100644 --- a/docs/schema-analyzers.md +++ b/docs/schema-analyzers.md @@ -37,7 +37,16 @@ $arangoClient->schema()->replaceAnalyzer('myAnalyzer', [ ``` ### deleteAnalyzer(string $name): bool +Delete the analyzer by its name. + ``` $arangoClient->schema()->deleteAnalyzer('myAnalyzer'); ``` +### deleteAllAnalyzers(): bool +This method deletes all custom analyzers available on the current database. + +``` +$arangoClient->schema()->deleteAllAnalyzers(); +``` + diff --git a/src/Schema/ManagesAnalyzers.php b/src/Schema/ManagesAnalyzers.php index 81272db..581d37f 100644 --- a/src/Schema/ManagesAnalyzers.php +++ b/src/Schema/ManagesAnalyzers.php @@ -53,6 +53,34 @@ public function deleteAnalyzer(string $name): bool return (bool) $this->arangoClient->request('delete', $uri); } + /** + * Removes all custom analyzes defined for the current database. + * + * @see https://docs.arangodb.com/stable/develop/http-api/analyzers/#remove-an-analyzer + * + * @throws ArangoException + */ + public function deleteAllAnalyzers(): bool + { + $analyzers = $this->getAnalyzers(); + + $database = $this->arangoClient->getDatabase(); + + foreach ($analyzers as $analyzer) { + if (!str_starts_with($analyzer->name, "$database::")) { + continue; + } + + $uri = '/_api/analyzer/' . $analyzer->name; + + $this->arangoClient->request('delete', $uri); + } + + return true; + } + + + /** * @see https://docs.arangodb.com/stable/develop/http-api/analyzers/#list-all-analyzers * diff --git a/tests/SchemaManagerAnalyzersTest.php b/tests/SchemaManagerAnalyzersTest.php index 0195370..68d2ed8 100644 --- a/tests/SchemaManagerAnalyzersTest.php +++ b/tests/SchemaManagerAnalyzersTest.php @@ -84,3 +84,23 @@ $hasAnalyzer = $this->schemaManager->hasAnalyzer($fullName); expect($hasAnalyzer)->toBeFalse(); }); + +test('deleteAllAnalyzers', function () { + $initialAnalyzers = $this->schemaManager->getAnalyzers(); + + $this->schemaManager->createAnalyzer([ + 'name' => 'customAnalyzer1', + 'type' => 'identity', + ]); + $this->schemaManager->createAnalyzer([ + 'name' => 'customAnalyzer2', + 'type' => 'identity', + ]); + + $this->schemaManager->deleteAllAnalyzers(); + + $endAnalyzers = $this->schemaManager->getAnalyzers(); + + // We already have an analyzer that is created before all tests. So, three analyzers are actually deleted. + expect(count($initialAnalyzers) - 1)->toBe(count($endAnalyzers)); +}); From ad5bc11331902b709627f0b8a47a8cc002e2e3ce Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:53:01 +0100 Subject: [PATCH 09/16] Added deleteAllCollections (#38) * Dried up deleteAllAnalyzers code * Added deleteAllCollections * Added deleteAllCollections --- docs/schema-collections.md | 6 ++++++ src/Schema/ManagesAnalyzers.php | 4 +--- src/Schema/ManagesCollections.php | 14 ++++++++++++++ tests/SchemaManagerCollectionsTest.php | 25 +++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/docs/schema-collections.md b/docs/schema-collections.md index 4c7fc1c..f0584f4 100644 --- a/docs/schema-collections.md +++ b/docs/schema-collections.md @@ -81,4 +81,10 @@ Delete a collection ``` $arangoClient->schema()->deleteCollection('users'); ``` +### deleteAllCollections(): bool +This method deletes all non-system collections available on the current database. + +``` +$arangoClient->schema()->deleteAllCollections(); +``` diff --git a/src/Schema/ManagesAnalyzers.php b/src/Schema/ManagesAnalyzers.php index 581d37f..d0ef3e0 100644 --- a/src/Schema/ManagesAnalyzers.php +++ b/src/Schema/ManagesAnalyzers.php @@ -71,9 +71,7 @@ public function deleteAllAnalyzers(): bool continue; } - $uri = '/_api/analyzer/' . $analyzer->name; - - $this->arangoClient->request('delete', $uri); + $this->deleteAnalyzer($analyzer->name); } return true; diff --git a/src/Schema/ManagesCollections.php b/src/Schema/ManagesCollections.php index ea2308c..db39948 100644 --- a/src/Schema/ManagesCollections.php +++ b/src/Schema/ManagesCollections.php @@ -214,4 +214,18 @@ public function deleteCollection(string $name): bool return (bool) $this->arangoClient->request('delete', $uri); } + + /** + * @throws ArangoException + */ + public function deleteAllCollections(): bool + { + $collections = $this->getCollections(true); + + foreach ($collections as $collection) { + $this->deleteCollection($collection->name); + } + + return true; + } } diff --git a/tests/SchemaManagerCollectionsTest.php b/tests/SchemaManagerCollectionsTest.php index f913ddd..a527bbf 100644 --- a/tests/SchemaManagerCollectionsTest.php +++ b/tests/SchemaManagerCollectionsTest.php @@ -192,3 +192,28 @@ $this->schemaManager->deleteCollection($collection); }); + +test('deleteAllCollections', function () { + $collection1 = 'collection1'; + $collection2 = 'collection2'; + + if (!$this->schemaManager->hasCollection($collection1)) { + $result = $this->schemaManager->createCollection($collection1, []); + expect($result->name)->toEqual($collection1); + } + + if (!$this->schemaManager->hasCollection($collection2)) { + $result = $this->schemaManager->createCollection($collection2, []); + expect($result->name)->toEqual($collection2); + } + + $createdCollections = $this->schemaManager->getCollections(true); + + $result = $this->schemaManager->deleteAllCollections(); + + $finalCollections = $this->schemaManager->getCollections(true); + + expect($result)->toBeTrue(); + expect(count($createdCollections))->toBe(2); + expect(count($finalCollections))->toBe(0); +}); From 4ffd75054f859cd1844b2738fa155516ce96a827 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Tue, 26 Nov 2024 20:20:51 +0100 Subject: [PATCH 10/16] Feat/add delete all views (#39) * Added newline * Added deleteAllViews --- docs/schema-collections.md | 1 + docs/schema-views.md | 7 +++++++ src/Schema/ManagesViews.php | 14 ++++++++++++++ tests/SchemaManagerViewsTest.php | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/docs/schema-collections.md b/docs/schema-collections.md index f0584f4..6200a7d 100644 --- a/docs/schema-collections.md +++ b/docs/schema-collections.md @@ -81,6 +81,7 @@ Delete a collection ``` $arangoClient->schema()->deleteCollection('users'); ``` + ### deleteAllCollections(): bool This method deletes all non-system collections available on the current database. diff --git a/docs/schema-views.md b/docs/schema-views.md index ab11cc1..21ca0bd 100644 --- a/docs/schema-views.md +++ b/docs/schema-views.md @@ -64,3 +64,10 @@ $arangoClient->schema()->updateView('pages', [ $arangoClient->schema()->deleteView('testViewBasics'); ``` +### deleteAllViews(): bool +This method deletes all views available on the current database. + +``` +$arangoClient->schema()->deleteAllViews(); +``` + diff --git a/src/Schema/ManagesViews.php b/src/Schema/ManagesViews.php index 8fa494c..ace5459 100644 --- a/src/Schema/ManagesViews.php +++ b/src/Schema/ManagesViews.php @@ -47,6 +47,20 @@ public function deleteView(string $name): bool return (bool) $this->arangoClient->request('delete', $uri); } + /** + * @throws ArangoException + */ + public function deleteAllViews(): bool + { + $views = $this->getViews(); + + foreach ($views as $view) { + $this->deleteView($view->name); + } + + return true; + } + /** * @see https://www.arangodb.com/docs/stable/http/views-arangosearch.html#list-all-views * diff --git a/tests/SchemaManagerViewsTest.php b/tests/SchemaManagerViewsTest.php index 5ed96ad..2934092 100644 --- a/tests/SchemaManagerViewsTest.php +++ b/tests/SchemaManagerViewsTest.php @@ -89,3 +89,25 @@ $deleted = $this->schemaManager->deleteView($view['name']); expect($deleted)->toBeTrue(); }); + +test('deleteAllViews', function () { + $view1 = [ + 'name' => 'view1', + ]; + $view2 = [ + 'name' => 'view2', + ]; + $this->schemaManager->createView($view1); + $this->schemaManager->createView($view2); + + + $createdViews = $this->schemaManager->getViews(); + + $result = $this->schemaManager->deleteAllViews(); + + $finalViews = $this->schemaManager->getViews(); + + expect($result)->toBeTrue(); + expect(count($createdViews))->toBe(3); + expect(count($finalViews))->toBe(0); +}); From 963f07879c0dc4bdd3abbea41b67b29f0c72ccf0 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Tue, 26 Nov 2024 20:31:32 +0100 Subject: [PATCH 11/16] Added deleteAllGraphs (#40) --- docs/schema-graphs.md | 7 +++++++ src/Schema/ManagesGraphs.php | 14 ++++++++++++++ tests/SchemaManagerGraphsTest.php | 15 +++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/docs/schema-graphs.md b/docs/schema-graphs.md index 1b4f2d4..92d2657 100644 --- a/docs/schema-graphs.md +++ b/docs/schema-graphs.md @@ -44,6 +44,13 @@ $arangoClient->schema()->hasGraph('relations'); $arangoClient->schema()->deleteGraph('locations'); ``` +### deleteAllGraphs(): bool +This method deletes all named graphs available on the current database. + +``` +$arangoClient->schema()->deleteAllGraphs(); +``` + ### getGraphVertices(string $name): array ``` $arangoClient->schema()->getGraphVertices('relations'); diff --git a/src/Schema/ManagesGraphs.php b/src/Schema/ManagesGraphs.php index ce090cb..3baf338 100644 --- a/src/Schema/ManagesGraphs.php +++ b/src/Schema/ManagesGraphs.php @@ -92,6 +92,20 @@ public function deleteGraph(string $name): bool return (bool) $this->arangoClient->request('delete', $uri); } + /** + * @throws ArangoException + */ + public function deleteAllGraphs(): bool + { + $graphs = $this->getGraphs(); + + foreach ($graphs as $graph) { + $this->deleteGraph($graph->name); + } + + return true; + } + /** * @see https://www.arangodb.com/docs/stable/http/gharial-management.html#list-vertex-collections * diff --git a/tests/SchemaManagerGraphsTest.php b/tests/SchemaManagerGraphsTest.php index c937f3e..0559eab 100644 --- a/tests/SchemaManagerGraphsTest.php +++ b/tests/SchemaManagerGraphsTest.php @@ -331,3 +331,18 @@ $this->schemaManager->deleteCollection('characters'); $this->schemaManager->deleteCollection('vassals'); }); + +test('deleteAllGraphs', function () { + $result = $this->schemaManager->createGraph('graph1', [], true); + $result = $this->schemaManager->createGraph('graph2', [], true); + + $createdGraphs = $this->schemaManager->getGraphs(); + + $result = $this->schemaManager->deleteAllGraphs(); + + $finalGraphs = $this->schemaManager->getGraphs(); + + expect($result)->toBeTrue(); + expect(count($createdGraphs))->toBe(2); + expect(count($finalGraphs))->toBe(0); +})->only(); From 58ed9f98b1423243984e4f77a1a9629498b5d0e4 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:52:05 +0100 Subject: [PATCH 12/16] Typo fix --- docs/transaction-manager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/transaction-manager.md b/docs/transaction-manager.md index 7a592f2..7d96028 100644 --- a/docs/transaction-manager.md +++ b/docs/transaction-manager.md @@ -53,7 +53,7 @@ Get the latest transaction id, or validate a given id. This method will throw if $arangoClient->transactions()->getTransaction('123'); ``` -### getTransaction() +### getTransactions() Get a list of all running transactions for this TransactionManager object. ``` From 4b8118c1ffc8ed9df84339d6bc873effb2dc18af Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sun, 1 Dec 2024 10:42:24 +0100 Subject: [PATCH 13/16] Update schema-graphs.md (#41) --- docs/schema-graphs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/schema-graphs.md b/docs/schema-graphs.md index 92d2657..4c99197 100644 --- a/docs/schema-graphs.md +++ b/docs/schema-graphs.md @@ -4,7 +4,7 @@ You can use the schema manager to perform CRUD actions on named graphs. ## Graph functions The schema manager supports the following graph functions: -### public function createGraph(string $name, array $config = [], $waitForSync = false): stdClass +### createGraph(string $name, array $config = [], $waitForSync = false): stdClass ``` $arangoClient->schema()->createGraph( 'relations', From 208d8dcb969512f80d44cb8c7aa7bc839b14e926 Mon Sep 17 00:00:00 2001 From: Laravel Freelancer NL <36150929+LaravelFreelancerNL@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:15:30 +0100 Subject: [PATCH 14/16] 42 add disconnect (#43) * chore: added .phpunit.cache * test: improved test * test: removed only. * feat: added disconnect functionality * chore: simplified disconnect * test: added rawRequest test * docs: improved disconnect docs * test: added connect test * fix: connect returns true upon success * docs: added connect method --------- Co-authored-by: Deploy --- .gitignore | 1 + docs/arangodb-client.md | 47 ++++++++++++++++++- src/ArangoClient.php | 52 +++++++++++++++++++++ tests/ArangoClientTest.php | 77 +++++++++++++++++++++++++++++-- tests/ExceptionsTest.php | 7 ++- tests/SchemaManagerGraphsTest.php | 2 +- 6 files changed, 176 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 7021d1d..0983d73 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .php_cs .php_cs.cache .phpunit.result.cache +.phpunit.cache .vscode clover.xml composer.lock diff --git a/docs/arangodb-client.md b/docs/arangodb-client.md index 12cafe6..c547619 100644 --- a/docs/arangodb-client.md +++ b/docs/arangodb-client.md @@ -66,8 +66,28 @@ Send a request to ArangoDB's HTTP REST API. This is mostly for internal use but $arangoClient->request( 'get', '/_api/version', - 'query' => [ - 'details' => $details + [ + 'query' => [ + 'details' => $details + ] + ] +]); +``` + +### rawRequest(string $method, string $uri, array|HttpRequestOptions $options = []): ResponseInterface|null +Returns the raw response of the request. +*Note* that the request itself is made against the configured endpoint but the databasename is _not_ automatically +prepended to the uri as opposed to a regular request. + + +``` +$arangoClient->rawRequest( + 'get', + '/_api/version', + [ + 'query' => [ + 'details' => $details + ] ] ]); ``` @@ -106,4 +126,27 @@ $arangoClient->schema()->createCollection('users'); Pass chained method to the admin manager. ``` $arangoClient->admin()->getVersion(); +``` + +### connect(array $config = [], ?GuzzleClient $httpClient = null): void +You can update the config by calling the connect method. This replaces the underlying connection +and prepares the connection for any requests that follow. + +``` +$config = [ + 'host' => 'http://localhost', + 'port' => '8529', + 'username' => 'your-other-database-username', + 'password' => 'your-other-database-password', + 'database'=> 'your-other-database' +]; + +$arangoClient->connect($config): void +``` + +### disconnect(): bool +Disconnect from the current keep-alive connection, if any. + +``` +$arangoClient->disconnect(); ``` \ No newline at end of file diff --git a/src/ArangoClient.php b/src/ArangoClient.php index e5d42e7..c8336ba 100644 --- a/src/ArangoClient.php +++ b/src/ArangoClient.php @@ -43,13 +43,41 @@ class ArangoClient * @throws UnknownProperties */ public function __construct(array $config = [], ?GuzzleClient $httpClient = null) + { + $this->connect($config, $httpClient); + } + + /** + * ArangoClient constructor. + * + * @param array $config + * @param GuzzleClient|null $httpClient + * + * @throws UnknownProperties + */ + public function connect(array $config = [], ?GuzzleClient $httpClient = null): bool { $config['endpoint'] = $this->generateEndpoint($config); $this->config = new HttpClientConfig($config); $this->httpClient = $httpClient ?? new GuzzleClient($this->config->mapGuzzleHttpClientConfig()); + + return true; } + /** + * We disconnect by creating a new guzzle client. The old client will remove the current connection upon destruction. + * + * @return bool + */ + public function disconnect(): bool + { + $this->httpClient = new GuzzleClient($this->config->mapGuzzleHttpClientConfig()); + + return true; + } + + /** * @param array $config */ @@ -58,10 +86,12 @@ public function generateEndpoint(array $config): string if (isset($config['endpoint'])) { return (string) $config['endpoint']; } + $endpoint = 'http://localhost:8529'; if (isset($config['host'])) { $endpoint = (string) $config['host']; } + if (isset($config['port'])) { $endpoint .= ':' . (string) $config['port']; } @@ -96,6 +126,28 @@ public function request(string $method, string $uri, array|HttpRequestOptions $o return new stdClass(); } + /** + * @param array|HttpRequestOptions $options + * + * @throws ArangoException + */ + public function rawRequest(string $method, string $uri, array|HttpRequestOptions $options = []): ResponseInterface|null + { + if (is_array($options)) { + $options = $this->prepareRequestOptions($options); + } + + $response = null; + try { + $response = $this->httpClient->request($method, $uri, $options->all()); + } catch (Throwable $e) { + $this->handleGuzzleException($e); + } + + return $response; + } + + /** * @param array $options * diff --git a/tests/ArangoClientTest.php b/tests/ArangoClientTest.php index 0187280..05aee95 100644 --- a/tests/ArangoClientTest.php +++ b/tests/ArangoClientTest.php @@ -4,14 +4,18 @@ use ArangoClient\Admin\AdminManager; use ArangoClient\ArangoClient; +use ArangoClient\Http\HttpClientConfig; use ArangoClient\Schema\SchemaManager; use ArangoClient\Statement\Statement; use GuzzleHttp\Client; +use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7\Response; +use function PHPUnit\Framework\assertTrue; + uses(Tests\TestCase::class); test('get config', function () { @@ -46,13 +50,13 @@ test('client with host port config', function () { $config = [ 'host' => 'http://127.0.0.1', - 'port' => '1234', + 'port' => '8529', 'username' => 'root', ]; $client = new ArangoClient($config); $retrievedConfig = $client->getConfig(); - expect($retrievedConfig['endpoint'])->toEqual('http://127.0.0.1:1234'); + expect($retrievedConfig['endpoint'])->toEqual('http://127.0.0.1:8529'); }); test('config with alien properties', function () { @@ -60,7 +64,7 @@ 'name' => 'arangodb', 'driver' => 'arangodb', 'host' => 'http://127.0.0.1', - 'port' => '1234', + 'port' => '8529', 'username' => 'root', ]; $client = new ArangoClient($config); @@ -73,8 +77,26 @@ test('set and get http client', function () { $oldClient = $this->arangoClient->getHttpClient(); - $newClient = Mockery::mock(Client::class); + $defaultConfig = [ + 'endpoint' => 'http://localhost:8529', + 'host' => null, + 'port' => null, + 'version' => 1.1, + 'connection' => 'Keep-Alive', + 'allow_redirects' => false, + 'connect_timeout' => 0.0, + 'username' => 'root', + 'password' => null, + 'database' => $this->testDatabaseName, + 'jsonStreamDecoderThreshold' => 1048576, + ]; + + $config = new HttpClientConfig($defaultConfig); + + $newClient = new GuzzleClient($config->mapGuzzleHttpClientConfig()); + $this->arangoClient->setHttpClient($newClient); + $retrievedClient = $this->arangoClient->getHttpClient(); expect($oldClient)->toBeInstanceOf(Client::class); @@ -89,6 +111,14 @@ expect($result->version)->toBeString(); }); + +test('rawRequest', function () { + $response = $this->arangoClient->rawRequest('get', '/_api/version', []); + + expect($response->getStatusCode())->toBe(200); + expect($response->getHeader('Connection')[0])->toBe('Keep-Alive'); +}); + test('get user', function () { $user = $this->arangoClient->getUser(); expect($user)->toBe('root'); @@ -103,10 +133,13 @@ $database = $this->arangoClient->getDatabase(); expect($database)->toBe($newDatabaseName); + + // Reset DB name + $this->arangoClient->setDatabase($this->testDatabaseName); }); test('database name is used in requests', function () { - $database = 'some_database'; + $database = 'arangodb_php_client__test'; if (!$this->arangoClient->schema()->hasDatabase($database)) { $this->arangoClient->schema()->createDatabase($database); } @@ -234,3 +267,37 @@ $this->schemaManager->deleteCollection($collection); }); + + +test('connect', function () { + $oldHttpClient = $this->arangoClient->getHttpClient(); + $oldHttpClientObjectId = spl_object_id($oldHttpClient); + + $newConfig = [ + 'endpoint' => 'http://localhost:8529', + 'version' => 2, + 'connection' => 'Close', + 'username' => 'root', + 'password' => null, + 'database' => $this->testDatabaseName, + 'jsonStreamDecoderThreshold' => 1048576, + ]; + + $response = $this->arangoClient->connect($newConfig); + + $newHttpClient = $this->arangoClient->getHttpClient(); + $newHttpClientObjectId = spl_object_id($newHttpClient); + + expect($oldHttpClientObjectId)->not()->toBe($newHttpClientObjectId); + expect($response)->toBeTrue(); + + $this->arangoClient->setHttpClient($oldHttpClient); +}); + + + +test('disconnect', function () { + $disconnected = $this->arangoClient->disconnect(); + + assertTrue($disconnected); +}); diff --git a/tests/ExceptionsTest.php b/tests/ExceptionsTest.php index 668aca1..980e2c6 100644 --- a/tests/ExceptionsTest.php +++ b/tests/ExceptionsTest.php @@ -2,6 +2,8 @@ declare(strict_types=1); +use ArangoClient\Exceptions\ArangoException; + uses(Tests\TestCase::class); test('test409 conflict exception', function () { @@ -18,6 +20,7 @@ test('calls to none existing db throw', function () { $this->arangoClient->setDatabase('NoneExistingDb'); - $this->expectExceptionCode(404); $this->schemaManager->hasCollection('dummy'); -}); + + $this->arangoClient->setDatabase($this->testDatabaseName); +})->throws(ArangoException::class); diff --git a/tests/SchemaManagerGraphsTest.php b/tests/SchemaManagerGraphsTest.php index 0559eab..faa8f7d 100644 --- a/tests/SchemaManagerGraphsTest.php +++ b/tests/SchemaManagerGraphsTest.php @@ -345,4 +345,4 @@ expect($result)->toBeTrue(); expect(count($createdGraphs))->toBe(2); expect(count($finalGraphs))->toBe(0); -})->only(); +}); From 31c101419a0c263008c105d2506778968c302211 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:44:00 +0000 Subject: [PATCH 15/16] build(deps): bump dependabot/fetch-metadata from 2.2.0 to 2.3.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.2.0...v2.3.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index eb537d8..2cb1d5e 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.2.0 + uses: dependabot/fetch-metadata@v2.3.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From 70b0ae18140b30aaf79ec9c1743cc299e12f3a74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 17:56:17 +0000 Subject: [PATCH 16/16] build(deps): bump dependabot/fetch-metadata from 2.3.0 to 2.4.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.3.0...v2.4.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 2cb1d5e..1a13177 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.3.0 + uses: dependabot/fetch-metadata@v2.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}"