From bdd8bebb22ce5dca7a678a43b6634238450a91a7 Mon Sep 17 00:00:00 2001 From: SergkeiM Date: Tue, 28 Jul 2026 14:49:08 +0300 Subject: [PATCH] Add extensive unit test suite and configure PCOV coverage Introduces a comprehensive suite of unit tests for various API endpoints and configuration builders, greatly enhancing test coverage. Configures PCOV for accurate code coverage reporting in the CI pipeline and local development environment. Includes minor bug fixes and documentation updates. --- .github/workflows/run-tests.yml | 2 +- .gitignore | 2 + .php-cs-fixer.dist.php | 4 + README.md | 2 +- docker/php/Dockerfile | 3 + src/CloudflareServiceProvider.php | 8 +- .../Rules/CacheSettingsRule.php | 2 +- src/Configurations/Rules/ExecuteRule.php | 2 +- .../Rules/LogCustomFieldRule.php | 2 +- src/Configurations/Rules/OriginRule.php | 2 +- src/Configurations/Rules/RedirectRule.php | 2 +- src/Configurations/Rules/RewriteRule.php | 2 +- src/Configurations/Rules/ScoreRule.php | 2 +- src/Configurations/Rules/ServeErrorRule.php | 2 +- src/Configurations/Rules/SkipRule.php | 2 +- src/Endpoints/Workers/Routes.php | 2 +- src/Endpoints/Zones/PageRules.php | 2 +- src/Exceptions/MissingArgumentException.php | 2 +- src/HttpClient/Response.php | 4 + .../Configurations/Rules/BlockRuleTest.php | 27 +++ .../Rules/CacheSettingsRuleTest.php | 21 ++ .../Rules/ChallengeRuleTest.php | 21 ++ .../Rules/CompressionRuleTest.php | 21 ++ .../Configurations/Rules/ConfigRuleTest.php | 21 ++ .../Rules/DDoSDynamicRuleTest.php | 21 ++ .../Configurations/Rules/ExecuteRuleTest.php | 21 ++ .../Rules/ForceConnectionCloseRuleTest.php | 21 ++ .../Rules/JSChallengeRuleTest.php | 21 ++ .../Rules/LogCustomFieldRuleTest.php | 21 ++ .../Configurations/Rules/LogRuleTest.php | 21 ++ .../Rules/ManagedChallengeRuleTest.php | 21 ++ .../Configurations/Rules/OriginRuleTest.php | 21 ++ .../Configurations/Rules/RedirectRuleTest.php | 21 ++ .../Configurations/Rules/RewriteRuleTest.php | 21 ++ test/Tests/Configurations/Rules/RuleTest.php | 76 ++++++ .../Configurations/Rules/ScoreRuleTest.php | 21 ++ .../Rules/ServeErrorRuleTest.php | 21 ++ .../Configurations/Rules/SkipRuleTest.php | 30 +++ test/Tests/Configurations/RulesetTest.php | 64 ++++++ .../Configurations/Workers/DeploymentTest.php | 18 +- .../Configurations/Zones/CachePurgeTest.php | 62 +++++ .../Configurations/Zones/PageRuleTest.php | 207 +++++++++++++++-- test/Tests/D1Test.php | 216 ++++++++++++++++++ .../Endpoints/Accounts/AuditLogsTest.php | 27 +++ test/Tests/Endpoints/Accounts/MembersTest.php | 100 ++++++++ test/Tests/Endpoints/Accounts/RolesTest.php | 41 ++++ .../Tests/Endpoints/Accounts/RulesetsTest.php | 91 ++++++++ test/Tests/Endpoints/AccountsTest.php | 119 ++++++++++ test/Tests/Endpoints/Tunnel/RoutesTest.php | 128 +++++++++++ .../Endpoints/Tunnel/VirtualNetworksTest.php | 103 +++++++++ test/Tests/Endpoints/Workers/CronTest.php | 45 ++++ .../Endpoints/Workers/DeploymentsTest.php | 62 +++++ test/Tests/Endpoints/Workers/DomainsTest.php | 74 ++++++ .../Endpoints/Workers/DurableObjectsTest.php | 21 ++ .../Endpoints/Workers/EnvironmentTest.php | 68 ++++++ test/Tests/Endpoints/Workers/KVTest.php | 157 +++++++++++++ test/Tests/Endpoints/Workers/LogsTest.php | 55 +++++ test/Tests/Endpoints/Workers/RoutesTest.php | 89 ++++++++ test/Tests/Endpoints/Workers/ScriptsTest.php | 175 ++++++++++++++ test/Tests/Endpoints/Workers/SettingsTest.php | 45 ++++ .../Tests/Endpoints/Workers/SubdomainTest.php | 42 ++++ test/Tests/Endpoints/Workers/VersionsTest.php | 52 +++++ .../Endpoints/Zones/CloudConnectorTest.php | 47 ++++ test/Tests/Endpoints/Zones/DNSSECTest.php | 61 +++++ test/Tests/Endpoints/Zones/DNSTest.php | 163 +++++++++++++ test/Tests/Endpoints/Zones/HoldTest.php | 71 ++++++ test/Tests/Endpoints/Zones/LockdownTest.php | 98 ++++++++ test/Tests/Endpoints/Zones/PageRulesTest.php | 166 ++++++++++++++ test/Tests/Endpoints/Zones/RulesTest.php | 46 ++++ test/Tests/Endpoints/Zones/RulesetsTest.php | 91 ++++++++ test/Tests/Endpoints/ZonesTest.php | 170 ++++++++++++++ .../MissingArgumentExceptionTest.php | 32 +++ test/Tests/ExpressionBuilderTest.php | 159 +++++++++++++ .../Exceptions/RequestExceptionTest.php | 35 +++ test/Tests/HttpClient/HttpClientTest.php | 98 ++++++++ test/Tests/HttpClient/ResponseTest.php | 88 +++++++ test/Tests/IPTest.php | 27 +++ 77 files changed, 3898 insertions(+), 33 deletions(-) create mode 100644 test/Tests/Configurations/Rules/BlockRuleTest.php create mode 100644 test/Tests/Configurations/Rules/CacheSettingsRuleTest.php create mode 100644 test/Tests/Configurations/Rules/ChallengeRuleTest.php create mode 100644 test/Tests/Configurations/Rules/CompressionRuleTest.php create mode 100644 test/Tests/Configurations/Rules/ConfigRuleTest.php create mode 100644 test/Tests/Configurations/Rules/DDoSDynamicRuleTest.php create mode 100644 test/Tests/Configurations/Rules/ExecuteRuleTest.php create mode 100644 test/Tests/Configurations/Rules/ForceConnectionCloseRuleTest.php create mode 100644 test/Tests/Configurations/Rules/JSChallengeRuleTest.php create mode 100644 test/Tests/Configurations/Rules/LogCustomFieldRuleTest.php create mode 100644 test/Tests/Configurations/Rules/LogRuleTest.php create mode 100644 test/Tests/Configurations/Rules/ManagedChallengeRuleTest.php create mode 100644 test/Tests/Configurations/Rules/OriginRuleTest.php create mode 100644 test/Tests/Configurations/Rules/RedirectRuleTest.php create mode 100644 test/Tests/Configurations/Rules/RewriteRuleTest.php create mode 100644 test/Tests/Configurations/Rules/RuleTest.php create mode 100644 test/Tests/Configurations/Rules/ScoreRuleTest.php create mode 100644 test/Tests/Configurations/Rules/ServeErrorRuleTest.php create mode 100644 test/Tests/Configurations/Rules/SkipRuleTest.php create mode 100644 test/Tests/Configurations/RulesetTest.php create mode 100644 test/Tests/D1Test.php create mode 100644 test/Tests/Endpoints/Accounts/AuditLogsTest.php create mode 100644 test/Tests/Endpoints/Accounts/MembersTest.php create mode 100644 test/Tests/Endpoints/Accounts/RolesTest.php create mode 100644 test/Tests/Endpoints/Accounts/RulesetsTest.php create mode 100644 test/Tests/Endpoints/AccountsTest.php create mode 100644 test/Tests/Endpoints/Tunnel/RoutesTest.php create mode 100644 test/Tests/Endpoints/Tunnel/VirtualNetworksTest.php create mode 100644 test/Tests/Endpoints/Workers/CronTest.php create mode 100644 test/Tests/Endpoints/Workers/DeploymentsTest.php create mode 100644 test/Tests/Endpoints/Workers/DomainsTest.php create mode 100644 test/Tests/Endpoints/Workers/EnvironmentTest.php create mode 100644 test/Tests/Endpoints/Workers/LogsTest.php create mode 100644 test/Tests/Endpoints/Workers/RoutesTest.php create mode 100644 test/Tests/Endpoints/Workers/ScriptsTest.php create mode 100644 test/Tests/Endpoints/Workers/SettingsTest.php create mode 100644 test/Tests/Endpoints/Workers/SubdomainTest.php create mode 100644 test/Tests/Endpoints/Workers/VersionsTest.php create mode 100644 test/Tests/Endpoints/Zones/CloudConnectorTest.php create mode 100644 test/Tests/Endpoints/Zones/DNSSECTest.php create mode 100644 test/Tests/Endpoints/Zones/DNSTest.php create mode 100644 test/Tests/Endpoints/Zones/HoldTest.php create mode 100644 test/Tests/Endpoints/Zones/LockdownTest.php create mode 100644 test/Tests/Endpoints/Zones/PageRulesTest.php create mode 100644 test/Tests/Endpoints/Zones/RulesTest.php create mode 100644 test/Tests/Endpoints/Zones/RulesetsTest.php create mode 100644 test/Tests/Endpoints/ZonesTest.php create mode 100644 test/Tests/Exceptions/MissingArgumentExceptionTest.php create mode 100644 test/Tests/ExpressionBuilderTest.php create mode 100644 test/Tests/HttpClient/Exceptions/RequestExceptionTest.php create mode 100644 test/Tests/HttpClient/HttpClientTest.php create mode 100644 test/Tests/HttpClient/ResponseTest.php create mode 100644 test/Tests/IPTest.php diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 7276fb1..22efef6 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -32,7 +32,7 @@ jobs: with: php-version: ${{ matrix.php }} tools: composer:v2 - coverage: none + coverage: pcov env: update: true diff --git a/.gitignore b/.gitignore index d797add..b8e3bcf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ phpunit.xml .phpunit.cache .phpunit.result.cache +clover.xml +coverage-report composer.lock composer.phar vendor diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index f51d57b..728d7d2 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,7 +4,11 @@ ->in(__DIR__) ->exclude([ "local-test", + "docker", ".github", + ".vscode", + ".phpunit.cache", + "docs", "vendor", "node_modules" ]); diff --git a/README.md b/README.md index 0d4e1c6..c69bf43 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ This package requires **PHP >= 8.2** and supports **Laravel 12 and 13** (via `il | PHP | Laravel 12 | Laravel 13 | | --- | :---: | :---: | -| 8.2 | ✅ | — (Laravel 13 requires PHP >= 8.3) | +| 8.2 | ✅ | ❌ | | 8.3 | ✅ | ✅ | | 8.4 | ✅ | ✅ | | 8.5 | ✅ | ✅ | diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile index 516a338..b234219 100644 --- a/docker/php/Dockerfile +++ b/docker/php/Dockerfile @@ -6,7 +6,10 @@ RUN apt-get update \ git \ unzip \ libzip-dev \ + $PHPIZE_DEPS \ && docker-php-ext-install zip \ + && pecl install pcov \ + && docker-php-ext-enable pcov \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/CloudflareServiceProvider.php b/src/CloudflareServiceProvider.php index 357c49f..1c66f13 100644 --- a/src/CloudflareServiceProvider.php +++ b/src/CloudflareServiceProvider.php @@ -30,9 +30,15 @@ private function setupConfig(): void if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) { $this->publishes([$source => $this->app->configPath('cloudflare.php')]); - } elseif ($this->app instanceof LumenApplication) { + } + // @codeCoverageIgnoreStart + // Lumen is discontinued and not an installed dependency here (only + // referenced for interface compatibility); this branch cannot be + // exercised without adding a dependency on an abandoned framework. + elseif ($this->app instanceof LumenApplication) { $this->app->configure('cloudflare'); } + // @codeCoverageIgnoreEnd $this->mergeConfigFrom($source, 'cloudflare'); } diff --git a/src/Configurations/Rules/CacheSettingsRule.php b/src/Configurations/Rules/CacheSettingsRule.php index c55f592..d3e2d38 100644 --- a/src/Configurations/Rules/CacheSettingsRule.php +++ b/src/Configurations/Rules/CacheSettingsRule.php @@ -12,6 +12,6 @@ class CacheSettingsRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/ExecuteRule.php b/src/Configurations/Rules/ExecuteRule.php index ac9f95d..1e95b07 100644 --- a/src/Configurations/Rules/ExecuteRule.php +++ b/src/Configurations/Rules/ExecuteRule.php @@ -12,6 +12,6 @@ class ExecuteRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/LogCustomFieldRule.php b/src/Configurations/Rules/LogCustomFieldRule.php index d2cf7ff..835bb35 100644 --- a/src/Configurations/Rules/LogCustomFieldRule.php +++ b/src/Configurations/Rules/LogCustomFieldRule.php @@ -12,6 +12,6 @@ class LogCustomFieldRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/OriginRule.php b/src/Configurations/Rules/OriginRule.php index 0a14430..bb96bd5 100644 --- a/src/Configurations/Rules/OriginRule.php +++ b/src/Configurations/Rules/OriginRule.php @@ -12,6 +12,6 @@ class OriginRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/RedirectRule.php b/src/Configurations/Rules/RedirectRule.php index 7eb7d86..4757152 100644 --- a/src/Configurations/Rules/RedirectRule.php +++ b/src/Configurations/Rules/RedirectRule.php @@ -12,6 +12,6 @@ class RedirectRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/RewriteRule.php b/src/Configurations/Rules/RewriteRule.php index ab5d9cd..0f79d78 100644 --- a/src/Configurations/Rules/RewriteRule.php +++ b/src/Configurations/Rules/RewriteRule.php @@ -12,6 +12,6 @@ class RewriteRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/ScoreRule.php b/src/Configurations/Rules/ScoreRule.php index 2474704..aee80f0 100644 --- a/src/Configurations/Rules/ScoreRule.php +++ b/src/Configurations/Rules/ScoreRule.php @@ -12,6 +12,6 @@ class ScoreRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/ServeErrorRule.php b/src/Configurations/Rules/ServeErrorRule.php index bd99cbe..e84a70d 100644 --- a/src/Configurations/Rules/ServeErrorRule.php +++ b/src/Configurations/Rules/ServeErrorRule.php @@ -12,6 +12,6 @@ class ServeErrorRule extends Rule protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Configurations/Rules/SkipRule.php b/src/Configurations/Rules/SkipRule.php index 8a8eac9..7ec6dc8 100644 --- a/src/Configurations/Rules/SkipRule.php +++ b/src/Configurations/Rules/SkipRule.php @@ -40,6 +40,6 @@ public function disableLogging(): self protected function getActionParameters(): ?array { - + return null; } } diff --git a/src/Endpoints/Workers/Routes.php b/src/Endpoints/Workers/Routes.php index 37cf518..a2f6149 100644 --- a/src/Endpoints/Workers/Routes.php +++ b/src/Endpoints/Workers/Routes.php @@ -35,7 +35,7 @@ public function create(string $zoneId, array $values): ResponseInterface { $this->requiredParams(['pattern'], $values); - return $this->$this->getHttpClient()->post("/zones/{$zoneId}/workers/routes", $values); + return $this->getHttpClient()->post("/zones/{$zoneId}/workers/routes", $values); } /** diff --git a/src/Endpoints/Zones/PageRules.php b/src/Endpoints/Zones/PageRules.php index 72add30..06d5db0 100644 --- a/src/Endpoints/Zones/PageRules.php +++ b/src/Endpoints/Zones/PageRules.php @@ -55,7 +55,7 @@ public function create(string $zoneId, array|PageRule $values): ResponseInterfac $values = $values->toArray(); } - return $this->$this->getHttpClient()->post("/zones/{$zoneId}/pagerules", $values); + return $this->getHttpClient()->post("/zones/{$zoneId}/pagerules", $values); } /** diff --git a/src/Exceptions/MissingArgumentException.php b/src/Exceptions/MissingArgumentException.php index ef3d113..cf734c8 100644 --- a/src/Exceptions/MissingArgumentException.php +++ b/src/Exceptions/MissingArgumentException.php @@ -9,7 +9,7 @@ class MissingArgumentException extends \ErrorException * @param int $code * @param \Throwable|null $previous */ - public function __construct($required, int $code = 0, \Throwable $previous = null) + public function __construct($required, int $code = 0, ?\Throwable $previous = null) { if (is_string($required)) { $required = [$required]; diff --git a/src/HttpClient/Response.php b/src/HttpClient/Response.php index 4dfbc26..f3e564a 100644 --- a/src/HttpClient/Response.php +++ b/src/HttpClient/Response.php @@ -114,6 +114,9 @@ public function get($target, $key, $default = null) foreach ($key as $i => $segment) { unset($key[$i]); + // @codeCoverageIgnoreStart + // $key is always exploded into string segments above, so $segment + // can never actually be null or a float; kept as defensive guards. if (is_null($segment)) { return $target; } @@ -121,6 +124,7 @@ public function get($target, $key, $default = null) if (is_float($segment)) { $segment = (string) $segment; } + // @codeCoverageIgnoreEnd if (is_array($target) && array_key_exists($segment, $target)) { $target = $target[$segment]; diff --git a/test/Tests/Configurations/Rules/BlockRuleTest.php b/test/Tests/Configurations/Rules/BlockRuleTest.php new file mode 100644 index 0000000..28ef11a --- /dev/null +++ b/test/Tests/Configurations/Rules/BlockRuleTest.php @@ -0,0 +1,27 @@ + 'blocked'], 'application/json', 403); + + $array = $rule->toArray(); + + $this->assertSame('block', $array['action']); + $this->assertSame([ + 'response' => [ + 'content' => ['error' => 'blocked'], + 'content_type' => 'application/json', + 'status_code' => 403, + ], + ], $array['action_parameters']); + } +} diff --git a/test/Tests/Configurations/Rules/CacheSettingsRuleTest.php b/test/Tests/Configurations/Rules/CacheSettingsRuleTest.php new file mode 100644 index 0000000..1e1570d --- /dev/null +++ b/test/Tests/Configurations/Rules/CacheSettingsRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('set_cache_settings', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/ChallengeRuleTest.php b/test/Tests/Configurations/Rules/ChallengeRuleTest.php new file mode 100644 index 0000000..3951421 --- /dev/null +++ b/test/Tests/Configurations/Rules/ChallengeRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('challenge', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/CompressionRuleTest.php b/test/Tests/Configurations/Rules/CompressionRuleTest.php new file mode 100644 index 0000000..83fc737 --- /dev/null +++ b/test/Tests/Configurations/Rules/CompressionRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('compress_response', $array['action']); + $this->assertSame(['algorithms' => ['name' => 'gzip']], $array['action_parameters']); + } +} diff --git a/test/Tests/Configurations/Rules/ConfigRuleTest.php b/test/Tests/Configurations/Rules/ConfigRuleTest.php new file mode 100644 index 0000000..adbea57 --- /dev/null +++ b/test/Tests/Configurations/Rules/ConfigRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('set_config', $array['action']); + $this->assertSame(['ssl' => 'flexible'], $array['action_parameters']); + } +} diff --git a/test/Tests/Configurations/Rules/DDoSDynamicRuleTest.php b/test/Tests/Configurations/Rules/DDoSDynamicRuleTest.php new file mode 100644 index 0000000..c1135c2 --- /dev/null +++ b/test/Tests/Configurations/Rules/DDoSDynamicRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('ddos_dynamic', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/ExecuteRuleTest.php b/test/Tests/Configurations/Rules/ExecuteRuleTest.php new file mode 100644 index 0000000..d12bcb7 --- /dev/null +++ b/test/Tests/Configurations/Rules/ExecuteRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('execute', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/ForceConnectionCloseRuleTest.php b/test/Tests/Configurations/Rules/ForceConnectionCloseRuleTest.php new file mode 100644 index 0000000..bde97f1 --- /dev/null +++ b/test/Tests/Configurations/Rules/ForceConnectionCloseRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('force_connection_close', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/JSChallengeRuleTest.php b/test/Tests/Configurations/Rules/JSChallengeRuleTest.php new file mode 100644 index 0000000..8836495 --- /dev/null +++ b/test/Tests/Configurations/Rules/JSChallengeRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('js_challenge', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/LogCustomFieldRuleTest.php b/test/Tests/Configurations/Rules/LogCustomFieldRuleTest.php new file mode 100644 index 0000000..21c303e --- /dev/null +++ b/test/Tests/Configurations/Rules/LogCustomFieldRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('log_custom_field', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/LogRuleTest.php b/test/Tests/Configurations/Rules/LogRuleTest.php new file mode 100644 index 0000000..9ee3dcf --- /dev/null +++ b/test/Tests/Configurations/Rules/LogRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('log', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/ManagedChallengeRuleTest.php b/test/Tests/Configurations/Rules/ManagedChallengeRuleTest.php new file mode 100644 index 0000000..b92f351 --- /dev/null +++ b/test/Tests/Configurations/Rules/ManagedChallengeRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('managed_challenge', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/OriginRuleTest.php b/test/Tests/Configurations/Rules/OriginRuleTest.php new file mode 100644 index 0000000..925457a --- /dev/null +++ b/test/Tests/Configurations/Rules/OriginRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('route', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/RedirectRuleTest.php b/test/Tests/Configurations/Rules/RedirectRuleTest.php new file mode 100644 index 0000000..0c9bc63 --- /dev/null +++ b/test/Tests/Configurations/Rules/RedirectRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('redirect', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/RewriteRuleTest.php b/test/Tests/Configurations/Rules/RewriteRuleTest.php new file mode 100644 index 0000000..cc286dd --- /dev/null +++ b/test/Tests/Configurations/Rules/RewriteRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('rewrite', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/RuleTest.php b/test/Tests/Configurations/Rules/RuleTest.php new file mode 100644 index 0000000..8fbb1fb --- /dev/null +++ b/test/Tests/Configurations/Rules/RuleTest.php @@ -0,0 +1,76 @@ +assertSame([ + 'action' => 'log', + 'enabled' => false, + 'expression' => true, + ], $rule->toArray()); + } + + #[Test] + public function shouldEnableAndDisable() + { + $rule = (new LogRule())->enable(); + $this->assertTrue($rule->toArray()['enabled']); + + $rule->disable(); + $this->assertFalse($rule->toArray()['enabled']); + } + + #[Test] + public function shouldSetDescriptionIdAndRef() + { + $rule = (new LogRule()) + ->setDescription('my description') + ->setId('rule_id') + ->setRef('rule_ref'); + + $array = $rule->toArray(); + + $this->assertSame('my description', $array['description']); + $this->assertSame('rule_id', $array['id']); + $this->assertSame('rule_ref', $array['ref']); + } + + #[Test] + public function shouldSetExpressionFromString() + { + $rule = (new LogRule())->setExpression('ip.src eq 127.0.0.1'); + + $this->assertSame('ip.src eq 127.0.0.1', $rule->toArray()['expression']); + } + + #[Test] + public function shouldSetExpressionFromExpressionBuilder() + { + $builder = (new ExpressionBuilder())->field('ip.src')->eq('127.0.0.1'); + + $rule = (new LogRule())->setExpression($builder); + + $this->assertSame((string) $builder, $rule->toArray()['expression']); + } + + #[Test] + public function shouldSetExpressionFromClosure() + { + $rule = (new LogRule())->setExpression(function (ExpressionBuilder $builder) { + return $builder->field('ip.src')->eq('127.0.0.1'); + }); + + $this->assertSame('ip.src eq 127.0.0.1', $rule->toArray()['expression']); + } +} diff --git a/test/Tests/Configurations/Rules/ScoreRuleTest.php b/test/Tests/Configurations/Rules/ScoreRuleTest.php new file mode 100644 index 0000000..81b5b17 --- /dev/null +++ b/test/Tests/Configurations/Rules/ScoreRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('score', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/ServeErrorRuleTest.php b/test/Tests/Configurations/Rules/ServeErrorRuleTest.php new file mode 100644 index 0000000..a4e81d3 --- /dev/null +++ b/test/Tests/Configurations/Rules/ServeErrorRuleTest.php @@ -0,0 +1,21 @@ +toArray(); + + $this->assertSame('serve_error', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } +} diff --git a/test/Tests/Configurations/Rules/SkipRuleTest.php b/test/Tests/Configurations/Rules/SkipRuleTest.php new file mode 100644 index 0000000..5b60142 --- /dev/null +++ b/test/Tests/Configurations/Rules/SkipRuleTest.php @@ -0,0 +1,30 @@ +toArray(); + + $this->assertSame('skip', $array['action']); + $this->assertArrayNotHasKey('action_parameters', $array); + } + + #[Test] + public function shouldEnableAndDisableLogging() + { + $rule = new SkipRule(); + + $this->assertSame($rule, $rule->enableLogging()); + $this->assertSame($rule, $rule->disableLogging()); + } +} diff --git a/test/Tests/Configurations/RulesetTest.php b/test/Tests/Configurations/RulesetTest.php new file mode 100644 index 0000000..7687948 --- /dev/null +++ b/test/Tests/Configurations/RulesetTest.php @@ -0,0 +1,64 @@ +zone()->requestFirewallCustom(); + + $this->assertSame([ + 'name' => 'my ruleset', + 'kind' => 'zone', + 'phase' => 'http_request_firewall_custom', + 'rules' => [], + ], $ruleset->toArray()); + } + + #[Test] + public function shouldSetNameAndDescription() + { + $ruleset = (new Ruleset('my ruleset')) + ->setName('renamed') + ->setDescription('an informative description') + ->managed() + ->ddosL4(); + + $array = $ruleset->toArray(); + + $this->assertSame('renamed', $array['name']); + $this->assertSame('managed', $array['kind']); + $this->assertSame('ddos_l4', $array['phase']); + $this->assertSame('an informative description', $array['description']); + } + + #[Test] + public function shouldAddRules() + { + $ruleset = (new Ruleset('my ruleset')) + ->custom() + ->rateLimit() + ->addRule((new BlockRule(['error' => 'blocked']))->setExpression('true')); + + $array = $ruleset->toArray(); + + $this->assertCount(1, $array['rules']); + $this->assertSame('block', $array['rules'][0]['action']); + } + + #[Test] + public function shouldThrowOnUndefinedMethod() + { + $this->expectException(BadMethodCallException::class); + + (new Ruleset('my ruleset'))->notARealMethod(); + } +} diff --git a/test/Tests/Configurations/Workers/DeploymentTest.php b/test/Tests/Configurations/Workers/DeploymentTest.php index 5e5dfa6..435c1cb 100644 --- a/test/Tests/Configurations/Workers/DeploymentTest.php +++ b/test/Tests/Configurations/Workers/DeploymentTest.php @@ -4,8 +4,9 @@ use Cloudflare\Configurations\Workers\Deployment; use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; -class DeploymentTest extends \PHPUnit\Framework\TestCase +class DeploymentTest extends TestCase { #[Test] public function shouldNotHaveVersions() @@ -21,6 +22,7 @@ public function shouldNotHaveVersions() ], $deployment->toArray()); } + #[Test] public function shouldHaveVersions() { $deployment = new Deployment('This is a human-readable message about the deployment'); @@ -41,6 +43,20 @@ public function shouldHaveVersions() ], $deployment->toArray()); } + #[Test] + public function shouldOverrideExistingVersion() + { + $deployment = (new Deployment('message')) + ->addVersion('id', 0.2) + ->addVersion('id', 0.5); + + $versions = $deployment->toArray()['versions']; + + $this->assertCount(1, $versions); + $this->assertSame(0.5, $versions[0]['percentage']); + } + + #[Test] public function shouldUpdateMessage() { $deployment = new Deployment('This is a human-readable message about the deployment'); diff --git a/test/Tests/Configurations/Zones/CachePurgeTest.php b/test/Tests/Configurations/Zones/CachePurgeTest.php index e172501..11f3cd9 100644 --- a/test/Tests/Configurations/Zones/CachePurgeTest.php +++ b/test/Tests/Configurations/Zones/CachePurgeTest.php @@ -60,4 +60,66 @@ public function shouldHaveCountry() ] ], $cachePurge->toArray()); } + + #[Test] + public function shouldHaveLanguage() + { + $cachePurge = (new CachePurge())->byFilesAdvanced('https://example.com/script.js', language: 'en-US'); + + $this->assertEquals([ + 'files' => [ + [ + 'url' => 'https://example.com/script.js', + 'headers' => [ + 'accept-language' => 'en-US' + ] + ] + ] + ], $cachePurge->toArray()); + } + + #[Test] + public function shouldOverrideExistingFileAdvancedEntry() + { + $cachePurge = (new CachePurge()) + ->byFilesAdvanced('https://example.com/script.js', 'mobile') + ->byFilesAdvanced('https://example.com/script.js', 'desktop'); + + $files = $cachePurge->toArray()['files']; + + $this->assertCount(1, $files); + $this->assertSame('desktop', $files[0]['headers']['CF-Device-Type']); + } + + #[Test] + public function shouldHaveTags() + { + $cachePurge = (new CachePurge())->byTags(['my-tag']); + + $this->assertEquals(['tags' => ['my-tag']], $cachePurge->toArray()); + } + + #[Test] + public function shouldHaveHosts() + { + $cachePurge = (new CachePurge())->byHosts(['example.com']); + + $this->assertEquals(['hosts' => ['example.com']], $cachePurge->toArray()); + } + + #[Test] + public function shouldHavePrefixes() + { + $cachePurge = (new CachePurge())->byPrefixes(['images/']); + + $this->assertEquals(['prefixes' => ['images/']], $cachePurge->toArray()); + } + + #[Test] + public function shouldHaveFiles() + { + $cachePurge = (new CachePurge())->byFiles(['https://example.com/script.js']); + + $this->assertEquals(['files' => ['https://example.com/script.js']], $cachePurge->toArray()); + } } diff --git a/test/Tests/Configurations/Zones/PageRuleTest.php b/test/Tests/Configurations/Zones/PageRuleTest.php index b4aea3e..0a7f7b0 100644 --- a/test/Tests/Configurations/Zones/PageRuleTest.php +++ b/test/Tests/Configurations/Zones/PageRuleTest.php @@ -3,9 +3,11 @@ namespace Cloudflare\Tests\Configurations\Zones; use Cloudflare\Configurations\Zones\PageRule; +use Cloudflare\Exceptions\ConfigurationException; use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; -class PageRuleTest extends \PHPUnit\Framework\TestCase +class PageRuleTest extends TestCase { #[Test] public function shouldNotHaveActions() @@ -32,28 +34,199 @@ public function shouldHaveZarazDisabled() $pageRule = (new PageRule('example.com/*'))->disableZaraz(true); $this->assertEquals([ - 'targets' => [ - [ - 'target' => 'url', - 'constraint' => [ - 'operator' => 'matches', - 'value' => 'example.com/*' - ] - ] - ], - 'actions' => [ - [ - 'id' => 'disable_zaraz', - 'value' => 'on' - ] - ] - ], $pageRule->toArray()); + 'id' => 'disable_zaraz', + 'value' => 'on' + ], $pageRule->toArray()['actions'][0]); } + #[Test] public function shouldHaveStatusDisabled() { $pageRule = (new PageRule('example.com/*'))->disable(); $this->assertEquals('disabled', $pageRule->toArray()['status']); } + + #[Test] + public function shouldHaveStatusEnabled() + { + $pageRule = (new PageRule('example.com/*'))->enable(); + + $this->assertEquals('active', $pageRule->toArray()['status']); + } + + #[Test] + public function shouldSetPriority() + { + $pageRule = (new PageRule('example.com/*'))->setPriority(5); + + $this->assertSame(5, $pageRule->toArray()['priority']); + } + + #[Test] + public function shouldSetAllSimpleActions() + { + $pageRule = (new PageRule('example.com/*')) + ->alwaysUseHTTPS(true) + ->automaticHTTPSRewrites(true) + ->browserCacheTTL(3600) + ->browserIntegrityCheck(true) + ->cacheByDeviceType(true) + ->cacheKey('custom-key') + ->disableApps(true) + ->disablePerformance(true) + ->emailObfuscation(true) + ->hostHeaderOverride('example.com') + ->IPGeoLocationHeader(true) + ->mirage(true) + ->opportunisticEncryption(true) + ->originCacheControl(true) + ->disableSecurity(true) + ->originErrorPagePassthru(true) + ->queryStringSort(true) + ->resolveOverride('origin.example.com') + ->respectStrongEtag(true) + ->responseBuffering(true) + ->rocketLoader(true) + ->trueClientIpHeader(true) + ->waf(true); + + $ids = array_column($pageRule->toArray()['actions'], 'id'); + + $this->assertSame([ + 'always_use_https', + 'automatic_https_rewrites', + 'browser_cache_ttl', + 'browser_check', + 'cache_by_device_type', + 'cache_key', + 'disable_apps', + 'disable_performance', + 'disable_security', + 'host_header_override', + 'ip_geolocation', + 'mirage', + 'opportunistic_encryption', + 'explicit_cache_control', + 'origin_error_page_pass_thru', + 'sort_query_string_for_cache', + 'resolve_override', + 'respect_strong_etag', + 'response_buffering', + 'rocket_loader', + 'true_client_ip_header', + 'waf', + ], $ids); + } + + #[Test] + public function shouldOverrideExistingActionValue() + { + $pageRule = (new PageRule('example.com/*')) + ->browserCacheTTL(3600) + ->browserCacheTTL(7200); + + $actions = $pageRule->toArray()['actions']; + + $this->assertCount(1, $actions); + $this->assertSame(7200, $actions[0]['value']); + } + + #[Test] + public function shouldSetBypassCacheOnCookie() + { + $pageRule = (new PageRule('example.com/*'))->bypassCacheOnCookie('session_*'); + + $this->assertSame('bypass_cache_on_cookie', $pageRule->toArray()['actions'][0]['id']); + } + + #[Test] + public function shouldThrowOnInvalidBypassCacheOnCookie() + { + $this->expectException(ConfigurationException::class); + + (new PageRule('example.com/*'))->bypassCacheOnCookie('invalid cookie!'); + } + + #[Test] + public function shouldSetCacheOnCookie() + { + $pageRule = (new PageRule('example.com/*'))->cacheOnCookie('session_*'); + + $this->assertSame('cache_on_cookie', $pageRule->toArray()['actions'][0]['id']); + } + + #[Test] + public function shouldThrowOnInvalidCacheOnCookie() + { + $this->expectException(ConfigurationException::class); + + (new PageRule('example.com/*'))->cacheOnCookie('invalid cookie!'); + } + + #[Test] + public function shouldSetValidCacheLevel() + { + $pageRule = (new PageRule('example.com/*'))->cacheLevel('aggressive'); + + $this->assertSame('cache_level', $pageRule->toArray()['actions'][0]['id']); + } + + #[Test] + public function shouldThrowOnInvalidCacheLevel() + { + $this->expectException(ConfigurationException::class); + + (new PageRule('example.com/*'))->cacheLevel('invalid'); + } + + #[Test] + public function shouldSetEdgeCacheTTL() + { + $pageRule = (new PageRule('example.com/*'))->edgeCacheTTL(3600); + + $this->assertSame('edge_cache_ttl', $pageRule->toArray()['actions'][0]['id']); + } + + #[Test] + public function shouldThrowOnEdgeCacheTTLTooHigh() + { + $this->expectException(ConfigurationException::class); + + (new PageRule('example.com/*'))->edgeCacheTTL(2678401); + } + + #[Test] + public function shouldSetForwardingURLWithDefaultStatusCode() + { + $pageRule = (new PageRule('example.com/*'))->forwardingURL('https://example.com'); + + $action = $pageRule->toArray()['actions'][0]; + $this->assertSame('forwarding_url', $action['id']); + $this->assertSame(301, $action['value']['status_code']); + } + + #[Test] + public function shouldThrowOnInvalidForwardingURLStatusCode() + { + $this->expectException(ConfigurationException::class); + + (new PageRule('example.com/*'))->forwardingURL('https://example.com', 300); + } + + #[Test] + public function shouldSetValidSslMode() + { + $pageRule = (new PageRule('example.com/*'))->ssl('full'); + + $this->assertSame('ssl', $pageRule->toArray()['actions'][0]['id']); + } + + #[Test] + public function shouldThrowOnInvalidSslMode() + { + $this->expectException(ConfigurationException::class); + + (new PageRule('example.com/*'))->ssl('invalid'); + } } diff --git a/test/Tests/D1Test.php b/test/Tests/D1Test.php new file mode 100644 index 0000000..ae47d5f --- /dev/null +++ b/test/Tests/D1Test.php @@ -0,0 +1,216 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['uuid' => 'database_id']]])), + ]); + + $response = $client->d1()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/d1/database', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithoutLocation() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['uuid' => 'database_id']])), + ]); + + $response = $client->d1()->create('account_id', 'my-database'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame(['name' => 'my-database'], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldCreateWithLocation() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['uuid' => 'database_id']])), + ]); + + $response = $client->d1()->create('account_id', 'my-database', 'wnam'); + + $this->assertTrue($response->successful()); + $this->assertSame([ + 'name' => 'my-database', + 'primary_location_hint' => 'wnam', + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['uuid' => 'database_id']])), + ]); + + $response = $client->d1()->details('account_id', 'database_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/d1/database/database_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->d1()->delete('account_id', 'database_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/d1/database/database_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldExportWithoutBookmark() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['success' => true]])), + ]); + + $response = $client->d1()->export('account_id', 'database_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertArrayNotHasKey('current_bookmark', $body); + } + + #[Test] + public function shouldExportWithBookmark() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['success' => true]])), + ]); + + $response = $client->d1()->export('account_id', 'database_id', 'bookmark_1', true, true, ['table1']); + + $this->assertTrue($response->successful()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertSame('bookmark_1', $body['current_bookmark']); + } + + #[Test] + public function shouldImportInit() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['success' => true]])), + ]); + + $response = $client->d1()->import('account_id', 'database_id', 'init', 'etag_value'); + + $this->assertTrue($response->successful()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertSame('etag_value', $body['etag']); + } + + #[Test] + public function shouldImportIngest() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['success' => true]])), + ]); + + $response = $client->d1()->import('account_id', 'database_id', 'ingest', 'etag_value', 'filename.sql'); + + $this->assertTrue($response->successful()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertSame('filename.sql', $body['filename']); + $this->assertSame('etag_value', $body['etag']); + } + + #[Test] + public function shouldImportPoll() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['success' => true]])), + ]); + + $response = $client->d1()->import('account_id', 'database_id', 'poll', null, null, 'bookmark_1'); + + $this->assertTrue($response->successful()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertSame('bookmark_1', $body['current_bookmark']); + } + + #[Test] + public function shouldThrowWhenIngestMissingFilename() + { + $client = $this->mockClient([]); + + $this->expectException(MissingArgumentException::class); + + $client->d1()->import('account_id', 'database_id', 'ingest', 'etag_value'); + } + + #[Test] + public function shouldThrowWhenPollMissingBookmark() + { + $client = $this->mockClient([]); + + $this->expectException(MissingArgumentException::class); + + $client->d1()->import('account_id', 'database_id', 'poll'); + } + + #[Test] + public function shouldThrowWhenInitMissingEtag() + { + $client = $this->mockClient([]); + + $this->expectException(MissingArgumentException::class); + + $client->d1()->import('account_id', 'database_id', 'init'); + } + + #[Test] + public function shouldQuery() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['results' => []]]])), + ]); + + $response = $client->d1()->query('account_id', 'database_id', 'SELECT * FROM table1', ['param1']); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/d1/database/database_id/query', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldRaw() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['results' => []]]])), + ]); + + $response = $client->d1()->raw('account_id', 'database_id', 'SELECT * FROM table1'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/d1/database/database_id/raw', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Accounts/AuditLogsTest.php b/test/Tests/Endpoints/Accounts/AuditLogsTest.php new file mode 100644 index 0000000..54430fa --- /dev/null +++ b/test/Tests/Endpoints/Accounts/AuditLogsTest.php @@ -0,0 +1,27 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'log_id']]])), + ]); + + $response = $client->accounts()->auditLogs()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/audit_logs', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Accounts/MembersTest.php b/test/Tests/Endpoints/Accounts/MembersTest.php new file mode 100644 index 0000000..ac36a6b --- /dev/null +++ b/test/Tests/Endpoints/Accounts/MembersTest.php @@ -0,0 +1,100 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'member_id']]])), + ]); + + $response = $client->accounts()->members()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/members', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldAdd() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'member_id']])), + ]); + + $response = $client->accounts()->members()->add('account_id', [ + 'email' => 'user@example.com', + 'roles' => ['role_id'], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/members', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'member_id']])), + ]); + + $response = $client->accounts()->members()->delete('account_id', 'member_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/members/member_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'member_id']])), + ]); + + $response = $client->accounts()->members()->details('account_id', 'member_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/members/member_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateRoles() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'member_id']])), + ]); + + $response = $client->accounts()->members()->updateRoles('account_id', 'member_id', ['role_id']); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame(['roles' => ['role_id']], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldUpdatePolicies() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'member_id']])), + ]); + + $response = $client->accounts()->members()->updatePolicies('account_id', 'member_id', ['policy_id']); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame(['policies' => ['policy_id']], json_decode((string) $this->lastRequest()->getBody(), true)); + } +} diff --git a/test/Tests/Endpoints/Accounts/RolesTest.php b/test/Tests/Endpoints/Accounts/RolesTest.php new file mode 100644 index 0000000..df42300 --- /dev/null +++ b/test/Tests/Endpoints/Accounts/RolesTest.php @@ -0,0 +1,41 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'role_id']]])), + ]); + + $response = $client->accounts()->roles()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/roles', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'role_id']])), + ]); + + $response = $client->accounts()->roles()->details('account_id', 'role_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/roles/role_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Accounts/RulesetsTest.php b/test/Tests/Endpoints/Accounts/RulesetsTest.php new file mode 100644 index 0000000..db573f9 --- /dev/null +++ b/test/Tests/Endpoints/Accounts/RulesetsTest.php @@ -0,0 +1,91 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'ruleset_id']]])), + ]); + + $response = $client->accounts()->rulesets()->get('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/rulesets', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'ruleset_id']])), + ]); + + $response = $client->accounts()->rulesets()->create('account_id', [ + 'name' => 'my ruleset', + 'kind' => 'root', + 'phase' => 'http_request_firewall_custom', + 'rules' => [['action' => 'block', 'expression' => 'true']], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/rulesets', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithRulesetObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'ruleset_id']])), + ]); + + $ruleset = (new Ruleset('my ruleset'))->addRule((new BlockRule(['error' => 'blocked']))->setExpression('true')); + + $response = $client->accounts()->rulesets()->create('account_id', $ruleset); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'ruleset_id']])), + ]); + + $response = $client->accounts()->rulesets()->details('account_id', 'ruleset_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/rulesets/ruleset_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->accounts()->rulesets()->delete('account_id', 'ruleset_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/rulesets/ruleset_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/AccountsTest.php b/test/Tests/Endpoints/AccountsTest.php new file mode 100644 index 0000000..5020a06 --- /dev/null +++ b/test/Tests/Endpoints/AccountsTest.php @@ -0,0 +1,119 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'account_id']]])), + ]); + + $response = $client->accounts()->list(); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithoutUnit() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'account_id']])), + ]); + + $response = $client->accounts()->create('my account', 'standard'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame([ + 'name' => 'my account', + 'type' => 'standard', + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldCreateWithUnit() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'account_id']])), + ]); + + $response = $client->accounts()->create('my account', 'enterprise', 'unit_id'); + + $this->assertTrue($response->successful()); + $this->assertSame([ + 'name' => 'my account', + 'type' => 'enterprise', + 'unit' => ['id' => 'unit_id'], + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'account_id']])), + ]); + + $response = $client->accounts()->details('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateWithoutSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'account_id']])), + ]); + + $response = $client->accounts()->update('account_id', 'renamed account'); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame(['name' => 'renamed account'], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldUpdateWithSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'account_id']])), + ]); + + $response = $client->accounts()->update('account_id', 'renamed account', ['enforce_twofactor' => true]); + + $this->assertTrue($response->successful()); + $this->assertSame([ + 'name' => 'renamed account', + 'settings' => ['enforce_twofactor' => true], + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'account_id']])), + ]); + + $response = $client->accounts()->delete('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Tunnel/RoutesTest.php b/test/Tests/Endpoints/Tunnel/RoutesTest.php new file mode 100644 index 0000000..6fb96c2 --- /dev/null +++ b/test/Tests/Endpoints/Tunnel/RoutesTest.php @@ -0,0 +1,128 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'route_id']]])), + ]); + + $response = $client->tunnel()->routes()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/routes', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetByIpWithoutVirtualNetwork() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'route_id']]])), + ]); + + $response = $client->tunnel()->routes()->getByIP('account_id', '127.0.0.1'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/routes/ip/127.0.0.1', $this->lastRequest()->getUri()->getPath()); + $this->assertSame('', $this->lastRequest()->getUri()->getQuery()); + } + + #[Test] + public function shouldGetByIpWithVirtualNetwork() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'route_id']]])), + ]); + + $response = $client->tunnel()->routes()->getByIP('account_id', '127.0.0.1', 'vnet_id'); + + $this->assertTrue($response->successful()); + $this->assertStringContainsString('virtual_network_id=vnet_id', $this->lastRequest()->getUri()->getQuery()); + } + + #[Test] + public function shouldCreateWithoutOptionalParams() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->tunnel()->routes()->create('account_id', '10.0.0.0/24'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame(['network' => '10.0.0.0/24'], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldCreateWithOptionalParams() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->tunnel()->routes()->create('account_id', '10.0.0.0/24', 'vnet_id', 'my comment'); + + $this->assertTrue($response->successful()); + $this->assertSame([ + 'network' => '10.0.0.0/24', + 'virtual_network_id' => 'vnet_id', + 'comment' => 'my comment', + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->tunnel()->routes()->details('account_id', 'route_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/routes/route_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->tunnel()->routes()->update('account_id', 'route_id', ['comment' => 'updated']); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/routes/route_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->tunnel()->routes()->delete('account_id', 'route_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/routes/route_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Tunnel/VirtualNetworksTest.php b/test/Tests/Endpoints/Tunnel/VirtualNetworksTest.php new file mode 100644 index 0000000..112d7a5 --- /dev/null +++ b/test/Tests/Endpoints/Tunnel/VirtualNetworksTest.php @@ -0,0 +1,103 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'vnet_id']]])), + ]); + + $response = $client->tunnel()->virtualNetworks()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/virtual_networks', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithoutComment() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'vnet_id']])), + ]); + + $response = $client->tunnel()->virtualNetworks()->create('account_id', 'my-network'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame([ + 'name' => 'my-network', + 'is_default' => false, + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldCreateWithComment() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'vnet_id']])), + ]); + + $response = $client->tunnel()->virtualNetworks()->create('account_id', 'my-network', true, 'my comment'); + + $this->assertTrue($response->successful()); + $this->assertSame([ + 'name' => 'my-network', + 'is_default' => true, + 'comment' => 'my comment', + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'vnet_id']])), + ]); + + $response = $client->tunnel()->virtualNetworks()->details('account_id', 'vnet_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/virtual_networks/vnet_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'vnet_id']])), + ]); + + $response = $client->tunnel()->virtualNetworks()->update('account_id', 'vnet_id', ['comment' => 'updated']); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/virtual_networks/vnet_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->tunnel()->virtualNetworks()->delete('account_id', 'vnet_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/teamnet/virtual_networks/vnet_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Workers/CronTest.php b/test/Tests/Endpoints/Workers/CronTest.php new file mode 100644 index 0000000..ee1ac04 --- /dev/null +++ b/test/Tests/Endpoints/Workers/CronTest.php @@ -0,0 +1,45 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['cron' => '* * * * *']]])), + ]); + + $response = $client->workers()->cron()->get('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/schedules', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['cron' => '* * * * *']]])), + ]); + + $response = $client->workers()->cron()->update('account_id', 'script_name', ['* * * * *', '0 0 * * *']); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/schedules', $this->lastRequest()->getUri()->getPath()); + $this->assertSame([ + ['cron' => '* * * * *'], + ['cron' => '0 0 * * *'], + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } +} diff --git a/test/Tests/Endpoints/Workers/DeploymentsTest.php b/test/Tests/Endpoints/Workers/DeploymentsTest.php new file mode 100644 index 0000000..4a75f9a --- /dev/null +++ b/test/Tests/Endpoints/Workers/DeploymentsTest.php @@ -0,0 +1,62 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'deployment_id']]])), + ]); + + $response = $client->workers()->deployments()->get('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/deployments', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'deployment_id']])), + ]); + + $response = $client->workers()->deployments()->create('account_id', 'script_name', [ + 'strategy' => 'percentage', + 'versions' => [['version_id' => 'version_id', 'percentage' => 100]], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/deployments', $this->lastRequest()->getUri()->getPath()); + $this->assertSame('', $this->lastRequest()->getUri()->getQuery()); + } + + #[Test] + public function shouldCreateWithDeploymentObjectAndForce() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'deployment_id']])), + ]); + + $deployment = (new Deployment('rollout'))->addVersion('version_id', 100); + + $response = $client->workers()->deployments()->create('account_id', 'script_name', $deployment, true); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertStringContainsString('force=', $this->lastRequest()->getUri()->getQuery()); + } +} diff --git a/test/Tests/Endpoints/Workers/DomainsTest.php b/test/Tests/Endpoints/Workers/DomainsTest.php new file mode 100644 index 0000000..69584f9 --- /dev/null +++ b/test/Tests/Endpoints/Workers/DomainsTest.php @@ -0,0 +1,74 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'domain_id']]])), + ]); + + $response = $client->workers()->domains()->get('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/domains', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldAttach() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'domain_id']])), + ]); + + $response = $client->workers()->domains()->attach('account_id', [ + 'environment' => 'production', + 'hostname' => 'example.com', + 'service' => 'my-worker', + 'zone_id' => 'zone_id', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/domains', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDetach() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->domains()->detach('account_id', 'domain_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/domains/domain_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetDomain() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'domain_id']])), + ]); + + $response = $client->workers()->domains()->domain('account_id', 'domain_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/domains/domain_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Workers/DurableObjectsTest.php b/test/Tests/Endpoints/Workers/DurableObjectsTest.php index 5bb76b0..826a6e3 100644 --- a/test/Tests/Endpoints/Workers/DurableObjectsTest.php +++ b/test/Tests/Endpoints/Workers/DurableObjectsTest.php @@ -11,6 +11,27 @@ class DurableObjectsTest extends TestCase { use InteractsWithMockClient; + #[Test] + public function shouldList() + { + $client = $this->mockClient([ + new Response(200, [], json_encode([ + 'success' => true, + 'result' => [ + ['id' => 'namespace_id'], + ], + ])), + ]); + + $response = $client->workers()->durableObjects()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('namespace_id', $response->json('result.0.id')); + + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/durable_objects/namespaces', $this->lastRequest()->getUri()->getPath()); + } + #[Test] public function shouldListObjects() { diff --git a/test/Tests/Endpoints/Workers/EnvironmentTest.php b/test/Tests/Endpoints/Workers/EnvironmentTest.php new file mode 100644 index 0000000..ec21efb --- /dev/null +++ b/test/Tests/Endpoints/Workers/EnvironmentTest.php @@ -0,0 +1,68 @@ +mockClient([ + new Response(200, [], 'script content'), + ]); + + $response = $client->workers()->environment()->get('account_id', 'service_name', 'production'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/services/service_name/environments/production/content', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldThrowOnUpdate() + { + $client = $this->mockClient([]); + + $this->expectException(BadMethodCallException::class); + + $client->workers()->environment()->update('account_id', 'service_name', 'production'); + } + + #[Test] + public function shouldGetSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->workers()->environment()->getSettings('account_id', 'service_name', 'production'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/services/service_name/environments/production/settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->workers()->environment()->updateSettings('account_id', 'service_name', 'production', [ + 'bindings' => [], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/services/service_name/environments/production/settings', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Workers/KVTest.php b/test/Tests/Endpoints/Workers/KVTest.php index ede9b58..5ccf4cd 100644 --- a/test/Tests/Endpoints/Workers/KVTest.php +++ b/test/Tests/Endpoints/Workers/KVTest.php @@ -11,6 +11,163 @@ class KVTest extends TestCase { use InteractsWithMockClient; + #[Test] + public function shouldList() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'namespace_id']]])), + ]); + + $response = $client->workers()->kv()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'namespace_id']])), + ]); + + $response = $client->workers()->kv()->create('account_id', 'my-namespace'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces', $this->lastRequest()->getUri()->getPath()); + $this->assertSame(['title' => 'my-namespace'], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'namespace_id']])), + ]); + + $response = $client->workers()->kv()->details('account_id', 'namespace_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'namespace_id']])), + ]); + + $response = $client->workers()->kv()->update('account_id', 'namespace_id', 'renamed'); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->kv()->delete('account_id', 'namespace_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldListKeys() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['name' => 'key1']]])), + ]); + + $response = $client->workers()->kv()->listKeys('account_id', 'namespace_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/keys', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetKeyMetadata() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['someKey' => 'someValue']])), + ]); + + $response = $client->workers()->kv()->keyMetadata('account_id', 'namespace_id', 'key1'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/metadata/key1', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetKeyDetails() + { + $client = $this->mockClient([ + new Response(200, [], 'value1'), + ]); + + $response = $client->workers()->kv()->keyDetails('account_id', 'namespace_id', 'key1'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/values/key1', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldWriteKeyWithMetadata() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->kv()->writeKeyWithMetadata('account_id', 'namespace_id', 'key1', ['value' => 'value1']); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/values/key1', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDeleteKey() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->kv()->deleteKey('account_id', 'namespace_id', 'key1'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/values/key1', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldWriteMultipleKeys() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->kv()->writeMultipleKeys('account_id', 'namespace_id', [ + ['key' => 'key1', 'value' => 'value1'], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/bulk', $this->lastRequest()->getUri()->getPath()); + } + #[Test] public function shouldDeleteMultipleKeys() { diff --git a/test/Tests/Endpoints/Workers/LogsTest.php b/test/Tests/Endpoints/Workers/LogsTest.php new file mode 100644 index 0000000..262a503 --- /dev/null +++ b/test/Tests/Endpoints/Workers/LogsTest.php @@ -0,0 +1,55 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'tail_id']]])), + ]); + + $response = $client->workers()->logs()->get('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/tails', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldStart() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'tail_id']])), + ]); + + $response = $client->workers()->logs()->start('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/tails', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->logs()->delete('account_id', 'script_name', 'tail_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/tails/tail_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Workers/RoutesTest.php b/test/Tests/Endpoints/Workers/RoutesTest.php new file mode 100644 index 0000000..4994756 --- /dev/null +++ b/test/Tests/Endpoints/Workers/RoutesTest.php @@ -0,0 +1,89 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'route_id']]])), + ]); + + $response = $client->workers()->routes()->get('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/workers/routes', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->workers()->routes()->create('zone_id', [ + 'pattern' => 'example.com/*', + 'script' => 'my-worker', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/workers/routes', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->workers()->routes()->details('zone_id', 'route_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/workers/routes/route_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->workers()->routes()->update('zone_id', 'route_id', [ + 'pattern' => 'example.com/*', + 'script' => 'my-worker', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/workers/routes/route_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'route_id']])), + ]); + + $response = $client->workers()->routes()->delete('zone_id', 'route_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/workers/routes/route_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Workers/ScriptsTest.php b/test/Tests/Endpoints/Workers/ScriptsTest.php new file mode 100644 index 0000000..4c3a588 --- /dev/null +++ b/test/Tests/Endpoints/Workers/ScriptsTest.php @@ -0,0 +1,175 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'script_name']]])), + ]); + + $response = $client->workers()->scripts()->get('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDownload() + { + $client = $this->mockClient([ + new Response(200, [], 'export default { fetch() {} }'), + ]); + + $response = $client->workers()->scripts()->download('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldThrowOnUpload() + { + $client = $this->mockClient([]); + + $this->expectException(BadMethodCallException::class); + + $client->workers()->scripts()->upload('account_id', 'script_name'); + } + + #[Test] + public function shouldThrowOnUpdateContent() + { + $client = $this->mockClient([]); + + $this->expectException(BadMethodCallException::class); + + $client->workers()->scripts()->updateContent('account_id', 'script_name'); + } + + #[Test] + public function shouldGetContent() + { + $client = $this->mockClient([ + new Response(200, [], 'export default { fetch() {} }'), + ]); + + $response = $client->workers()->scripts()->getContent('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/content/v2', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetScriptSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->workers()->scripts()->getScriptSettings('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/script-settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateScriptSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->workers()->scripts()->updateScriptSettings('account_id', 'script_name', ['logpush' => true]); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/script-settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->workers()->scripts()->getSettings('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateSettings() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->workers()->scripts()->updateSettings('account_id', 'script_name', ['bindings' => []]); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetUsageModel() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['usage_model' => 'standard']])), + ]); + + $response = $client->workers()->scripts()->getUsageModel('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/usage-model', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateUsageModel() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['usage_model' => 'bundled']])), + ]); + + $response = $client->workers()->scripts()->updateUsageModel('account_id', 'script_name', 'bundled'); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/usage-model', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->workers()->scripts()->delete('account_id', 'script_name', true); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name', $this->lastRequest()->getUri()->getPath()); + $this->assertStringContainsString('force=', $this->lastRequest()->getUri()->getQuery()); + } +} diff --git a/test/Tests/Endpoints/Workers/SettingsTest.php b/test/Tests/Endpoints/Workers/SettingsTest.php new file mode 100644 index 0000000..024d5e2 --- /dev/null +++ b/test/Tests/Endpoints/Workers/SettingsTest.php @@ -0,0 +1,45 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['default_usage_model' => 'standard']])), + ]); + + $response = $client->workers()->settings()->get('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/account-settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['default_usage_model' => 'standard']])), + ]); + + $response = $client->workers()->settings()->create('account_id', 'standard', true); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/account-settings', $this->lastRequest()->getUri()->getPath()); + $this->assertSame([ + 'default_usage_model' => 'standard', + 'green_compute' => true, + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } +} diff --git a/test/Tests/Endpoints/Workers/SubdomainTest.php b/test/Tests/Endpoints/Workers/SubdomainTest.php new file mode 100644 index 0000000..30038d2 --- /dev/null +++ b/test/Tests/Endpoints/Workers/SubdomainTest.php @@ -0,0 +1,42 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['subdomain' => 'my-subdomain']])), + ]); + + $response = $client->workers()->subdomain()->get('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/subdomain', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['subdomain' => 'my-subdomain']])), + ]); + + $response = $client->workers()->subdomain()->create('account_id', 'my-subdomain'); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/subdomain', $this->lastRequest()->getUri()->getPath()); + $this->assertSame(['subdomain' => 'my-subdomain'], json_decode((string) $this->lastRequest()->getBody(), true)); + } +} diff --git a/test/Tests/Endpoints/Workers/VersionsTest.php b/test/Tests/Endpoints/Workers/VersionsTest.php new file mode 100644 index 0000000..9500663 --- /dev/null +++ b/test/Tests/Endpoints/Workers/VersionsTest.php @@ -0,0 +1,52 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'version_id']]])), + ]); + + $response = $client->workers()->versions()->list('account_id', 'script_name'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/versions', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldThrowOnUpload() + { + $client = $this->mockClient([]); + + $this->expectException(BadMethodCallException::class); + + $client->workers()->versions()->upload('account_id', 'script_name'); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'version_id']])), + ]); + + $response = $client->workers()->versions()->details('account_id', 'script_name', 'version_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/accounts/account_id/workers/scripts/script_name/versions/version_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Zones/CloudConnectorTest.php b/test/Tests/Endpoints/Zones/CloudConnectorTest.php new file mode 100644 index 0000000..21d8182 --- /dev/null +++ b/test/Tests/Endpoints/Zones/CloudConnectorTest.php @@ -0,0 +1,47 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'rule_id']]])), + ]); + + $response = $client->zones()->cloudConnector()->get('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('rule_id', $response->json('result.0.id')); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/cloud_connector/rules', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'rule_id']]])), + ]); + + $response = $client->zones()->cloudConnector()->update('zone_id', [ + 'name' => 'my rule', + 'expression' => 'true', + 'provider' => 'aws_s3', + 'parameters' => ['host' => 'example.com'], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/cloud_connector/rules', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Zones/DNSSECTest.php b/test/Tests/Endpoints/Zones/DNSSECTest.php new file mode 100644 index 0000000..8b4b426 --- /dev/null +++ b/test/Tests/Endpoints/Zones/DNSSECTest.php @@ -0,0 +1,61 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['status' => 'active']])), + ]); + + $response = $client->zones()->dnssec()->details('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('active', $response->json('result.status')); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dnssec', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['status' => 'active']])), + ]); + + $response = $client->zones()->dnssec()->update('zone_id', 'active', true, true); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dnssec', $this->lastRequest()->getUri()->getPath()); + $this->assertSame([ + 'dnssec_multi_signer' => true, + 'dnssec_presigned' => true, + 'status' => 'active', + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->zones()->dnssec()->delete('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dnssec', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Zones/DNSTest.php b/test/Tests/Endpoints/Zones/DNSTest.php new file mode 100644 index 0000000..57cfe19 --- /dev/null +++ b/test/Tests/Endpoints/Zones/DNSTest.php @@ -0,0 +1,163 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->zones()->dns()->scan('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/scan', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldList() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'record_id']]])), + ]); + + $response = $client->zones()->dns()->list('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('record_id', $response->json('result.0.id')); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'record_id']])), + ]); + + $response = $client->zones()->dns()->create('zone_id', [ + 'type' => 'A', + 'name' => 'example.com', + 'content' => '127.0.0.1', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldThrowWhenCreateMissingRequiredParams() + { + $client = $this->mockClient([]); + + $this->expectException(MissingArgumentException::class); + + $client->zones()->dns()->create('zone_id', ['name' => 'example.com']); + } + + #[Test] + public function shouldExport() + { + $client = $this->mockClient([ + new Response(200, [], 'example.com. 300 IN A 127.0.0.1'), + ]); + + $response = $client->zones()->dns()->export('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/export', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldImport() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['recs_added' => 1]])), + ]); + + $response = $client->zones()->dns()->import('zone_id', 'example.com. 300 IN A 127.0.0.1'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/import', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'record_id']])), + ]); + + $response = $client->zones()->dns()->details('zone_id', 'record_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/record_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'record_id']])), + ]); + + $response = $client->zones()->dns()->update('zone_id', 'record_id', [ + 'type' => 'A', + 'name' => 'example.com', + 'content' => '127.0.0.1', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/record_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldOverwrite() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'record_id']])), + ]); + + $response = $client->zones()->dns()->overwrite('zone_id', 'record_id', [ + 'type' => 'A', + 'name' => 'example.com', + 'content' => '127.0.0.1', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/record_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'record_id']])), + ]); + + $response = $client->zones()->dns()->delete('zone_id', 'record_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/dns_records/record_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Zones/HoldTest.php b/test/Tests/Endpoints/Zones/HoldTest.php new file mode 100644 index 0000000..9e7d3f4 --- /dev/null +++ b/test/Tests/Endpoints/Zones/HoldTest.php @@ -0,0 +1,71 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['hold' => true]])), + ]); + + $response = $client->zones()->holds()->details('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/hold', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['hold' => true]])), + ]); + + $response = $client->zones()->holds()->create('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/hold', $this->lastRequest()->getUri()->getPath()); + $this->assertSame(['include_subdomains' => true], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldDeleteWithoutHoldAfter() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['hold' => false]])), + ]); + + $response = $client->zones()->holds()->delete('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/hold', $this->lastRequest()->getUri()->getPath()); + $this->assertSame('', $this->lastRequest()->getUri()->getQuery()); + } + + #[Test] + public function shouldDeleteWithHoldAfter() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['hold' => true]])), + ]); + + $response = $client->zones()->holds()->delete('zone_id', '2030-01-01T00:00:00Z'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertStringContainsString('hold_after=', $this->lastRequest()->getUri()->getQuery()); + } +} diff --git a/test/Tests/Endpoints/Zones/LockdownTest.php b/test/Tests/Endpoints/Zones/LockdownTest.php new file mode 100644 index 0000000..cfeee96 --- /dev/null +++ b/test/Tests/Endpoints/Zones/LockdownTest.php @@ -0,0 +1,98 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'lockdown_id']]])), + ]); + + $response = $client->zones()->lockdowns()->list('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/firewall/lockdowns', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithSingleIp() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'lockdown_id']])), + ]); + + $response = $client->zones()->lockdowns()->create('zone_id', '127.0.0.1', ['example.com/*']); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertSame('ip', $body['configurations']['target']); + } + + #[Test] + public function shouldCreateWithIpRange() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'lockdown_id']])), + ]); + + $response = $client->zones()->lockdowns()->create('zone_id', '127.0.0.1/16', ['example.com/*']); + + $this->assertTrue($response->successful()); + $body = json_decode((string) $this->lastRequest()->getBody(), true); + $this->assertSame('ip_range', $body['configurations']['target']); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'lockdown_id']])), + ]); + + $response = $client->zones()->lockdowns()->details('zone_id', 'lockdown_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/firewall/lockdowns/lockdown_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'lockdown_id']])), + ]); + + $response = $client->zones()->lockdowns()->update('zone_id', 'lockdown_id', '127.0.0.1', ['example.com/*']); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/firewall/lockdowns/lockdown_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'lockdown_id']])), + ]); + + $response = $client->zones()->lockdowns()->delete('zone_id', 'lockdown_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/firewall/lockdowns/lockdown_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Zones/PageRulesTest.php b/test/Tests/Endpoints/Zones/PageRulesTest.php new file mode 100644 index 0000000..48c734c --- /dev/null +++ b/test/Tests/Endpoints/Zones/PageRulesTest.php @@ -0,0 +1,166 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => []])), + ]); + + $response = $client->zones()->pageRules()->settings('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules/settings', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldList() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'page_rule_id']]])), + ]); + + $response = $client->zones()->pageRules()->list('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $response = $client->zones()->pageRules()->create('zone_id', [ + 'targets' => [['target' => 'url', 'constraint' => ['operator' => 'matches', 'value' => 'example.com/*']]], + 'actions' => [['id' => 'ssl', 'value' => 'flexible']], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithPageRuleObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $pageRule = (new PageRule('example.com/*'))->enable()->ssl('flexible'); + + $response = $client->zones()->pageRules()->create('zone_id', $pageRule); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $response = $client->zones()->pageRules()->details('zone_id', 'page_rule_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules/page_rule_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $response = $client->zones()->pageRules()->update('zone_id', 'page_rule_id', [ + 'targets' => [['target' => 'url', 'constraint' => ['operator' => 'matches', 'value' => 'example.com/*']]], + 'actions' => [['id' => 'ssl', 'value' => 'flexible']], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules/page_rule_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateWithPageRuleObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $pageRule = (new PageRule('example.com/*'))->disable(); + + $response = $client->zones()->pageRules()->update('zone_id', 'page_rule_id', $pageRule); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + } + + #[Test] + public function shouldOverwriteWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $response = $client->zones()->pageRules()->overwrite('zone_id', 'page_rule_id', [ + 'targets' => [['target' => 'url', 'constraint' => ['operator' => 'matches', 'value' => 'example.com/*']]], + 'actions' => [['id' => 'ssl', 'value' => 'flexible']], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules/page_rule_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldOverwriteWithPageRuleObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $pageRule = new PageRule('example.com/*'); + + $response = $client->zones()->pageRules()->overwrite('zone_id', 'page_rule_id', $pageRule); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'page_rule_id']])), + ]); + + $response = $client->zones()->pageRules()->delete('zone_id', 'page_rule_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/pagerules/page_rule_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/Zones/RulesTest.php b/test/Tests/Endpoints/Zones/RulesTest.php new file mode 100644 index 0000000..11f144f --- /dev/null +++ b/test/Tests/Endpoints/Zones/RulesTest.php @@ -0,0 +1,46 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'rule_id']])), + ]); + + $response = $client->zones()->rules()->create('zone_id', 'ruleset_id', [ + 'action' => 'block', + 'expression' => 'true', + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/rulesets/ruleset_id/rules', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithRuleObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'rule_id']])), + ]); + + $rule = (new BlockRule(['error' => 'blocked']))->enable()->setExpression('true'); + + $response = $client->zones()->rules()->create('zone_id', 'ruleset_id', $rule); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + } +} diff --git a/test/Tests/Endpoints/Zones/RulesetsTest.php b/test/Tests/Endpoints/Zones/RulesetsTest.php new file mode 100644 index 0000000..2dc31a1 --- /dev/null +++ b/test/Tests/Endpoints/Zones/RulesetsTest.php @@ -0,0 +1,91 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'ruleset_id']]])), + ]); + + $response = $client->zones()->rulesets()->get('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/rulesets', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'ruleset_id']])), + ]); + + $response = $client->zones()->rulesets()->create('zone_id', [ + 'name' => 'my ruleset', + 'kind' => 'zone', + 'phase' => 'http_request_firewall_custom', + 'rules' => [['action' => 'block', 'expression' => 'true']], + ]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/rulesets', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldCreateWithRulesetObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'ruleset_id']])), + ]); + + $ruleset = (new Ruleset('my ruleset'))->addRule((new BlockRule(['error' => 'blocked']))->setExpression('true')); + + $response = $client->zones()->rulesets()->create('zone_id', $ruleset); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'ruleset_id']])), + ]); + + $response = $client->zones()->rulesets()->details('zone_id', 'ruleset_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/rulesets/ruleset_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => null])), + ]); + + $response = $client->zones()->rulesets()->delete('zone_id', 'ruleset_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/rulesets/ruleset_id', $this->lastRequest()->getUri()->getPath()); + } +} diff --git a/test/Tests/Endpoints/ZonesTest.php b/test/Tests/Endpoints/ZonesTest.php new file mode 100644 index 0000000..609e0c4 --- /dev/null +++ b/test/Tests/Endpoints/ZonesTest.php @@ -0,0 +1,170 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => [['id' => 'zone_id']]])), + ]); + + $response = $client->zones()->list('account_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones', $this->lastRequest()->getUri()->getPath()); + $this->assertStringContainsString('account%5Bid%5D=account_id', $this->lastRequest()->getUri()->getQuery()); + } + + #[Test] + public function shouldCreate() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->create('account_id', 'example.com'); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones', $this->lastRequest()->getUri()->getPath()); + $this->assertSame([ + 'name' => 'example.com', + 'account' => ['id' => 'account_id'], + 'type' => 'full', + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldGetDetails() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->details('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldDelete() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->delete('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('DELETE', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldUpdateWithoutVanityNameServers() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->update('zone_id', 'full'); + + $this->assertTrue($response->successful()); + $this->assertSame('PATCH', $this->lastRequest()->getMethod()); + $this->assertSame(['type' => 'full'], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldUpdateWithVanityNameServers() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->update('zone_id', 'full', ['ns1.example.com']); + + $this->assertTrue($response->successful()); + $this->assertSame([ + 'type' => 'full', + 'vanity_name_servers' => ['ns1.example.com'], + ], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldActivationCheck() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->activationCheck('zone_id'); + + $this->assertTrue($response->successful()); + $this->assertSame('PUT', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/activation_check', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldPurgeWithArray() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $response = $client->zones()->purge('zone_id', ['tags' => ['my-tag']]); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/zones/zone_id/purge_cache', $this->lastRequest()->getUri()->getPath()); + } + + #[Test] + public function shouldPurgeWithCachePurgeObject() + { + $client = $this->mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['id' => 'zone_id']])), + ]); + + $config = (new CachePurge())->everything(); + + $response = $client->zones()->purge('zone_id', $config); + + $this->assertTrue($response->successful()); + $this->assertSame('POST', $this->lastRequest()->getMethod()); + $this->assertSame(['purge_everything' => true], json_decode((string) $this->lastRequest()->getBody(), true)); + } + + #[Test] + public function shouldThrowWhenPurgeMissingAnyRequiredParams() + { + $client = $this->mockClient([]); + + $this->expectException(MissingArgumentException::class); + + $client->zones()->purge('zone_id', []); + } + + #[Test] + public function shouldGetCache() + { + $client = $this->mockClient([]); + + $this->assertInstanceOf(Cache::class, $client->zones()->cache()); + } +} diff --git a/test/Tests/Exceptions/MissingArgumentExceptionTest.php b/test/Tests/Exceptions/MissingArgumentExceptionTest.php new file mode 100644 index 0000000..9f166a9 --- /dev/null +++ b/test/Tests/Exceptions/MissingArgumentExceptionTest.php @@ -0,0 +1,32 @@ +assertSame( + 'One or more of required ("name", "type") parameters is missing!', + $exception->getMessage() + ); + } + + #[Test] + public function shouldBuildMessageFromString() + { + $exception = new MissingArgumentException('name'); + + $this->assertSame( + 'One or more of required ("name") parameters is missing!', + $exception->getMessage() + ); + } +} diff --git a/test/Tests/ExpressionBuilderTest.php b/test/Tests/ExpressionBuilderTest.php new file mode 100644 index 0000000..ce19683 --- /dev/null +++ b/test/Tests/ExpressionBuilderTest.php @@ -0,0 +1,159 @@ +field('ip.src')->eq('127.0.0.1'); + + $this->assertSame('ip.src eq 127.0.0.1', $builder->build()); + $this->assertSame('ip.src eq 127.0.0.1', (string) $builder); + } + + #[Test] + public function shouldQuoteNonFieldNonIpStringValues() + { + $builder = (new ExpressionBuilder())->field('http.host')->eq('example.com'); + + $this->assertSame('http.host eq "example.com"', $builder->build()); + } + + #[Test] + public function shouldNotQuoteFieldNameValues() + { + $builder = (new ExpressionBuilder())->field('ip.src')->eq('ip.dst'); + + $this->assertSame('ip.src eq ip.dst', $builder->build()); + } + + #[Test] + public function shouldFormatArrayValues() + { + $builder = (new ExpressionBuilder())->field('ip.src')->in(['127.0.0.1', '127.0.0.2']); + + $this->assertSame('ip.src in {127.0.0.1 127.0.0.2}', $builder->build()); + } + + #[Test] + public function shouldFormatNonStringNonArrayValues() + { + $builder = (new ExpressionBuilder())->field('http.request.body.size')->gt(1024); + + $this->assertSame('http.request.body.size gt 1024', $builder->build()); + } + + #[Test] + public function shouldAddExpressionWithoutOperatorOrValue() + { + $builder = (new ExpressionBuilder())->addExpression('true'); + + $this->assertSame('true', $builder->build()); + } + + #[Test] + public function shouldAddLogicalOperators() + { + $builder = (new ExpressionBuilder()) + ->field('ip.src')->eq('127.0.0.1') + ->and() + ->field('ip.dst')->eq('127.0.0.2'); + + $this->assertSame('ip.src eq 127.0.0.1 and ip.dst eq 127.0.0.2', $builder->build()); + } + + #[Test] + public function shouldNegateWithNot() + { + $builder = (new ExpressionBuilder())->not()->field('ssl'); + + $this->assertSame('not ssl', $builder->build()); + } + + #[Test] + public function shouldGroupExpressions() + { + $builder = (new ExpressionBuilder())->group(function (ExpressionBuilder $b) { + return $b->field('ip.src')->eq('127.0.0.1')->or()->field('ip.src')->eq('127.0.0.2'); + }); + + $this->assertSame('ip.src eq 127.0.0.1 or ip.src eq 127.0.0.2', $builder->build()); + } + + #[Test] + public function shouldGroupExpressionsAlongsideOthers() + { + $builder = (new ExpressionBuilder()) + ->field('ssl') + ->and() + ->group(function (ExpressionBuilder $b) { + return $b->field('ip.src')->eq('127.0.0.1'); + }); + + $this->assertSame('ssl and (ip.src eq 127.0.0.1)', $builder->build()); + } + + #[Test] + public function shouldAddFunctionWithoutOperatorOrValue() + { + $builder = (new ExpressionBuilder())->addFunction('len', 'ip.src'); + + $this->assertSame('len(ip.src)', $builder->build()); + } + + #[Test] + public function shouldAddFunctionWithOperatorAndValue() + { + $builder = (new ExpressionBuilder())->addFunction('len', 'ip.src', 'eq', 10); + + $this->assertSame('len(ip.src) eq 10', $builder->build()); + } + + #[Test] + public function shouldThrowOnInvalidFunctionField() + { + $this->expectException(InvalidArgumentException::class); + + (new ExpressionBuilder())->addFunction('len', 'not.a.real.field'); + } + + #[Test] + public function shouldThrowOnInvalidFieldName() + { + $this->expectException(InvalidArgumentException::class); + + (new ExpressionBuilder())->field('not.a.real.field'); + } + + #[Test] + public function shouldAddStrictWildcard() + { + $builder = (new ExpressionBuilder())->wildcard('*.example.com', true); + + $this->assertSame('strict wildcard "*.example.com"', $builder->build()); + } + + #[Test] + public function shouldAddNonStrictWildcard() + { + $builder = (new ExpressionBuilder())->wildcard('*.example.com', false); + + $this->assertSame('wildcard "*.example.com"', $builder->build()); + } + + #[Test] + public function shouldThrowOnUndefinedMethod() + { + $this->expectException(BadMethodCallException::class); + + (new ExpressionBuilder())->notARealMethod(); + } +} diff --git a/test/Tests/HttpClient/Exceptions/RequestExceptionTest.php b/test/Tests/HttpClient/Exceptions/RequestExceptionTest.php new file mode 100644 index 0000000..3cc70c1 --- /dev/null +++ b/test/Tests/HttpClient/Exceptions/RequestExceptionTest.php @@ -0,0 +1,35 @@ + 'something went wrong']))); + + $exception = new RequestException($response); + + $this->assertSame(499, $exception->getCode()); + $this->assertStringContainsString('HTTP request returned status code 499', $exception->getMessage()); + $this->assertStringContainsString('something went wrong', $exception->getMessage()); + $this->assertSame($response, $exception->response); + } + + #[Test] + public function shouldOmitBodySummaryWhenBodyIsEmpty() + { + $response = new Response(new PsrResponse(499, [], '')); + + $exception = new RequestException($response); + + $this->assertSame('HTTP request returned status code 499', $exception->getMessage()); + } +} diff --git a/test/Tests/HttpClient/HttpClientTest.php b/test/Tests/HttpClient/HttpClientTest.php new file mode 100644 index 0000000..26935f7 --- /dev/null +++ b/test/Tests/HttpClient/HttpClientTest.php @@ -0,0 +1,98 @@ +mockClient([]); + + $this->assertInstanceOf(GuzzleClient::class, $client->getHttpClient()->getGuzzleClient()); + } + + #[Test] + public function shouldIssueHeadRequest() + { + $client = $this->mockClient([ + new Response(200, [], ''), + ]); + + $response = $client->getHttpClient()->head('/zones'); + + $this->assertTrue($response->successful()); + $this->assertSame('HEAD', $this->lastRequest()->getMethod()); + } + + #[Test] + public function shouldIssueHeadRequestWithQuery() + { + $client = $this->mockClient([ + new Response(200, [], ''), + ]); + + $client->getHttpClient()->head('/zones', ['name' => 'example.com']); + + $this->assertStringContainsString('name=example.com', $this->lastRequest()->getUri()->getQuery()); + } + + #[TestWith([400, BadRequestException::class])] + #[TestWith([401, AuthenticationException::class])] + #[TestWith([403, PermissionDeniedException::class])] + #[TestWith([404, NotFoundException::class])] + #[TestWith([422, UnprocessableEntityException::class])] + #[TestWith([429, RateLimitException::class])] + #[TestWith([500, InternalServerException::class])] + #[TestWith([503, InternalServerException::class])] + #[TestWith([418, RequestException::class])] + #[Test] + public function shouldThrowMappedExceptionForStatus(int $status, string $expectedException) + { + $client = $this->mockClient([ + new Response($status, [], json_encode(['success' => false, 'errors' => [['message' => 'failed']]])), + ]); + + $this->expectException($expectedException); + + $client->zones()->details('zone_id'); + } + + #[Test] + public function shouldWrapConnectExceptionIntoConnectionException() + { + $request = new Request('GET', 'https://api.cloudflare.com/client/v4/zones/zone_id'); + $mock = new \GuzzleHttp\Handler\MockHandler([ + new ConnectException('Could not resolve host', $request), + ]); + + $client = new \Cloudflare\Client('token', [ + \GuzzleHttp\Middleware::history($this->requestHistory), + fn (callable $handler) => fn ($req, array $options) => $mock($req, $options), + ]); + + $this->expectException(ConnectionException::class); + + $client->zones()->details('zone_id'); + } +} diff --git a/test/Tests/HttpClient/ResponseTest.php b/test/Tests/HttpClient/ResponseTest.php new file mode 100644 index 0000000..bcfacae --- /dev/null +++ b/test/Tests/HttpClient/ResponseTest.php @@ -0,0 +1,88 @@ +assertSame('raw body', $response->body()); + } + + #[Test] + public function shouldReturnFullDecodedJsonWithoutKey() + { + $response = new Response(new PsrResponse(200, [], json_encode(['success' => true, 'result' => ['id' => 'x']]))); + + $this->assertSame([ + 'success' => true, + 'result' => ['id' => 'x'], + ], $response->json()); + } + + #[Test] + public function shouldReturnDefaultForMissingKey() + { + $response = new Response(new PsrResponse(200, [], json_encode(['result' => ['id' => 'x']]))); + + $this->assertSame('fallback', $response->json('result.missing', 'fallback')); + } + + #[Test] + public function shouldReturnUnderlyingPsrResponse() + { + $psrResponse = new PsrResponse(200, [], 'body'); + + $response = new Response($psrResponse); + + $this->assertSame($psrResponse, $response->toPsrResponse()); + } + + #[Test] + public function shouldReturnStatus() + { + $response = new Response(new PsrResponse(201, [], '')); + + $this->assertSame(201, $response->status()); + } + + #[Test] + public function shouldBeSuccessfulOnlyForStatus200() + { + $this->assertTrue((new Response(new PsrResponse(200, [], '')))->successful()); + $this->assertFalse((new Response(new PsrResponse(201, [], '')))->successful()); + } + + #[Test] + public function shouldBeFailedForNon200Status() + { + $this->assertTrue((new Response(new PsrResponse(404, [], '')))->failed()); + $this->assertFalse((new Response(new PsrResponse(200, [], '')))->failed()); + } + + #[Test] + public function shouldTraverseObjectTargets() + { + $response = new Response(new PsrResponse(200, [], '')); + + $target = (object) ['result' => (object) ['id' => 'x']]; + + $this->assertSame('x', $response->get($target, 'result.id')); + } + + #[Test] + public function shouldCastToString() + { + $response = new Response(new PsrResponse(200, [], 'raw body')); + + $this->assertSame('raw body', (string) $response); + } +} diff --git a/test/Tests/IPTest.php b/test/Tests/IPTest.php new file mode 100644 index 0000000..92599a8 --- /dev/null +++ b/test/Tests/IPTest.php @@ -0,0 +1,27 @@ +mockClient([ + new Response(200, [], json_encode(['success' => true, 'result' => ['ipv4_cidrs' => []]])), + ]); + + $response = $client->ips()->get(); + + $this->assertTrue($response->successful()); + $this->assertSame('GET', $this->lastRequest()->getMethod()); + $this->assertSame('/client/v4/ips', $this->lastRequest()->getUri()->getPath()); + } +}