diff --git a/.gitattributes b/.gitattributes
index 913b096..3b10ee5 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8,6 +8,6 @@ test-integration export-ignore
CHANGELOG.md export-ignore
docker-compose.yml export-ignore
indocker export-ignore
-phpcs.xml export-ignore
+mago.toml export-ignore
phpunit.xml.dist export-ignore
phpunit-integration.xml export-ignore
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a0bc93b..086876c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,12 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
-## [Unreleased]
+## [3.2.0] - 2026-05-22
### Added
* *Nothing*
### Changed
* Update to PHPUnit 13
+* Migrate form PHP_CodeSniffer to Mago for code linting and formatting.
### Deprecated
* *Nothing*
diff --git a/composer.json b/composer.json
index 5ec14eb..94cfa0e 100644
--- a/composer.json
+++ b/composer.json
@@ -16,13 +16,14 @@
"psr/http-factory": "^1.1"
},
"require-dev": {
+ "carthage-software/mago": "^1.28",
"devster/ubench": "^2.1",
"guzzlehttp/guzzle": "^7.10",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpcov": "^12.0",
"phpunit/phpunit": "^13.0",
- "shlinkio/php-coding-standard": "~2.5.0",
+ "shlinkio/shlink-mago-config": "^1.0",
"symfony/var-dumper": "^8.0"
},
"autoload": {
@@ -42,8 +43,12 @@
"@stan",
"@test:unit"
],
- "cs": "phpcs",
- "cs:fix": "phpcbf",
+ "lint": "mago lint",
+ "lint:fix": "mago lint --fix",
+ "format": "mago format",
+ "format:check": "mago format --check",
+ "cs": ["@lint", "@format:check"],
+ "cs:fix": ["@lint:fix", "@format"],
"stan": "phpstan analyse",
"test:unit": "phpunit --order-by=random --testdox --testdox-summary",
"test:unit:ci": [
diff --git a/mago.toml b/mago.toml
new file mode 100644
index 0000000..84a7f29
--- /dev/null
+++ b/mago.toml
@@ -0,0 +1,20 @@
+#:schema https://mago.carthage.software/1.27.1/schema.json
+# Welcome to Mago!
+# For full documentation, see https://mago.carthage.software/tools/overview
+version = "1"
+php-version = "8.4.0"
+extends = "vendor/shlinkio/shlink-mago-config/mago.toml"
+
+[source]
+workspace = "."
+paths = ["src", "test", "test-integration"]
+excludes = ["vendor"]
+
+[source.glob]
+literal-separator = true
+
+[linter.rules]
+no-literal-password = { exclude = ["test"] }
+no-empty-catch-clause = { exclude = ["test"] }
+no-empty-loop = { exclude = ["test"] }
+loop-does-not-iterate = { exclude = ["test"] }
diff --git a/phpcs.xml b/phpcs.xml
deleted file mode 100644
index 6518077..0000000
--- a/phpcs.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Coding standard
-
-
-
-
-
-
-
-
-
- src
- test
- test-integration
-
diff --git a/src/Builder/ShlinkClientBuilder.php b/src/Builder/ShlinkClientBuilder.php
index ecdcad0..2d4f906 100644
--- a/src/Builder/ShlinkClientBuilder.php
+++ b/src/Builder/ShlinkClientBuilder.php
@@ -29,8 +29,7 @@ public function __construct(
private RequestFactoryInterface $requestFactory,
private StreamFactoryInterface $streamFactory,
private HttpDebuggerInterface|null $debugger = null,
- ) {
- }
+ ) {}
public function buildShortUrlsClient(ShlinkConfigInterface $config): ShortUrlsClientInterface
{
diff --git a/src/Builder/SingletonShlinkClientBuilder.php b/src/Builder/SingletonShlinkClientBuilder.php
index b176be1..94b12c8 100644
--- a/src/Builder/SingletonShlinkClientBuilder.php
+++ b/src/Builder/SingletonShlinkClientBuilder.php
@@ -17,49 +17,52 @@ class SingletonShlinkClientBuilder implements ShlinkClientBuilderInterface
{
private array $instances = [];
- public function __construct(private readonly ShlinkClientBuilderInterface $wrapped)
- {
- }
+ public function __construct(private readonly ShlinkClientBuilderInterface $wrapped) {}
public function buildShortUrlsClient(ShlinkConfigInterface $config): ShortUrlsClientInterface
{
$key = $this->configToKey($config);
- return $this->instances[ShortUrlsClientInterface::class][$key] ?? (
- $this->instances[ShortUrlsClientInterface::class][$key] = $this->wrapped->buildShortUrlsClient($config)
+ return (
+ $this->instances[ShortUrlsClientInterface::class][$key] ?? ($this->instances[ShortUrlsClientInterface::class][$key] =
+ $this->wrapped->buildShortUrlsClient($config))
);
}
public function buildVisitsClient(ShlinkConfigInterface $config): VisitsClientInterface
{
$key = $this->configToKey($config);
- return $this->instances[VisitsClientInterface::class][$key] ?? (
- $this->instances[VisitsClientInterface::class][$key] = $this->wrapped->buildVisitsClient($config)
+ return (
+ $this->instances[VisitsClientInterface::class][$key] ?? ($this->instances[VisitsClientInterface::class][$key] =
+ $this->wrapped->buildVisitsClient($config))
);
}
public function buildTagsClient(ShlinkConfigInterface $config): TagsClientInterface
{
$key = $this->configToKey($config);
- return $this->instances[TagsClientInterface::class][$key] ?? (
- $this->instances[TagsClientInterface::class][$key] = $this->wrapped->buildTagsClient($config)
+ return (
+ $this->instances[TagsClientInterface::class][$key] ?? ($this->instances[TagsClientInterface::class][$key] =
+ $this->wrapped->buildTagsClient($config))
);
}
public function buildDomainsClient(ShlinkConfigInterface $config): DomainsClientInterface
{
$key = $this->configToKey($config);
- return $this->instances[DomainsClientInterface::class][$key] ?? (
- $this->instances[DomainsClientInterface::class][$key] = $this->wrapped->buildDomainsClient($config)
+ return (
+ $this->instances[DomainsClientInterface::class][$key] ?? ($this->instances[DomainsClientInterface::class][$key] =
+ $this->wrapped->buildDomainsClient($config))
);
}
public function buildRedirectRulesClient(ShlinkConfigInterface $config): RedirectRulesClientInterface
{
$key = $this->configToKey($config);
- return $this->instances[RedirectRulesClientInterface::class][$key] ?? (
- $this->instances[RedirectRulesClientInterface::class][$key] = $this->wrapped->buildRedirectRulesClient(
- $config,
- )
+ return (
+ $this->instances[RedirectRulesClientInterface::class][$key] ?? ($this->instances[RedirectRulesClientInterface::class][$key] =
+ $this->wrapped->buildRedirectRulesClient(
+ $config,
+ ))
);
}
diff --git a/src/Config/ArrayShlinkConfig.php b/src/Config/ArrayShlinkConfig.php
index b6274dc..c43ef8e 100644
--- a/src/Config/ArrayShlinkConfig.php
+++ b/src/Config/ArrayShlinkConfig.php
@@ -15,19 +15,15 @@
public const API_KEY_PROP = 'apiKey';
public const VERSION_PROP = 'version';
- private function __construct(private ShlinkConfigInterface $wrapped)
- {
- }
+ private function __construct(private ShlinkConfigInterface $wrapped) {}
/**
* @throws InvalidConfigException
*/
public static function fromArray(array $config): self
{
- return new self(ShlinkConfig::fromRawConfig(new class ($config) implements RawConfigInterface {
- public function __construct(private readonly array $config)
- {
- }
+ return new self(ShlinkConfig::fromRawConfig(new class($config) implements RawConfigInterface {
+ public function __construct(private readonly array $config) {}
public function baseUrl(): string
{
diff --git a/src/Config/EnvShlinkConfig.php b/src/Config/EnvShlinkConfig.php
index 7f29ba0..6bcf853 100644
--- a/src/Config/EnvShlinkConfig.php
+++ b/src/Config/EnvShlinkConfig.php
@@ -16,9 +16,7 @@
public const API_KEY_ENV_VAR = 'SHLINK_API_KEY';
public const VERSION_ENV_VAR = 'SHLINK_API_VERSION';
- private function __construct(private ShlinkConfigInterface $wrapped)
- {
- }
+ private function __construct(private ShlinkConfigInterface $wrapped) {}
/**
* @throws InvalidConfigException
@@ -26,10 +24,8 @@ private function __construct(private ShlinkConfigInterface $wrapped)
public static function fromEnv(): self
{
$env = getenv();
- return new self(ShlinkConfig::fromRawConfig(new class ($env) implements RawConfigInterface {
- public function __construct(private readonly array $env)
- {
- }
+ return new self(ShlinkConfig::fromRawConfig(new class($env) implements RawConfigInterface {
+ public function __construct(private readonly array $env) {}
public function baseUrl(): string
{
diff --git a/src/Config/ShlinkConfig.php b/src/Config/ShlinkConfig.php
index 517eb44..3abf3a6 100644
--- a/src/Config/ShlinkConfig.php
+++ b/src/Config/ShlinkConfig.php
@@ -9,9 +9,7 @@
final readonly class ShlinkConfig implements ShlinkConfigInterface
{
- private function __construct(private string $baseUrl, private string $apiKey, private ApiVersion $version)
- {
- }
+ private function __construct(private string $baseUrl, private string $apiKey, private ApiVersion $version) {}
public static function fromBaseUrlAndApiKey(string $baseUrl, string $apiKey): ShlinkConfigInterface
{
diff --git a/src/Domains/DomainsClient.php b/src/Domains/DomainsClient.php
index 29be90d..548d6b8 100644
--- a/src/Domains/DomainsClient.php
+++ b/src/Domains/DomainsClient.php
@@ -14,9 +14,7 @@
readonly class DomainsClient implements DomainsClientInterface
{
- public function __construct(private HttpClientInterface $httpClient)
- {
- }
+ public function __construct(private HttpClientInterface $httpClient) {}
/**
* @inheritDoc
diff --git a/src/Domains/Model/Domain.php b/src/Domains/Model/Domain.php
index ca08152..bb24d9b 100644
--- a/src/Domains/Model/Domain.php
+++ b/src/Domains/Model/Domain.php
@@ -6,9 +6,7 @@
final readonly class Domain
{
- private function __construct(public string $domain, public bool $isDefault, public DomainRedirects $redirects)
- {
- }
+ private function __construct(public string $domain, public bool $isDefault, public DomainRedirects $redirects) {}
public static function fromArray(array $payload): self
{
diff --git a/src/Domains/Model/DomainRedirects.php b/src/Domains/Model/DomainRedirects.php
index 9a3ac0f..319d9f0 100644
--- a/src/Domains/Model/DomainRedirects.php
+++ b/src/Domains/Model/DomainRedirects.php
@@ -10,8 +10,7 @@ private function __construct(
public string|null $baseUrlRedirect,
public string|null $regularNotFoundRedirect,
public string|null $invalidShortUrlRedirect,
- ) {
- }
+ ) {}
public static function fromArray(array $payload): self
{
diff --git a/src/Domains/Model/DomainRedirectsConfig.php b/src/Domains/Model/DomainRedirectsConfig.php
index 127f53c..28da2fc 100644
--- a/src/Domains/Model/DomainRedirectsConfig.php
+++ b/src/Domains/Model/DomainRedirectsConfig.php
@@ -8,9 +8,7 @@
final class DomainRedirectsConfig implements JsonSerializable
{
- private function __construct(private array $payload = [])
- {
- }
+ private function __construct(private array $payload = []) {}
public static function forDomain(string $domain): self
{
diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php
index 302e759..fa351c4 100644
--- a/src/Exception/ExceptionInterface.php
+++ b/src/Exception/ExceptionInterface.php
@@ -6,6 +6,4 @@
use Throwable;
-interface ExceptionInterface extends Throwable
-{
-}
+interface ExceptionInterface extends Throwable {}
diff --git a/src/Http/ApiVersion.php b/src/Http/ApiVersion.php
index 730bab5..b7e261c 100644
--- a/src/Http/ApiVersion.php
+++ b/src/Http/ApiVersion.php
@@ -1,5 +1,7 @@
! in_array($key, self::STANDARD_PROBLEM_DETAILS_PROPS, true),
+ static fn (string $key) => !in_array($key, self::STANDARD_PROBLEM_DETAILS_PROPS, true),
ARRAY_FILTER_USE_KEY,
);
diff --git a/src/Http/HttpClient.php b/src/Http/HttpClient.php
index f2811b5..593a1cc 100644
--- a/src/Http/HttpClient.php
+++ b/src/Http/HttpClient.php
@@ -29,8 +29,7 @@ public function __construct(
private StreamFactoryInterface $streamFactory,
private ShlinkConfigInterface $config,
private HttpDebuggerInterface|null $debugger = null,
- ) {
- }
+ ) {}
/**
* @throws HttpException
@@ -63,16 +62,16 @@ private function callShlink(
array $query = [],
): array {
$uri = sprintf('%s/rest/v%s%s', $this->config->baseUrl(), $this->config->version()->value, $path);
- if (! empty($query)) {
+ if (!empty($query)) {
$uri = sprintf('%s?%s', $uri, http_build_query($query));
}
$req = $this->requestFactory->createRequest($method, $uri)
- ->withHeader('X-Api-Key', $this->config->apiKey());
+ ->withHeader('X-Api-Key', $this->config->apiKey());
if ($body !== null) {
$req = $req->withHeader('Content-Type', 'application/json')
- ->withBody($this->streamFactory->createStream(json_encode($body, JSON_THROW_ON_ERROR)));
+ ->withBody($this->streamFactory->createStream(json_encode($body, JSON_THROW_ON_ERROR)));
}
$this->debugger?->debugRequest($req);
diff --git a/src/Model/ListEndpointIterator.php b/src/Model/ListEndpointIterator.php
index 0da7383..9a0a5dd 100644
--- a/src/Model/ListEndpointIterator.php
+++ b/src/Model/ListEndpointIterator.php
@@ -44,7 +44,7 @@ private function getFullList(): iterable
}
$isLastPage = $currentPage < 0 || $currentPage === $this->currentPagination['pagesCount'];
- if (! $isLastPage) {
+ if (!$isLastPage) {
$this->loadPage($currentPage + 1);
yield from $this->getFullList();
}
@@ -52,7 +52,7 @@ private function getFullList(): iterable
private function calculateIndex(int $index, int $currentPage): int
{
- return ($currentPage - 1) * $this->itemsPerPage + $index;
+ return (($currentPage - 1) * $this->itemsPerPage) + $index;
}
public function count(): int
diff --git a/src/RedirectRules/Model/RedirectCondition.php b/src/RedirectRules/Model/RedirectCondition.php
index cbf8d6f..c405ec2 100644
--- a/src/RedirectRules/Model/RedirectCondition.php
+++ b/src/RedirectRules/Model/RedirectCondition.php
@@ -15,8 +15,7 @@ private function __construct(
public string|null $matchValue = null,
public string|null $matchKey = null,
private string|null $originalType = null,
- ) {
- }
+ ) {}
public static function forQueryParam(string $param, string $value): self
{
@@ -77,7 +76,7 @@ public static function fromArray(array $payload): self
$originalType = $payload['type'] ?? '';
return new self(
type: RedirectConditionType::tryFrom($originalType) ?? RedirectConditionType::UNKNOWN,
- matchValue: $payload['matchValue'] ?? null,
+ matchValue: $payload['matchValue'] ?? null,
matchKey: $payload['matchKey'] ?? null,
originalType: $originalType,
);
diff --git a/src/RedirectRules/Model/RedirectConditionType.php b/src/RedirectRules/Model/RedirectConditionType.php
index 4936409..b75de86 100644
--- a/src/RedirectRules/Model/RedirectConditionType.php
+++ b/src/RedirectRules/Model/RedirectConditionType.php
@@ -1,5 +1,7 @@
RedirectCondition::fromArray($condition),
+ RedirectCondition::fromArray(...),
$payload['conditions'] ?? [],
),
);
diff --git a/src/RedirectRules/Model/RedirectRuleData.php b/src/RedirectRules/Model/RedirectRuleData.php
index 993c6bb..b12898a 100644
--- a/src/RedirectRules/Model/RedirectRuleData.php
+++ b/src/RedirectRules/Model/RedirectRuleData.php
@@ -11,9 +11,7 @@
/**
* @param RedirectCondition[] $conditions
*/
- private function __construct(public string $longUrl, public array $conditions)
- {
- }
+ private function __construct(public string $longUrl, public array $conditions) {}
public static function forLongUrl(string $longUrl): self
{
diff --git a/src/RedirectRules/Model/RedirectRulesList.php b/src/RedirectRules/Model/RedirectRulesList.php
index 95755e3..76c33cc 100644
--- a/src/RedirectRules/Model/RedirectRulesList.php
+++ b/src/RedirectRules/Model/RedirectRulesList.php
@@ -14,16 +14,14 @@
/**
* @param RedirectRule[] $redirectRules
*/
- private function __construct(public string $defaultLongUrl, public array $redirectRules)
- {
- }
+ private function __construct(public string $defaultLongUrl, public array $redirectRules) {}
public static function fromArray(array $payload): self
{
return new self(
defaultLongUrl: $payload['defaultLongUrl'] ?? '',
redirectRules: array_map(
- static fn (array $rule) => RedirectRule::fromArray($rule),
+ RedirectRule::fromArray(...),
$payload['redirectRules'] ?? [],
),
);
diff --git a/src/RedirectRules/Model/SetRedirectRules.php b/src/RedirectRules/Model/SetRedirectRules.php
index 39cbdc3..07fae6f 100644
--- a/src/RedirectRules/Model/SetRedirectRules.php
+++ b/src/RedirectRules/Model/SetRedirectRules.php
@@ -15,9 +15,7 @@
/**
* @param array $rules
*/
- private function __construct(private array $rules)
- {
- }
+ private function __construct(private array $rules) {}
public static function fromScratch(): self
{
diff --git a/src/RedirectRules/RedirectRulesClient.php b/src/RedirectRules/RedirectRulesClient.php
index f7f4b06..298d5a0 100644
--- a/src/RedirectRules/RedirectRulesClient.php
+++ b/src/RedirectRules/RedirectRulesClient.php
@@ -17,9 +17,7 @@
readonly class RedirectRulesClient implements RedirectRulesClientInterface
{
- public function __construct(private HttpClientInterface $httpClient)
- {
- }
+ public function __construct(private HttpClientInterface $httpClient) {}
public function getShortUrlRedirectRules(ShortUrlIdentifier $identifier): RedirectRulesList
{
diff --git a/src/ShlinkClient.php b/src/ShlinkClient.php
index d07ad31..eee2426 100644
--- a/src/ShlinkClient.php
+++ b/src/ShlinkClient.php
@@ -42,8 +42,7 @@ public function __construct(
private TagsClientInterface $tagsClient,
private DomainsClientInterface $domainsClient,
private RedirectRulesClientInterface $redirectRulesClient,
- ) {
- }
+ ) {}
/**
* @inheritDoc
diff --git a/src/ShortUrls/Model/Device.php b/src/ShortUrls/Model/Device.php
index a263fb2..0f8ae7d 100644
--- a/src/ShortUrls/Model/Device.php
+++ b/src/ShortUrls/Model/Device.php
@@ -1,5 +1,7 @@
ShortUrl::fromArray($value), self::ITEMS_PER_PAGE);
+ parent::__construct($pageLoader, ShortUrl::fromArray(...), self::ITEMS_PER_PAGE);
}
/**
diff --git a/src/ShortUrls/ShortUrlsClient.php b/src/ShortUrls/ShortUrlsClient.php
index 45e0d8e..1b6c0fc 100644
--- a/src/ShortUrls/ShortUrlsClient.php
+++ b/src/ShortUrls/ShortUrlsClient.php
@@ -22,9 +22,7 @@
readonly class ShortUrlsClient implements ShortUrlsClientInterface
{
- public function __construct(private HttpClientInterface $httpClient)
- {
- }
+ public function __construct(private HttpClientInterface $httpClient) {}
public function listShortUrls(): ShortUrlsList
{
diff --git a/src/Tags/Model/TagRenaming.php b/src/Tags/Model/TagRenaming.php
index 75c1c8d..4978ac7 100644
--- a/src/Tags/Model/TagRenaming.php
+++ b/src/Tags/Model/TagRenaming.php
@@ -8,9 +8,7 @@
final readonly class TagRenaming implements JsonSerializable
{
- private function __construct(private array $payload)
- {
- }
+ private function __construct(private array $payload) {}
public static function fromOldNameAndNewName(string $oldName, string $newName): self
{
diff --git a/src/Tags/Model/TagWithStats.php b/src/Tags/Model/TagWithStats.php
index d1c66d4..8f2c5a0 100644
--- a/src/Tags/Model/TagWithStats.php
+++ b/src/Tags/Model/TagWithStats.php
@@ -8,9 +8,7 @@
final readonly class TagWithStats
{
- private function __construct(public string $tag, public int $shortUrlsCount, public VisitsSummary $visitsSummary)
- {
- }
+ private function __construct(public string $tag, public int $shortUrlsCount, public VisitsSummary $visitsSummary) {}
public static function fromArray(array $payload): self
{
diff --git a/src/Tags/Model/TagsFilter.php b/src/Tags/Model/TagsFilter.php
index b06b78f..008baaa 100644
--- a/src/Tags/Model/TagsFilter.php
+++ b/src/Tags/Model/TagsFilter.php
@@ -12,9 +12,7 @@
final class TagsFilter implements ArraySerializable
{
- private function __construct(private array $query = [])
- {
- }
+ private function __construct(private array $query = []) {}
public static function create(): self
{
@@ -55,7 +53,7 @@ public function shouldPaginateRequest(): bool
// no matter the size of the page. Because of that, when ordering by those fields, it's better to load the
// whole dataset at once, until that issue is fixed.
- if (! isset($this->query['orderBy'])) {
+ if (!isset($this->query['orderBy'])) {
return true;
}
@@ -65,6 +63,6 @@ public function shouldPaginateRequest(): bool
TagsListOrderField::VISITS_COUNT->value,
];
- return ! in_array($field, $orderFieldsThatShouldNotPaginate, true);
+ return !in_array($field, $orderFieldsThatShouldNotPaginate, true);
}
}
diff --git a/src/Tags/Model/TagsMode.php b/src/Tags/Model/TagsMode.php
index 5418715..41f6faa 100644
--- a/src/Tags/Model/TagsMode.php
+++ b/src/Tags/Model/TagsMode.php
@@ -1,5 +1,7 @@
$deletedVisits
*/
- private function __construct(public int $deletedVisits)
- {
- }
+ private function __construct(public int $deletedVisits) {}
public static function fromArray(array $payload): self
{
diff --git a/src/Visits/Model/VisitsFilterPayloadTrait.php b/src/Visits/Model/VisitsFilterPayloadTrait.php
index 74cfece..11d5b39 100644
--- a/src/Visits/Model/VisitsFilterPayloadTrait.php
+++ b/src/Visits/Model/VisitsFilterPayloadTrait.php
@@ -8,9 +8,7 @@
trait VisitsFilterPayloadTrait
{
- private function __construct(private array $query = [])
- {
- }
+ private function __construct(private array $query = []) {}
public static function create(): self
{
diff --git a/src/Visits/Model/VisitsList.php b/src/Visits/Model/VisitsList.php
index b90b1a0..b66ed8e 100644
--- a/src/Visits/Model/VisitsList.php
+++ b/src/Visits/Model/VisitsList.php
@@ -30,7 +30,7 @@ private function __construct(Closure $visitsLoader, Closure $itemMapper)
*/
public static function forTupleLoader(Closure $visitsLoader): self
{
- return new self($visitsLoader, static fn (array $value) => Visit::fromArray($value));
+ return new self($visitsLoader, Visit::fromArray(...));
}
/**
@@ -39,6 +39,6 @@ public static function forTupleLoader(Closure $visitsLoader): self
*/
public static function forOrphanVisitsTupleLoader(Closure $visitsLoader): self
{
- return new self($visitsLoader, static fn (array $value) => OrphanVisit::fromArray($value));
+ return new self($visitsLoader, OrphanVisit::fromArray(...));
}
}
diff --git a/src/Visits/Model/VisitsOverview.php b/src/Visits/Model/VisitsOverview.php
index c56d477..56c865d 100644
--- a/src/Visits/Model/VisitsOverview.php
+++ b/src/Visits/Model/VisitsOverview.php
@@ -8,9 +8,7 @@
final readonly class VisitsOverview implements Countable
{
- private function __construct(public VisitsSummary $nonOrphanVisits, public VisitsSummary $orphanVisits)
- {
- }
+ private function __construct(public VisitsSummary $nonOrphanVisits, public VisitsSummary $orphanVisits) {}
public static function fromArray(array $payload): self
{
diff --git a/src/Visits/Model/VisitsSummary.php b/src/Visits/Model/VisitsSummary.php
index 57c84c1..68a0ae9 100644
--- a/src/Visits/Model/VisitsSummary.php
+++ b/src/Visits/Model/VisitsSummary.php
@@ -11,9 +11,7 @@
* @param int<0, max> $nonBots
* @param int<0, max> $bots
*/
- private function __construct(public int $total, public int $nonBots, public int $bots)
- {
- }
+ private function __construct(public int $total, public int $nonBots, public int $bots) {}
public static function fromArray(array $payload): self
{
diff --git a/src/Visits/VisitsClient.php b/src/Visits/VisitsClient.php
index ef30e16..b6d3a79 100644
--- a/src/Visits/VisitsClient.php
+++ b/src/Visits/VisitsClient.php
@@ -23,9 +23,7 @@
readonly class VisitsClient implements VisitsClientInterface
{
- public function __construct(private HttpClientInterface $httpClient)
- {
- }
+ public function __construct(private HttpClientInterface $httpClient) {}
public function getVisitsOverview(): VisitsOverview
{
diff --git a/test-integration/Tags/TagsClientTest.php b/test-integration/Tags/TagsClientTest.php
index e68378d..18de7fe 100644
--- a/test-integration/Tags/TagsClientTest.php
+++ b/test-integration/Tags/TagsClientTest.php
@@ -22,9 +22,10 @@ protected function setUp(): void
{
$this->client = new TagsClient(self::httpClient());
- self::shlinkClient()->createShortUrl(
- ShortUrlCreation::forLongUrl('https://example.com')->withTags(...self::BASE_TAGS),
- );
+ self::shlinkClient()
+ ->createShortUrl(
+ ShortUrlCreation::forLongUrl('https://example.com')->withTags(...self::BASE_TAGS),
+ );
}
#[Test]
diff --git a/test/Builder/SingletonShlinkClientBuilderTest.php b/test/Builder/SingletonShlinkClientBuilderTest.php
index 99b2a2f..0c22550 100644
--- a/test/Builder/SingletonShlinkClientBuilderTest.php
+++ b/test/Builder/SingletonShlinkClientBuilderTest.php
@@ -24,7 +24,7 @@ class SingletonShlinkClientBuilderTest extends TestCase
use ClientBuilderMethodsProviderTrait;
private SingletonShlinkClientBuilder $builder;
- private MockObject & ShlinkClientBuilderInterface $wrapped;
+ private MockObject&ShlinkClientBuilderInterface $wrapped;
public function setUp(): void
{
@@ -38,15 +38,19 @@ public function setUp(): void
#[Test, DataProvider('provideMethods')]
public function buildClientReturnsAlwaysNewInstances(string $method): void
{
- $this->wrapped->expects($this->exactly(2))->method($method)->with(
- $this->isInstanceOf(ShlinkConfigInterface::class),
- )->willReturn(new ShlinkClient(
- $this->createStub(ShortUrlsClientInterface::class),
- $this->createStub(VisitsClientInterface::class),
- $this->createStub(TagsClientInterface::class),
- $this->createStub(DomainsClientInterface::class),
- $this->createStub(RedirectRulesClientInterface::class),
- ));
+ $this->wrapped
+ ->expects($this->exactly(2))
+ ->method($method)
+ ->with(
+ $this->isInstanceOf(ShlinkConfigInterface::class),
+ )
+ ->willReturn(new ShlinkClient(
+ $this->createStub(ShortUrlsClientInterface::class),
+ $this->createStub(VisitsClientInterface::class),
+ $this->createStub(TagsClientInterface::class),
+ $this->createStub(DomainsClientInterface::class),
+ $this->createStub(RedirectRulesClientInterface::class),
+ ));
$configOne = ShlinkConfig::fromBaseUrlAndApiKey('foo', 'bar');
$instance1 = $this->builder->{$method}($configOne);
diff --git a/test/Config/ArrayShlinkConfigTest.php b/test/Config/ArrayShlinkConfigTest.php
index d0518d3..775f8a0 100644
--- a/test/Config/ArrayShlinkConfigTest.php
+++ b/test/Config/ArrayShlinkConfigTest.php
@@ -26,17 +26,21 @@ public function exceptionIsThrownIfProvidedDataIsInvalid(
public static function provideInvalidData(): iterable
{
- $standardMessage = 'Provided array is missing "baseUrl" and/or "apiKey" props, or their values are invalid. '
+ $standardMessage =
+ 'Provided array is missing "baseUrl" and/or "apiKey" props, or their values are invalid. '
. 'Make sure both are set with strings.';
yield 'both missing' => [[], $standardMessage];
yield 'missing api key' => [[ArrayShlinkConfig::BASE_URL_PROP => 'foo'], $standardMessage];
yield 'missing base url' => [[ArrayShlinkConfig::API_KEY_PROP => 'bar'], $standardMessage];
- yield 'invalid version' => [[
- ArrayShlinkConfig::BASE_URL_PROP => 'foo',
- ArrayShlinkConfig::API_KEY_PROP => 'bar',
- ArrayShlinkConfig::VERSION_PROP => '2',
- ], 'Provided version "2" is invalid. Expected one of ["3"]'];
+ yield 'invalid version' => [
+ [
+ ArrayShlinkConfig::BASE_URL_PROP => 'foo',
+ ArrayShlinkConfig::API_KEY_PROP => 'bar',
+ ArrayShlinkConfig::VERSION_PROP => '2',
+ ],
+ 'Provided version "2" is invalid. Expected one of ["3"]',
+ ];
}
#[Test]
diff --git a/test/Config/EnvShlinkConfigTest.php b/test/Config/EnvShlinkConfigTest.php
index 05bdc05..3219904 100644
--- a/test/Config/EnvShlinkConfigTest.php
+++ b/test/Config/EnvShlinkConfigTest.php
@@ -41,7 +41,8 @@ public static function provideWrongEnvSetUps(): iterable
putenv(sprintf('%s=%s', $key, $value));
}
};
- $standardMessage = 'Either "SHLINK_BASE_URL" and/or "SHLINK_API_KEY" env vars are missing. '
+ $standardMessage =
+ 'Either "SHLINK_BASE_URL" and/or "SHLINK_API_KEY" env vars are missing. '
. 'Make sure both are properly set.';
yield 'no env vars' => [$buildSetUpWithEnvVars(), $standardMessage];
@@ -53,11 +54,14 @@ public static function provideWrongEnvSetUps(): iterable
$buildSetUpWithEnvVars([EnvShlinkConfig::BASE_URL_ENV_VAR => 'SOME_VALUE']),
$standardMessage,
];
- yield 'invalid api version' => [$buildSetUpWithEnvVars([
- EnvShlinkConfig::BASE_URL_ENV_VAR => 'SOME_VALUE',
- EnvShlinkConfig::API_KEY_ENV_VAR => 'SOME_VALUE',
- EnvShlinkConfig::VERSION_ENV_VAR => '4',
- ]), 'Provided version "4" is invalid. Expected one of ["3"]'];
+ yield 'invalid api version' => [
+ $buildSetUpWithEnvVars([
+ EnvShlinkConfig::BASE_URL_ENV_VAR => 'SOME_VALUE',
+ EnvShlinkConfig::API_KEY_ENV_VAR => 'SOME_VALUE',
+ EnvShlinkConfig::VERSION_ENV_VAR => '4',
+ ]),
+ 'Provided version "4" is invalid. Expected one of ["3"]',
+ ];
}
#[Test]
diff --git a/test/Domains/DomainsClientTest.php b/test/Domains/DomainsClientTest.php
index b0d70cc..7b1f448 100644
--- a/test/Domains/DomainsClientTest.php
+++ b/test/Domains/DomainsClientTest.php
@@ -22,7 +22,7 @@
class DomainsClientTest extends TestCase
{
private DomainsClient $domainsClient;
- private MockObject & HttpClientInterface $httpClient;
+ private MockObject&HttpClientInterface $httpClient;
public function setUp(): void
{
@@ -63,9 +63,13 @@ public function expectedDomainsAreReturnedOnList(): void
],
];
- $this->httpClient->expects($this->once())->method('getFromShlink')->with('/domains')->willReturn([
- 'domains' => ['data' => $payload],
- ]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('getFromShlink')
+ ->with('/domains')
+ ->willReturn([
+ 'domains' => ['data' => $payload],
+ ]);
$result = $this->domainsClient->listDomains();
$count = 0;
@@ -99,15 +103,19 @@ public function configureDomainRedirectsSendsExpectedRequestAndReceivesExpectedR
->removingBaseUrlRedirect()
->removingInvalidShortUrlRedirect();
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- '/domains/redirects',
- 'PATCH',
- $config,
- )->willReturn([
- DomainRedirectProps::BASE_URL->value => null,
- DomainRedirectProps::REGULAR_NOT_FOUND->value => 'somewhere.com',
- DomainRedirectProps::INVALID_SHORT_URL->value => null,
- ]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ '/domains/redirects',
+ 'PATCH',
+ $config,
+ )
+ ->willReturn([
+ DomainRedirectProps::BASE_URL->value => null,
+ DomainRedirectProps::REGULAR_NOT_FOUND->value => 'somewhere.com',
+ DomainRedirectProps::INVALID_SHORT_URL->value => null,
+ ]);
$result = $this->domainsClient->configureDomainRedirects($config);
@@ -133,8 +141,8 @@ public function configureDomainRedirectsThrowsProperExceptionIfSomethingGoesWron
public static function provideExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_ARGUMENT' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_ARGUMENT' => [
HttpException::fromPayload(['type' => ErrorType::INVALID_DATA->value]),
InvalidDataException::class,
];
diff --git a/test/Domains/Exception/DomainNotFoundExceptionTest.php b/test/Domains/Exception/DomainNotFoundExceptionTest.php
index e4af6ed..c322cdc 100644
--- a/test/Domains/Exception/DomainNotFoundExceptionTest.php
+++ b/test/Domains/Exception/DomainNotFoundExceptionTest.php
@@ -29,14 +29,24 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), '', '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- ]), '', $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message again',
- 'status' => $code = 404,
- 'authority' => $authority = 'authority',
- ]), $authority, $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ ]),
+ '',
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message again',
+ 'status' => $code = 404,
+ 'authority' => $authority = 'authority',
+ ]),
+ $authority,
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/Domains/Model/DomainRedirectsConfigTest.php b/test/Domains/Model/DomainRedirectsConfigTest.php
index 9b8693f..bd1f8f7 100644
--- a/test/Domains/Model/DomainRedirectsConfigTest.php
+++ b/test/Domains/Model/DomainRedirectsConfigTest.php
@@ -22,9 +22,9 @@ public function payloadIsBuiltAsExpected(callable $createConfig, array $expected
public static function provideConfigs(): iterable
{
- yield [fn () => DomainRedirectsConfig::forDomain('foo.com'), ['domain' => 'foo.com']];
+ yield [static fn () => DomainRedirectsConfig::forDomain('foo.com'), ['domain' => 'foo.com']];
yield [
- fn () => DomainRedirectsConfig::forDomain('foo.com')
+ static fn () => DomainRedirectsConfig::forDomain('foo.com')
->withRegularNotFoundRedirect('somewhere.com'),
[
'domain' => 'foo.com',
@@ -32,7 +32,7 @@ public static function provideConfigs(): iterable
],
];
yield [
- fn () => DomainRedirectsConfig::forDomain('bar.com')
+ static fn () => DomainRedirectsConfig::forDomain('bar.com')
->withRegularNotFoundRedirect('foo.com')
->removingBaseUrlRedirect(),
[
@@ -42,7 +42,7 @@ public static function provideConfigs(): iterable
],
];
yield [
- fn () => DomainRedirectsConfig::forDomain('bar.com')
+ static fn () => DomainRedirectsConfig::forDomain('bar.com')
->withRegularNotFoundRedirect('foo.net')
->withInvalidShortUrlRedirect('something.com')
->removingBaseUrlRedirect(),
@@ -54,7 +54,7 @@ public static function provideConfigs(): iterable
],
];
yield [
- fn () => DomainRedirectsConfig::forDomain('baz.com')
+ static fn () => DomainRedirectsConfig::forDomain('baz.com')
->removingBaseUrlRedirect()
->removingRegularNotFoundRedirect()
->removingInvalidShortUrlRedirect(),
@@ -66,7 +66,7 @@ public static function provideConfigs(): iterable
],
];
yield [
- fn () => DomainRedirectsConfig::forDomain('foobarbaz.com')
+ static fn () => DomainRedirectsConfig::forDomain('foobarbaz.com')
->withRegularNotFoundRedirect('foo.net')
->withInvalidShortUrlRedirect('something.com')
->withBaseUrlRedirect('base-redirect.com'),
diff --git a/test/Http/Exception/HttpExceptionTest.php b/test/Http/Exception/HttpExceptionTest.php
index 1252876..1c9ab09 100644
--- a/test/Http/Exception/HttpExceptionTest.php
+++ b/test/Http/Exception/HttpExceptionTest.php
@@ -41,7 +41,7 @@ public function exceptionIsCreatedAsExpectedFromResponse(
array $expectedAdditional,
): void {
$e = HttpException::fromNonSuccessfulResponse(
- (new Response())->withBody(Utils::streamFor(json_encode($payload, JSON_THROW_ON_ERROR))),
+ new Response()->withBody(Utils::streamFor(json_encode($payload, JSON_THROW_ON_ERROR))),
);
$this->runAssertions($e, $expectedType, $expectedTitle, $expectedDetail, $expectedStatus, $expectedAdditional);
}
diff --git a/test/Http/HttpClientTest.php b/test/Http/HttpClientTest.php
index 03d017c..8cec1c5 100644
--- a/test/Http/HttpClientTest.php
+++ b/test/Http/HttpClientTest.php
@@ -26,19 +26,23 @@
class HttpClientTest extends TestCase
{
private HttpClient $httpClient;
- private MockObject & ClientInterface $client;
+ private MockObject&ClientInterface $client;
public function setUp(): void
{
$this->client = $this->createMock(ClientInterface::class);
$requestFactory = $this->createStub(RequestFactoryInterface::class);
- $requestFactory->method('createRequest')->willReturnCallback(
- fn (string $method, string|UriInterface $uri) => new Request($method, $uri),
- );
+ $requestFactory
+ ->method('createRequest')
+ ->willReturnCallback(
+ static fn (string $method, string|UriInterface $uri) => new Request($method, $uri),
+ );
$streamFactory = $this->createStub(StreamFactoryInterface::class);
- $streamFactory->method('createStream')->willReturnCallback(fn (string $content) => Utils::streamFor($content));
+ $streamFactory
+ ->method('createStream')
+ ->willReturnCallback(Utils::streamFor(...));
$this->httpClient = new HttpClient(
$this->client,
@@ -54,16 +58,20 @@ public function getFromShlinkSendsExpectedRequest(
array|ArraySerializable $query,
string $expectedUri,
): void {
- $this->client->expects($this->once())->method('sendRequest')->with($this->callback(
- function (RequestInterface $req) use ($expectedUri) {
- Assert::assertEquals($expectedUri, $req->getUri()->__toString());
- Assert::assertEquals('GET', $req->getMethod());
- Assert::assertTrue($req->hasHeader('X-Api-Key'));
- Assert::assertEquals('123', $req->getHeaderLine('X-Api-Key'));
-
- return true;
- },
- ))->willReturn(new Response(200, [], '{}'));
+ $this->client
+ ->expects($this->once())
+ ->method('sendRequest')
+ ->with($this->callback(
+ static function (RequestInterface $req) use ($expectedUri) {
+ Assert::assertEquals($expectedUri, $req->getUri()->__toString());
+ Assert::assertEquals('GET', $req->getMethod());
+ Assert::assertTrue($req->hasHeader('X-Api-Key'));
+ Assert::assertEquals('123', $req->getHeaderLine('X-Api-Key'));
+
+ return true;
+ },
+ ))
+ ->willReturn(new Response(200, [], '{}'));
$this->httpClient->getFromShlink($path, $query);
}
@@ -87,7 +95,10 @@ public function toArray(): array
#[Test, DataProvider('provideNonSuccessfulStatuses')]
public function nonSuccessfulResponseResultsInException(int $status): void
{
- $this->client->expects($this->once())->method('sendRequest')->willReturn(new Response($status, [], '{}'));
+ $this->client
+ ->expects($this->once())
+ ->method('sendRequest')
+ ->willReturn(new Response($status, [], '{}'));
$this->expectException(HttpException::class);
@@ -107,9 +118,12 @@ public static function provideNonSuccessfulStatuses(): iterable
#[Test, DataProvider('provideSuccessfulStatuses')]
public function returnsExpectedResultBasedOnResponseStatus(int $status, array $expectedResult): void
{
- $this->client->expects($this->once())->method('sendRequest')->willReturn(
- new Response($status, [], '{"foo": "bar"}'),
- );
+ $this->client
+ ->expects($this->once())
+ ->method('sendRequest')
+ ->willReturn(
+ new Response($status, [], '{"foo": "bar"}'),
+ );
$result = $this->httpClient->getFromShlink('');
@@ -130,16 +144,20 @@ public function callShlinkWithBodySendsExpectedRequest(
array|JsonSerializable $body,
string $expectedBody,
): void {
- $this->client->expects($this->once())->method('sendRequest')->with(
- $this->callback(function (RequestInterface $req) use ($expectedBody, $method) {
- Assert::assertEquals($expectedBody, $req->getBody()->__toString());
- Assert::assertEquals($method, $req->getMethod());
- Assert::assertTrue($req->hasHeader('X-Api-Key'));
- Assert::assertEquals('123', $req->getHeaderLine('X-Api-Key'));
-
- return true;
- }),
- )->willReturn(new Response(200, [], '{}'));
+ $this->client
+ ->expects($this->once())
+ ->method('sendRequest')
+ ->with(
+ $this->callback(static function (RequestInterface $req) use ($expectedBody, $method) {
+ Assert::assertEquals($expectedBody, $req->getBody()->__toString());
+ Assert::assertEquals($method, $req->getMethod());
+ Assert::assertTrue($req->hasHeader('X-Api-Key'));
+ Assert::assertEquals('123', $req->getHeaderLine('X-Api-Key'));
+
+ return true;
+ }),
+ )
+ ->willReturn(new Response(200, [], '{}'));
$this->httpClient->callShlinkWithBody('/foo/bar', $method, $body);
}
diff --git a/test/RedirectRules/Model/RedirectRuleDataTest.php b/test/RedirectRules/Model/RedirectRuleDataTest.php
index c753cc1..febc77a 100644
--- a/test/RedirectRules/Model/RedirectRuleDataTest.php
+++ b/test/RedirectRules/Model/RedirectRuleDataTest.php
@@ -27,14 +27,17 @@ public function creationFromRedirectRule(): void
]);
$data = RedirectRuleData::fromRedirectRule($redirectRule);
- self::assertEquals([
- 'longUrl' => 'https://example.com',
- 'conditions' => [
- RedirectCondition::fromArray([]),
- RedirectCondition::fromArray([]),
- RedirectCondition::fromArray([]),
+ self::assertEquals(
+ [
+ 'longUrl' => 'https://example.com',
+ 'conditions' => [
+ RedirectCondition::fromArray([]),
+ RedirectCondition::fromArray([]),
+ RedirectCondition::fromArray([]),
+ ],
],
- ], $data->jsonSerialize());
+ $data->jsonSerialize(),
+ );
}
#[Test]
diff --git a/test/RedirectRules/Model/SetRedirectRulesTest.php b/test/RedirectRules/Model/SetRedirectRulesTest.php
index 2ca94e6..14828bd 100644
--- a/test/RedirectRules/Model/SetRedirectRulesTest.php
+++ b/test/RedirectRules/Model/SetRedirectRulesTest.php
@@ -55,35 +55,38 @@ public function creationFromRedirectRulesList(): void
$setRules = SetRedirectRules::fromRedirectRulesList($list);
- self::assertEquals([
- 'redirectRules' => [
- [
- 'longUrl' => 'https://example.com/android',
- 'conditions' => [
- [
- 'type' => RedirectConditionType::DEVICE->value,
- 'matchValue' => Device::ANDROID->value,
- 'matchKey' => null,
+ self::assertEquals(
+ [
+ 'redirectRules' => [
+ [
+ 'longUrl' => 'https://example.com/android',
+ 'conditions' => [
+ [
+ 'type' => RedirectConditionType::DEVICE->value,
+ 'matchValue' => Device::ANDROID->value,
+ 'matchKey' => null,
+ ],
],
],
- ],
- [
- 'longUrl' => 'https://example.com/freanch-and-foo-bar-query',
- 'conditions' => [
- [
- 'type' => RedirectConditionType::LANGUAGE->value,
- 'matchValue' => 'fr',
- 'matchKey' => null,
- ],
- [
- 'type' => RedirectConditionType::QUERY_PARAM->value,
- 'matchValue' => 'bar',
- 'matchKey' => 'foo',
+ [
+ 'longUrl' => 'https://example.com/freanch-and-foo-bar-query',
+ 'conditions' => [
+ [
+ 'type' => RedirectConditionType::LANGUAGE->value,
+ 'matchValue' => 'fr',
+ 'matchKey' => null,
+ ],
+ [
+ 'type' => RedirectConditionType::QUERY_PARAM->value,
+ 'matchValue' => 'bar',
+ 'matchKey' => 'foo',
+ ],
],
],
],
],
- ], json_decode((string) json_encode($setRules->jsonSerialize()), associative: true));
+ json_decode((string) json_encode($setRules->jsonSerialize()), associative: true),
+ );
}
#[Test]
@@ -104,28 +107,37 @@ public function rulesCanBeAddedOrRemoved(): void
$setRules = SetRedirectRules::fromScratch()
->withPushedRule(RedirectRuleData::forLongUrl('https://example.com/first'))
->withPushedRule(RedirectRuleData::forLongUrl('https://example.com/second'));
- self::assertEquals([
- 'redirectRules' => [
- RedirectRuleData::forLongUrl('https://example.com/first'),
- RedirectRuleData::forLongUrl('https://example.com/second'),
+ self::assertEquals(
+ [
+ 'redirectRules' => [
+ RedirectRuleData::forLongUrl('https://example.com/first'),
+ RedirectRuleData::forLongUrl('https://example.com/second'),
+ ],
],
- ], $setRules->jsonSerialize());
+ $setRules->jsonSerialize(),
+ );
$setRules = $setRules->withRule(2, RedirectRuleData::forLongUrl('https://example.com/third'));
- self::assertEquals([
- 'redirectRules' => [
- RedirectRuleData::forLongUrl('https://example.com/first'),
- RedirectRuleData::forLongUrl('https://example.com/third'),
- RedirectRuleData::forLongUrl('https://example.com/second'),
+ self::assertEquals(
+ [
+ 'redirectRules' => [
+ RedirectRuleData::forLongUrl('https://example.com/first'),
+ RedirectRuleData::forLongUrl('https://example.com/third'),
+ RedirectRuleData::forLongUrl('https://example.com/second'),
+ ],
],
- ], $setRules->jsonSerialize());
+ $setRules->jsonSerialize(),
+ );
$setRules = $setRules->withoutRule(1);
- self::assertEquals([
- 'redirectRules' => [
- RedirectRuleData::forLongUrl('https://example.com/third'),
- RedirectRuleData::forLongUrl('https://example.com/second'),
+ self::assertEquals(
+ [
+ 'redirectRules' => [
+ RedirectRuleData::forLongUrl('https://example.com/third'),
+ RedirectRuleData::forLongUrl('https://example.com/second'),
+ ],
],
- ], $setRules->jsonSerialize());
+ $setRules->jsonSerialize(),
+ );
}
}
diff --git a/test/RedirectRules/RedirectRulesClientTest.php b/test/RedirectRules/RedirectRulesClientTest.php
index 0dfa17d..c342060 100644
--- a/test/RedirectRules/RedirectRulesClientTest.php
+++ b/test/RedirectRules/RedirectRulesClientTest.php
@@ -25,7 +25,7 @@
class RedirectRulesClientTest extends TestCase
{
private RedirectRulesClient $client;
- private MockObject & HttpClientInterface $httpClient;
+ private MockObject&HttpClientInterface $httpClient;
public function setUp(): void
{
@@ -38,41 +38,45 @@ public function getShortUrlRedirectRulesCallsHttpClient(ShortUrlIdentifier $iden
{
[$shortCode, $query] = $identifier->toShortCodeAndQuery();
- $this->httpClient->expects($this->once())->method('getFromShlink')->with(
- sprintf('/short-urls/%s/redirect-rules', $shortCode),
- $query,
- )->willReturn([
- 'defaultLongUrl' => 'https://example.com/default',
- 'redirectRules' => [
- [
- 'longUrl' => 'https://example.com/android',
- 'priority' => 1,
- 'conditions' => [
- [
- 'type' => RedirectConditionType::DEVICE->value,
- 'matchValue' => Device::ANDROID->value,
- 'matchKey' => null,
+ $this->httpClient
+ ->expects($this->once())
+ ->method('getFromShlink')
+ ->with(
+ sprintf('/short-urls/%s/redirect-rules', $shortCode),
+ $query,
+ )
+ ->willReturn([
+ 'defaultLongUrl' => 'https://example.com/default',
+ 'redirectRules' => [
+ [
+ 'longUrl' => 'https://example.com/android',
+ 'priority' => 1,
+ 'conditions' => [
+ [
+ 'type' => RedirectConditionType::DEVICE->value,
+ 'matchValue' => Device::ANDROID->value,
+ 'matchKey' => null,
+ ],
],
],
- ],
- [
- 'longUrl' => 'https://example.com/freanch-and-foo-bar-query',
- 'priority' => 2,
- 'conditions' => [
- [
- 'type' => RedirectConditionType::LANGUAGE->value,
- 'matchValue' => 'fr',
- 'matchKey' => null,
- ],
- [
- 'type' => RedirectConditionType::QUERY_PARAM->value,
- 'matchValue' => 'bar',
- 'matchKey' => 'foo',
+ [
+ 'longUrl' => 'https://example.com/freanch-and-foo-bar-query',
+ 'priority' => 2,
+ 'conditions' => [
+ [
+ 'type' => RedirectConditionType::LANGUAGE->value,
+ 'matchValue' => 'fr',
+ 'matchKey' => null,
+ ],
+ [
+ 'type' => RedirectConditionType::QUERY_PARAM->value,
+ 'matchValue' => 'bar',
+ 'matchKey' => 'foo',
+ ],
],
],
],
- ],
- ]);
+ ]);
$result = $this->client->getShortUrlRedirectRules($identifier);
@@ -126,15 +130,19 @@ public function setShortUrlRedirectRulesCallsHttpClient(ShortUrlIdentifier $iden
[$shortCode, $query] = $identifier->toShortCodeAndQuery();
$rules = SetRedirectRules::fromScratch();
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- sprintf('/short-urls/%s/redirect-rules', $shortCode),
- 'POST',
- $rules,
- $query,
- )->willReturn([
- 'defaultLongUrl' => 'https://example.com/default',
- 'redirectRules' => [],
- ]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ sprintf('/short-urls/%s/redirect-rules', $shortCode),
+ 'POST',
+ $rules,
+ $query,
+ )
+ ->willReturn([
+ 'defaultLongUrl' => 'https://example.com/default',
+ 'redirectRules' => [],
+ ]);
$result = $this->client->setShortUrlRedirectRules($identifier, $rules);
diff --git a/test/ShlinkClientTest.php b/test/ShlinkClientTest.php
index a41d04e..956918f 100644
--- a/test/ShlinkClientTest.php
+++ b/test/ShlinkClientTest.php
@@ -41,11 +41,11 @@
class ShlinkClientTest extends TestCase
{
private ShlinkClient $shlinkClient;
- private MockObject & ShortUrlsClientInterface $shortUrlsClient;
- private MockObject & VisitsClientInterface $visitsClient;
- private MockObject & TagsClientInterface $tagsClient;
- private MockObject & DomainsClientInterface $domainsClient;
- private MockObject & RedirectRulesClientInterface $redirectRulesClient;
+ private MockObject&ShortUrlsClientInterface $shortUrlsClient;
+ private MockObject&VisitsClientInterface $visitsClient;
+ private MockObject&TagsClientInterface $tagsClient;
+ private MockObject&DomainsClientInterface $domainsClient;
+ private MockObject&RedirectRulesClientInterface $redirectRulesClient;
public function setUp(): void
{
@@ -74,18 +74,24 @@ public function listDomainsDelegatesCallToProperClient(): void
#[Test]
public function configureDomainRedirectsDelegatesCallToProperClient(): void
{
- $this->domainsClient->expects($this->once())->method('configureDomainRedirects')->willReturn(
- DomainRedirects::fromArray([]),
- );
+ $this->domainsClient
+ ->expects($this->once())
+ ->method('configureDomainRedirects')
+ ->willReturn(
+ DomainRedirects::fromArray([]),
+ );
$this->shlinkClient->configureDomainRedirects(DomainRedirectsConfig::forDomain('foo.com'));
}
#[Test]
public function listShortUrlsDelegatesCallToProperClient(): void
{
- $this->shortUrlsClient->expects($this->once())->method('listShortUrls')->willReturn(
- ShortUrlsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->shortUrlsClient
+ ->expects($this->once())
+ ->method('listShortUrls')
+ ->willReturn(
+ ShortUrlsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listShortUrls();
}
@@ -93,9 +99,13 @@ public function listShortUrlsDelegatesCallToProperClient(): void
public function listShortUrlsWithFilterDelegatesCallToProperClient(): void
{
$filter = ShortUrlsFilter::create();
- $this->shortUrlsClient->expects($this->once())->method('listShortUrlsWithFilter')->with($filter)->willReturn(
- ShortUrlsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->shortUrlsClient
+ ->expects($this->once())
+ ->method('listShortUrlsWithFilter')
+ ->with($filter)
+ ->willReturn(
+ ShortUrlsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listShortUrlsWithFilter($filter);
}
@@ -104,9 +114,13 @@ public function listShortUrlsWithFilterDelegatesCallToProperClient(): void
public function getShortUrlDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
- $this->shortUrlsClient->expects($this->once())->method('getShortUrl')->with($identifier)->willReturn(
- ShortUrl::fromArray(['dateCreated' => (new DateTimeImmutable())->format(DateTimeInterface::ATOM)]),
- );
+ $this->shortUrlsClient
+ ->expects($this->once())
+ ->method('getShortUrl')
+ ->with($identifier)
+ ->willReturn(
+ ShortUrl::fromArray(['dateCreated' => new DateTimeImmutable()->format(DateTimeInterface::ATOM)]),
+ );
$this->shlinkClient->getShortUrl($identifier);
}
@@ -124,9 +138,13 @@ public function deleteShortUrlDelegatesCallToProperClient(): void
public function createShortUrlDelegatesCallToProperClient(): void
{
$data = ShortUrlCreation::forLongUrl('https://foo.com');
- $this->shortUrlsClient->expects($this->once())->method('createShortUrl')->with($data)->willReturn(
- ShortUrl::fromArray(['dateCreated' => (new DateTimeImmutable())->format(DateTimeInterface::ATOM)]),
- );
+ $this->shortUrlsClient
+ ->expects($this->once())
+ ->method('createShortUrl')
+ ->with($data)
+ ->willReturn(
+ ShortUrl::fromArray(['dateCreated' => new DateTimeImmutable()->format(DateTimeInterface::ATOM)]),
+ );
$this->shlinkClient->createShortUrl($data);
}
@@ -136,9 +154,13 @@ public function editShortUrlDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
$data = ShortUrlEdition::create();
- $this->shortUrlsClient->expects($this->once())->method('editShortUrl')->with($identifier, $data)->willReturn(
- ShortUrl::fromArray(['dateCreated' => (new DateTimeImmutable())->format(DateTimeInterface::ATOM)]),
- );
+ $this->shortUrlsClient
+ ->expects($this->once())
+ ->method('editShortUrl')
+ ->with($identifier, $data)
+ ->willReturn(
+ ShortUrl::fromArray(['dateCreated' => new DateTimeImmutable()->format(DateTimeInterface::ATOM)]),
+ );
$this->shlinkClient->editShortUrl($identifier, $data);
}
@@ -162,9 +184,12 @@ public function listTagsWithFilterDelegatesCallToProperClient(): void
#[Test]
public function listTagsWithStatsDelegatesCallToProperClient(): void
{
- $this->tagsClient->expects($this->once())->method('listTagsWithStats')->willReturn(
- TagsWithStatsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->tagsClient
+ ->expects($this->once())
+ ->method('listTagsWithStats')
+ ->willReturn(
+ TagsWithStatsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listTagsWithStats();
}
@@ -172,9 +197,13 @@ public function listTagsWithStatsDelegatesCallToProperClient(): void
public function listTagsWithStatsWithFilterDelegatesCallToProperClient(): void
{
$filter = TagsFilter::create();
- $this->tagsClient->expects($this->once())->method('listTagsWithStatsWithFilter')->with($filter)->willReturn(
- TagsWithStatsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->tagsClient
+ ->expects($this->once())
+ ->method('listTagsWithStatsWithFilter')
+ ->with($filter)
+ ->willReturn(
+ TagsWithStatsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listTagsWithStatsWithFilter($filter);
}
@@ -198,9 +227,12 @@ public function deleteTagsDelegatesCallToProperClient(): void
#[Test]
public function getVisitsOverviewDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('getVisitsOverview')->willReturn(
- VisitsOverview::fromArray([]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('getVisitsOverview')
+ ->willReturn(
+ VisitsOverview::fromArray([]),
+ );
$this->shlinkClient->getVisitsOverview();
}
@@ -208,9 +240,13 @@ public function getVisitsOverviewDelegatesCallToProperClient(): void
public function listShortUrlVisitsDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
- $this->visitsClient->expects($this->once())->method('listShortUrlVisits')->with($identifier)->willReturn(
- VisitsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listShortUrlVisits')
+ ->with($identifier)
+ ->willReturn(
+ VisitsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listShortUrlVisits($identifier);
}
@@ -220,10 +256,14 @@ public function listShortUrlVisitsWithFilterDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
$filter = VisitsFilter::create();
- $this->visitsClient->expects($this->once())->method('listShortUrlVisitsWithFilter')->with(
- $identifier,
- $filter,
- )->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listShortUrlVisitsWithFilter')
+ ->with(
+ $identifier,
+ $filter,
+ )
+ ->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
$this->shlinkClient->listShortUrlVisitsWithFilter($identifier, $filter);
}
@@ -231,9 +271,13 @@ public function listShortUrlVisitsWithFilterDelegatesCallToProperClient(): void
#[Test]
public function listTagVisitsDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('listTagVisits')->with('foo')->willReturn(
- VisitsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listTagVisits')
+ ->with('foo')
+ ->willReturn(
+ VisitsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listTagVisits('foo');
}
@@ -241,10 +285,14 @@ public function listTagVisitsDelegatesCallToProperClient(): void
public function listTagVisitsWithFilterDelegatesCallToProperClient(): void
{
$filter = VisitsFilter::create();
- $this->visitsClient->expects($this->once())->method('listTagVisitsWithFilter')->with(
- 'foo',
- $filter,
- )->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listTagVisitsWithFilter')
+ ->with(
+ 'foo',
+ $filter,
+ )
+ ->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
$this->shlinkClient->listTagVisitsWithFilter('foo', $filter);
}
@@ -252,9 +300,12 @@ public function listTagVisitsWithFilterDelegatesCallToProperClient(): void
#[Test]
public function listDefaultDomainVisitsDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('listDefaultDOmainVisits')->willReturn(
- VisitsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listDefaultDOmainVisits')
+ ->willReturn(
+ VisitsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listDefaultDOmainVisits();
}
@@ -262,9 +313,13 @@ public function listDefaultDomainVisitsDelegatesCallToProperClient(): void
public function listDefaultDomainVisitsWithFilterDelegatesCallToProperClient(): void
{
$filter = VisitsFilter::create();
- $this->visitsClient->expects($this->once())->method('listDefaultDOmainVisitsWithFilter')->with(
- $filter,
- )->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listDefaultDOmainVisitsWithFilter')
+ ->with(
+ $filter,
+ )
+ ->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
$this->shlinkClient->listDefaultDOmainVisitsWithFilter($filter);
}
@@ -272,9 +327,13 @@ public function listDefaultDomainVisitsWithFilterDelegatesCallToProperClient():
#[Test]
public function listDomainVisitsDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('listDomainVisits')->with('foo.com')->willReturn(
- VisitsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listDomainVisits')
+ ->with('foo.com')
+ ->willReturn(
+ VisitsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listDomainVisits('foo.com');
}
@@ -282,10 +341,14 @@ public function listDomainVisitsDelegatesCallToProperClient(): void
public function listDomainVisitsWithFilterDelegatesCallToProperClient(): void
{
$filter = VisitsFilter::create();
- $this->visitsClient->expects($this->once())->method('listDomainVisitsWithFilter')->with(
- 'foo.com',
- $filter,
- )->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listDomainVisitsWithFilter')
+ ->with(
+ 'foo.com',
+ $filter,
+ )
+ ->willReturn(VisitsList::forTupleLoader(static fn () => [[], []]));
$this->shlinkClient->listDomainVisitsWithFilter('foo.com', $filter);
}
@@ -293,9 +356,12 @@ public function listDomainVisitsWithFilterDelegatesCallToProperClient(): void
#[Test]
public function listOrphanVisitsDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('listOrphanVisits')->willReturn(
- VisitsList::forOrphanVisitsTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listOrphanVisits')
+ ->willReturn(
+ VisitsList::forOrphanVisitsTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listOrphanVisits();
}
@@ -313,9 +379,13 @@ public function listOrphanVisitsWithFilterDelegatesCallToProperClient(OrphanVisi
OrphanVisitType::REGULAR_NOT_FOUND => OrphanVisitsFilter::create()->onlyIncludingRegularNotFound(),
};
- $this->visitsClient->expects($this->once())->method('listOrphanVisitsWithFilter')->with(
- $filter,
- )->willReturn(VisitsList::forOrphanVisitsTupleLoader(static fn () => [[], []]));
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listOrphanVisitsWithFilter')
+ ->with(
+ $filter,
+ )
+ ->willReturn(VisitsList::forOrphanVisitsTupleLoader(static fn () => [[], []]));
$this->shlinkClient->listOrphanVisitsWithFilter($filter);
}
@@ -323,9 +393,12 @@ public function listOrphanVisitsWithFilterDelegatesCallToProperClient(OrphanVisi
#[Test]
public function listNonOrphanVisitsDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('listNonOrphanVisits')->willReturn(
- VisitsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listNonOrphanVisits')
+ ->willReturn(
+ VisitsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listNonOrphanVisits();
}
@@ -333,9 +406,13 @@ public function listNonOrphanVisitsDelegatesCallToProperClient(): void
public function listNonOrphanVisitsWithFilterDelegatesCallToProperClient(): void
{
$filter = VisitsFilter::create();
- $this->visitsClient->expects($this->once())->method('listNonOrphanVisitsWithFilter')->with($filter)->willReturn(
- VisitsList::forTupleLoader(static fn () => [[], []]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('listNonOrphanVisitsWithFilter')
+ ->with($filter)
+ ->willReturn(
+ VisitsList::forTupleLoader(static fn () => [[], []]),
+ );
$this->shlinkClient->listNonOrphanVisitsWithFilter($filter);
}
@@ -343,9 +420,12 @@ public function listNonOrphanVisitsWithFilterDelegatesCallToProperClient(): void
#[Test]
public function deleteOrphanVisitsDelegatesCallToProperClient(): void
{
- $this->visitsClient->expects($this->once())->method('deleteOrphanVisits')->willReturn(
- VisitsDeletion::fromArray([]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('deleteOrphanVisits')
+ ->willReturn(
+ VisitsDeletion::fromArray([]),
+ );
$this->shlinkClient->deleteOrphanVisits();
}
@@ -353,9 +433,13 @@ public function deleteOrphanVisitsDelegatesCallToProperClient(): void
public function deleteShortUrlVisitsDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
- $this->visitsClient->expects($this->once())->method('deleteShortUrlVisits')->with($identifier)->willReturn(
- VisitsDeletion::fromArray([]),
- );
+ $this->visitsClient
+ ->expects($this->once())
+ ->method('deleteShortUrlVisits')
+ ->with($identifier)
+ ->willReturn(
+ VisitsDeletion::fromArray([]),
+ );
$this->shlinkClient->deleteShortUrlVisits($identifier);
}
@@ -363,9 +447,13 @@ public function deleteShortUrlVisitsDelegatesCallToProperClient(): void
public function getShortUrlRedirectRulesDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
- $this->redirectRulesClient->expects($this->once())->method('getShortUrlRedirectRules')->with(
- $identifier,
- )->willReturn(RedirectRulesList::fromArray([]));
+ $this->redirectRulesClient
+ ->expects($this->once())
+ ->method('getShortUrlRedirectRules')
+ ->with(
+ $identifier,
+ )
+ ->willReturn(RedirectRulesList::fromArray([]));
$this->shlinkClient->getShortUrlRedirectRules($identifier);
}
@@ -374,10 +462,14 @@ public function setShortUrlRedirectRulesDelegatesCallToProperClient(): void
{
$identifier = ShortUrlIdentifier::fromShortCode('foo');
$rules = SetRedirectRules::fromScratch();
- $this->redirectRulesClient->expects($this->once())->method('setShortUrlRedirectRules')->with(
- $identifier,
- $rules,
- )->willReturn(RedirectRulesList::fromArray([]));
+ $this->redirectRulesClient
+ ->expects($this->once())
+ ->method('setShortUrlRedirectRules')
+ ->with(
+ $identifier,
+ $rules,
+ )
+ ->willReturn(RedirectRulesList::fromArray([]));
$this->shlinkClient->setShortUrlRedirectRules($identifier, $rules);
}
}
diff --git a/test/ShortUrls/Exception/DeleteShortUrlThresholdExceptionTest.php b/test/ShortUrls/Exception/DeleteShortUrlThresholdExceptionTest.php
index f2ea272..882e9eb 100644
--- a/test/ShortUrls/Exception/DeleteShortUrlThresholdExceptionTest.php
+++ b/test/ShortUrls/Exception/DeleteShortUrlThresholdExceptionTest.php
@@ -32,16 +32,28 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), ShortUrlIdentifier::fromShortCode(''), 0, '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- ]), ShortUrlIdentifier::fromShortCode(''), 0, $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- 'shortCode' => $shortCode = 'foo',
- 'domain' => $domain = 's.test',
- 'threshold' => $threshold = 15,
- ]), ShortUrlIdentifier::fromShortCodeAndDomain($shortCode, $domain), $threshold, $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ ]),
+ ShortUrlIdentifier::fromShortCode(''),
+ 0,
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ 'shortCode' => $shortCode = 'foo',
+ 'domain' => $domain = 's.test',
+ 'threshold' => $threshold = 15,
+ ]),
+ ShortUrlIdentifier::fromShortCodeAndDomain($shortCode, $domain),
+ $threshold,
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/ShortUrls/Exception/InvalidLongUrlExceptionTest.php b/test/ShortUrls/Exception/InvalidLongUrlExceptionTest.php
index 3dcc9cb..7dcea70 100644
--- a/test/ShortUrls/Exception/InvalidLongUrlExceptionTest.php
+++ b/test/ShortUrls/Exception/InvalidLongUrlExceptionTest.php
@@ -29,14 +29,24 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), '', '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- ]), '', $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- 'url' => $url = 'https://foo.com/baz',
- ]), $url, $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ ]),
+ '',
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ 'url' => $url = 'https://foo.com/baz',
+ ]),
+ $url,
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/ShortUrls/Exception/NonUniqueSlugExceptionTest.php b/test/ShortUrls/Exception/NonUniqueSlugExceptionTest.php
index cc5e50e..ed81c4b 100644
--- a/test/ShortUrls/Exception/NonUniqueSlugExceptionTest.php
+++ b/test/ShortUrls/Exception/NonUniqueSlugExceptionTest.php
@@ -31,15 +31,27 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), '', null, '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- ]), '', null, $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- 'customSlug' => $customSlug = 'baz',
- 'domain' => $domain = 's.test',
- ]), $customSlug, $domain, $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ ]),
+ '',
+ null,
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ 'customSlug' => $customSlug = 'baz',
+ 'domain' => $domain = 's.test',
+ ]),
+ $customSlug,
+ $domain,
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/ShortUrls/Exception/ShortUrlNotFoundExceptionTest.php b/test/ShortUrls/Exception/ShortUrlNotFoundExceptionTest.php
index 6bcbcb1..693f367 100644
--- a/test/ShortUrls/Exception/ShortUrlNotFoundExceptionTest.php
+++ b/test/ShortUrls/Exception/ShortUrlNotFoundExceptionTest.php
@@ -30,20 +30,35 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), ShortUrlIdentifier::fromShortCode(''), '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- ]), ShortUrlIdentifier::fromShortCode(''), $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- 'shortCode' => $shortCode = 'foo',
- ]), ShortUrlIdentifier::fromShortCode($shortCode), $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- 'shortCode' => $shortCode = 'foo',
- 'domain' => $domain = 's.test',
- ]), ShortUrlIdentifier::fromShortCodeAndDomain($shortCode, $domain), $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ ]),
+ ShortUrlIdentifier::fromShortCode(''),
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ 'shortCode' => $shortCode = 'foo',
+ ]),
+ ShortUrlIdentifier::fromShortCode($shortCode),
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ 'shortCode' => $shortCode = 'foo',
+ 'domain' => $domain = 's.test',
+ ]),
+ ShortUrlIdentifier::fromShortCodeAndDomain($shortCode, $domain),
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/ShortUrls/Model/ShortUrlCreationTest.php b/test/ShortUrls/Model/ShortUrlCreationTest.php
index 21d4e3d..fae20c5 100644
--- a/test/ShortUrls/Model/ShortUrlCreationTest.php
+++ b/test/ShortUrls/Model/ShortUrlCreationTest.php
@@ -26,13 +26,13 @@ public static function provideConfigs(): iterable
{
$date = DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01');
- yield [fn () => ShortUrlCreation::forLongUrl('https://foo.com'), ['longUrl' => 'https://foo.com']];
+ yield [static fn () => ShortUrlCreation::forLongUrl('https://foo.com'), ['longUrl' => 'https://foo.com']];
yield [
- fn () => ShortUrlCreation::forLongUrl('https://foo.com')->returnExistingMatchingShortUrl(),
+ static fn () => ShortUrlCreation::forLongUrl('https://foo.com')->returnExistingMatchingShortUrl(),
['longUrl' => 'https://foo.com', 'findIfExists' => true],
];
yield [
- fn () => ShortUrlCreation::forLongUrl('https://foo.com')
+ static fn () => ShortUrlCreation::forLongUrl('https://foo.com')
->withTags('foo', 'bar')
->validSince($date) // @phpstan-ignore-line
->withCustomSlug('some-slug')
@@ -46,25 +46,25 @@ public static function provideConfigs(): iterable
],
];
yield [
- fn () => ShortUrlCreation::forLongUrl('https://foo.com')
+ static fn () => ShortUrlCreation::forLongUrl('https://foo.com')
->withCustomSlug('some-slug')
->withPathPrefix('my-prefix-')
->withShortCodeLength(50),
['longUrl' => 'https://foo.com', 'pathPrefix' => 'my-prefix-', 'shortCodeLength' => 50],
];
yield [
- fn () => ShortUrlCreation::forLongUrl('https://foo.com')
+ static fn () => ShortUrlCreation::forLongUrl('https://foo.com')
->withShortCodeLength(50)
->withCustomSlug('some-slug')
->withPathPrefix('my-prefix-'),
['longUrl' => 'https://foo.com', 'customSlug' => 'some-slug', 'pathPrefix' => 'my-prefix-'],
];
yield [
- fn () => ShortUrlCreation::forLongUrl('https://foo.com')->crawlable(),
+ static fn () => ShortUrlCreation::forLongUrl('https://foo.com')->crawlable(),
['longUrl' => 'https://foo.com', 'crawlable' => true],
];
yield [
- fn () => ShortUrlCreation::forLongUrl('https://foo.com')
+ static fn () => ShortUrlCreation::forLongUrl('https://foo.com')
->withoutQueryForwardingOnRedirect()
->forDomain('s.test'),
['longUrl' => 'https://foo.com', 'forwardQuery' => false, 'domain' => 's.test'],
diff --git a/test/ShortUrls/Model/ShortUrlEditionTest.php b/test/ShortUrls/Model/ShortUrlEditionTest.php
index 7298716..981ffa3 100644
--- a/test/ShortUrls/Model/ShortUrlEditionTest.php
+++ b/test/ShortUrls/Model/ShortUrlEditionTest.php
@@ -26,9 +26,9 @@ public static function provideConfigs(): iterable
{
$date = DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01');
- yield [fn () => ShortUrlEdition::create(), []];
+ yield [ShortUrlEdition::create(...), []];
yield [
- fn () => ShortUrlEdition::create()
+ static fn () => ShortUrlEdition::create()
->withTags('foo', 'bar')
->validUntil($date) // @phpstan-ignore-line
->withTitle('the title')
@@ -41,13 +41,13 @@ public static function provideConfigs(): iterable
],
];
yield [
- fn () => ShortUrlEdition::create()
+ static fn () => ShortUrlEdition::create()
->withLongUrl('https://edited.com/foo/bar')
->withoutTags(),
['longUrl' => 'https://edited.com/foo/bar', 'tags' => []],
];
yield [
- fn () => ShortUrlEdition::create()
+ static fn () => ShortUrlEdition::create()
->removingValidUntil()
->removingValidSince()
->removingMaxVisits()
diff --git a/test/ShortUrls/Model/ShortUrlMetaTest.php b/test/ShortUrls/Model/ShortUrlMetaTest.php
index 52e3239..1bf7e1d 100644
--- a/test/ShortUrls/Model/ShortUrlMetaTest.php
+++ b/test/ShortUrls/Model/ShortUrlMetaTest.php
@@ -33,10 +33,15 @@ public static function providePayloads(): iterable
$formattedDate = $now->format(DateTimeInterface::ATOM); // @phpstan-ignore-line
yield 'defaults' => [[], null, null, null];
- yield 'all data' => [[
- 'validSince' => $formattedDate,
- 'validUntil' => $formattedDate,
- 'maxVisits' => 35,
- ], $now, $now, 35];
+ yield 'all data' => [
+ [
+ 'validSince' => $formattedDate,
+ 'validUntil' => $formattedDate,
+ 'maxVisits' => 35,
+ ],
+ $now,
+ $now,
+ 35,
+ ];
}
}
diff --git a/test/ShortUrls/Model/ShortUrlTest.php b/test/ShortUrls/Model/ShortUrlTest.php
index 200ec57..ea01994 100644
--- a/test/ShortUrls/Model/ShortUrlTest.php
+++ b/test/ShortUrls/Model/ShortUrlTest.php
@@ -75,14 +75,16 @@ public static function providePayloads(): iterable
'crawlable' => true,
'forwardQuery' => true,
'tags' => ['foo', 'bar'],
- 'meta' => $meta = [
- 'maxVisits' => 30,
- ],
- 'visitsSummary' => $visitsSummary = [
- 'total' => 3,
- 'nonBots' => 3,
- 'bots' => 3,
- ],
+ 'meta' =>
+ $meta = [
+ 'maxVisits' => 30,
+ ],
+ 'visitsSummary' =>
+ $visitsSummary = [
+ 'total' => 3,
+ 'nonBots' => 3,
+ 'bots' => 3,
+ ],
],
'foo',
'https://s.test/foo',
diff --git a/test/ShortUrls/Model/ShortUrlsFilterTest.php b/test/ShortUrls/Model/ShortUrlsFilterTest.php
index 07d6c7d..9d68e7f 100644
--- a/test/ShortUrls/Model/ShortUrlsFilterTest.php
+++ b/test/ShortUrls/Model/ShortUrlsFilterTest.php
@@ -27,44 +27,44 @@ public static function providePayloads(): iterable
{
$date = new DateTimeImmutable();
- yield [fn () => ShortUrlsFilter::create(), []];
+ yield [ShortUrlsFilter::create(...), []];
yield [
- fn () => ShortUrlsFilter::create()
+ static fn () => ShortUrlsFilter::create()
->since($date)
->until($date),
['startDate' => $formatted = $date->format(DateTimeInterface::ATOM), 'endDate' => $formatted],
];
yield [
- fn () => ShortUrlsFilter::create()
+ static fn () => ShortUrlsFilter::create()
->containingSomeTags('foo', 'bar')
->searchingBy('searching'),
['tags' => ['foo', 'bar'], 'tagsMode' => 'any', 'searchTerm' => 'searching'],
];
yield [
- fn () => ShortUrlsFilter::create()->containingAllTags('foo', 'bar'),
+ static fn () => ShortUrlsFilter::create()->containingAllTags('foo', 'bar'),
['tags' => ['foo', 'bar'], 'tagsMode' => 'all'],
];
yield [
- fn () => ShortUrlsFilter::create()->orderingAscBy(ShortUrlListOrderField::VISITS),
+ static fn () => ShortUrlsFilter::create()->orderingAscBy(ShortUrlListOrderField::VISITS),
['orderBy' => 'visits-ASC'],
];
yield [
- fn () => ShortUrlsFilter::create()->orderingDescBy(ShortUrlListOrderField::LONG_URL),
+ static fn () => ShortUrlsFilter::create()->orderingDescBy(ShortUrlListOrderField::LONG_URL),
['orderBy' => 'longUrl-DESC'],
];
yield [
- fn () => ShortUrlsFilter::create()->excludingMaxVisitsReached()->excludingPastValidUntil(),
+ static fn () => ShortUrlsFilter::create()->excludingMaxVisitsReached()->excludingPastValidUntil(),
['excludeMaxVisitsReached' => 'true', 'excludePastValidUntil' => 'true'],
];
- yield [fn () => ShortUrlsFilter::create()->forDomain('s.test'), ['domain' => 's.test']];
+ yield [static fn () => ShortUrlsFilter::create()->forDomain('s.test'), ['domain' => 's.test']];
yield [
- fn () => ShortUrlsFilter::create()->notContainingSomeTags('foo', 'bar', 'baz'),
+ static fn () => ShortUrlsFilter::create()->notContainingSomeTags('foo', 'bar', 'baz'),
['excludeTags' => ['foo', 'bar', 'baz'], 'excludeTagsMode' => 'any'],
];
yield [
- fn () => ShortUrlsFilter::create()->notContainingAnyTags('foo', 'bar', 'baz'),
+ static fn () => ShortUrlsFilter::create()->notContainingAnyTags('foo', 'bar', 'baz'),
['excludeTags' => ['foo', 'bar', 'baz'], 'excludeTagsMode' => 'all'],
];
- yield [fn () => ShortUrlsFilter::create()->createdWithApiKey('foo'), ['apiKeyName' => 'foo']];
+ yield [static fn () => ShortUrlsFilter::create()->createdWithApiKey('foo'), ['apiKeyName' => 'foo']];
}
}
diff --git a/test/ShortUrls/ShortUrlsClientTest.php b/test/ShortUrls/ShortUrlsClientTest.php
index 4169971..aacc7f6 100644
--- a/test/ShortUrls/ShortUrlsClientTest.php
+++ b/test/ShortUrls/ShortUrlsClientTest.php
@@ -30,15 +30,14 @@
class ShortUrlsClientTest extends TestCase
{
private ShortUrlsClient $client;
- private MockObject & HttpClientInterface $httpClient;
+ private MockObject&HttpClientInterface $httpClient;
private string $now;
public function setUp(): void
{
$this->httpClient = $this->createMock(HttpClientInterface::class);
$this->client = new ShortUrlsClient($this->httpClient);
- $this->now = (new DateTimeImmutable())->format(DateTimeInterface::ATOM);
- ;
+ $this->now = new DateTimeImmutable()->format(DateTimeInterface::ATOM);
}
#[Test]
@@ -47,37 +46,41 @@ public function listShortUrlVisitsPerformsExpectedCall(): void
$amountOfPages = 3;
$now = $this->now;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/short-urls',
- $this->anything(),
- )->willReturnCallback(
- function ($_, array $query) use ($amountOfPages, $now) {
- $page = $query['page'];
- $data = [
- [
- 'shortCode' => 'shortCode_' . $page . '_1',
- 'longUrl' => 'longUrl_' . $page . '_1',
- 'dateCreated' => $now,
- ],
- [
- 'shortCode' => 'shortCode_' . $page . '_2',
- 'longUrl' => 'longUrl_' . $page . '_2',
- 'dateCreated' => $now,
- ],
- ];
-
- return [
- 'shortUrls' => [
- 'data' => $data,
- 'pagination' => [
- 'currentPage' => $page,
- 'pagesCount' => $amountOfPages,
- 'totalItems' => $amountOfPages * count($data),
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/short-urls',
+ $this->anything(),
+ )
+ ->willReturnCallback(
+ static function ($_, array $query) use ($amountOfPages, $now) {
+ $page = $query['page'];
+ $data = [
+ [
+ 'shortCode' => 'shortCode_' . $page . '_1',
+ 'longUrl' => 'longUrl_' . $page . '_1',
+ 'dateCreated' => $now,
],
- ],
- ];
- },
- );
+ [
+ 'shortCode' => 'shortCode_' . $page . '_2',
+ 'longUrl' => 'longUrl_' . $page . '_2',
+ 'dateCreated' => $now,
+ ],
+ ];
+
+ return [
+ 'shortUrls' => [
+ 'data' => $data,
+ 'pagination' => [
+ 'currentPage' => $page,
+ 'pagesCount' => $amountOfPages,
+ 'totalItems' => $amountOfPages * count($data),
+ ],
+ ],
+ ];
+ },
+ );
$result = $this->client->listShortUrls();
@@ -88,8 +91,8 @@ function ($_, array $query) use ($amountOfPages, $now) {
$count++;
self::assertStringStartsWith('shortCode_', $shortUrl->shortCode);
self::assertStringStartsWith('longUrl_', $shortUrl->longUrl);
- self::assertStringEndsWith($index % 2 === 0 ? '_1' : '_2', $shortUrl->shortCode);
- self::assertStringEndsWith($index % 2 === 0 ? '_1' : '_2', $shortUrl->longUrl);
+ self::assertStringEndsWith(($index % 2) === 0 ? '_1' : '_2', $shortUrl->shortCode);
+ self::assertStringEndsWith(($index % 2) === 0 ? '_1' : '_2', $shortUrl->longUrl);
self::assertStringStartsWith($shortUrl->dateCreated->format('Y-m-d'), $now);
}
@@ -100,10 +103,14 @@ function ($_, array $query) use ($amountOfPages, $now) {
public function getShortUrlPerformsExpectedCall(ShortUrlIdentifier $identifier): void
{
$expected = ['dateCreated' => $this->now];
- $this->httpClient->expects($this->once())->method('getFromShlink')->with(
- sprintf('/short-urls/%s', $identifier->shortCode),
- $this->callback(fn (array $query): bool => ($query['domain'] ?? null) === $identifier->domain),
- )->willReturn($expected);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('getFromShlink')
+ ->with(
+ sprintf('/short-urls/%s', $identifier->shortCode),
+ $this->callback(static fn (array $query): bool => ($query['domain'] ?? null) === $identifier->domain),
+ )
+ ->willReturn($expected);
$result = $this->client->getShortUrl($identifier);
@@ -113,12 +120,15 @@ public function getShortUrlPerformsExpectedCall(ShortUrlIdentifier $identifier):
#[Test, DataProvider('provideIdentifiers')]
public function deleteShortUrlPerformsExpectedCall(ShortUrlIdentifier $identifier): void
{
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- sprintf('/short-urls/%s', $identifier->shortCode),
- 'DELETE',
- [],
- $this->callback(fn (array $query): bool => ($query['domain'] ?? null) === $identifier->domain),
- );
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ sprintf('/short-urls/%s', $identifier->shortCode),
+ 'DELETE',
+ [],
+ $this->callback(static fn (array $query): bool => ($query['domain'] ?? null) === $identifier->domain),
+ );
$this->client->deleteShortUrl($identifier);
}
@@ -128,12 +138,16 @@ public function editShortUrlPerformsExpectedCall(ShortUrlIdentifier $identifier)
{
$expected = ['dateCreated' => $this->now];
$edit = ShortUrlEdition::create();
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- sprintf('/short-urls/%s', $identifier->shortCode),
- 'PATCH',
- $edit,
- $this->callback(fn (array $query): bool => ($query['domain'] ?? null) === $identifier->domain),
- )->willReturn($expected);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ sprintf('/short-urls/%s', $identifier->shortCode),
+ 'PATCH',
+ $edit,
+ $this->callback(static fn (array $query): bool => ($query['domain'] ?? null) === $identifier->domain),
+ )
+ ->willReturn($expected);
$result = $this->client->editShortUrl($identifier, $edit);
@@ -151,11 +165,15 @@ public function createShortUrlPerformsExpectedCall(): void
{
$expected = ['dateCreated' => $this->now];
$create = ShortUrlCreation::forLongUrl('https://foo.com');
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- '/short-urls',
- 'POST',
- $create,
- )->willReturn($expected);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ '/short-urls',
+ 'POST',
+ $create,
+ )
+ ->willReturn($expected);
$result = $this->client->createShortUrl($create);
@@ -177,8 +195,8 @@ public function getShortUrlThrowsProperExceptionOnError(HttpException $original,
public static function provideGetExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_SHORTCODE' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_SHORTCODE' => [
HttpException::fromPayload(['type' => ErrorType::SHORT_URL_NOT_FOUND->value]),
ShortUrlNotFoundException::class,
];
@@ -199,12 +217,12 @@ public function deleteShortUrlThrowsProperExceptionOnError(HttpException $origin
public static function provideDeleteExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_SHORTCODE' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_SHORTCODE' => [
HttpException::fromPayload(['type' => ErrorType::SHORT_URL_NOT_FOUND->value]),
ShortUrlNotFoundException::class,
];
- yield 'INVALID_SHORT_URL_DELETION' => [
+ yield 'INVALID_SHORT_URL_DELETION' => [
HttpException::fromPayload(['type' => ErrorType::INVALID_SHORT_URL_DELETION->value]),
DeleteShortUrlThresholdException::class,
];
@@ -225,12 +243,12 @@ public function createShortUrlThrowsProperExceptionOnError(HttpException $origin
public static function provideCreateExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_ARGUMENT' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_ARGUMENT' => [
HttpException::fromPayload(['type' => ErrorType::INVALID_DATA->value]),
InvalidDataException::class,
];
- yield 'INVALID_SLUG' => [
+ yield 'INVALID_SLUG' => [
HttpException::fromPayload(['type' => ErrorType::NON_UNIQUE_SLUG->value]),
NonUniqueSlugException::class,
];
@@ -251,8 +269,8 @@ public function editShortUrlThrowsProperExceptionOnError(HttpException $original
public static function provideEditExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_SHORTCODE' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_SHORTCODE' => [
HttpException::fromPayload(['type' => ErrorType::SHORT_URL_NOT_FOUND->value]),
ShortUrlNotFoundException::class,
];
diff --git a/test/Tags/Exception/ForbiddenTagOperationExceptionTest.php b/test/Tags/Exception/ForbiddenTagOperationExceptionTest.php
index d18b02c..b8f74fa 100644
--- a/test/Tags/Exception/ForbiddenTagOperationExceptionTest.php
+++ b/test/Tags/Exception/ForbiddenTagOperationExceptionTest.php
@@ -24,9 +24,13 @@ public function exceptionIsProperlyCreated(HttpException $prev, string $expected
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- ]), $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ ]),
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/Tags/Exception/TagConflictExceptionTest.php b/test/Tags/Exception/TagConflictExceptionTest.php
index f4029af..9bb0a3c 100644
--- a/test/Tags/Exception/TagConflictExceptionTest.php
+++ b/test/Tags/Exception/TagConflictExceptionTest.php
@@ -31,15 +31,27 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), '', '', '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- ]), '', '', $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 409,
- 'oldName' => $oldName = 'old',
- 'newName' => $newName = 'new',
- ]), $oldName, $newName, $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ ]),
+ '',
+ '',
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 409,
+ 'oldName' => $oldName = 'old',
+ 'newName' => $newName = 'new',
+ ]),
+ $oldName,
+ $newName,
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/Tags/Exception/TagNotFoundExceptionTest.php b/test/Tags/Exception/TagNotFoundExceptionTest.php
index 541a7d1..a89ab6f 100644
--- a/test/Tags/Exception/TagNotFoundExceptionTest.php
+++ b/test/Tags/Exception/TagNotFoundExceptionTest.php
@@ -29,14 +29,24 @@ public function exceptionIsProperlyCreated(
public static function provideExceptions(): iterable
{
yield [HttpException::fromPayload([]), '', '', -1];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 400,
- ]), '', $message, $code];
- yield [HttpException::fromPayload([
- 'detail' => $message = 'This is the message',
- 'status' => $code = 404,
- 'tag' => $tag = 'foo',
- ]), $tag, $message, $code];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 400,
+ ]),
+ '',
+ $message,
+ $code,
+ ];
+ yield [
+ HttpException::fromPayload([
+ 'detail' => $message = 'This is the message',
+ 'status' => $code = 404,
+ 'tag' => $tag = 'foo',
+ ]),
+ $tag,
+ $message,
+ $code,
+ ];
}
}
diff --git a/test/Tags/Model/TagsFilterTest.php b/test/Tags/Model/TagsFilterTest.php
index 8a14076..18c5ab3 100644
--- a/test/Tags/Model/TagsFilterTest.php
+++ b/test/Tags/Model/TagsFilterTest.php
@@ -24,33 +24,35 @@ public function requiresPaginationBasedOnTheOrderingFields(callable $buildFilter
public static function provideOrderings(): iterable
{
- yield 'no order' => [fn () => TagsFilter::create(), true];
- yield 'tag ASC' => [fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::TAG), true];
- yield 'tag DESC' => [fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::TAG), true];
+ yield 'no order' => [TagsFilter::create(...), true];
+ yield 'tag ASC' => [static fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::TAG), true];
+ yield 'tag DESC' => [static fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::TAG), true];
yield 'shortUrlsCount ASC' => [
- fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::SHORT_URLS_COUNT),
+ static fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::SHORT_URLS_COUNT),
false,
];
yield 'shortUrlsCount DESC' => [
- fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::SHORT_URLS_COUNT),
+ static fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::SHORT_URLS_COUNT),
false,
];
yield 'visitsCount ASC' => [
- fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::VISITS_COUNT),
+ static fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::VISITS_COUNT),
false,
];
yield 'visitsCount DESC' => [
- fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::VISITS_COUNT),
+ static fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::VISITS_COUNT),
false,
];
yield 'override towards paginable' => [
- fn () => TagsFilter::create()->orderingAscBy(TagsListOrderField::SHORT_URLS_COUNT)
- ->orderingDescBy(TagsListOrderField::TAG),
+ static fn () => TagsFilter::create()
+ ->orderingAscBy(TagsListOrderField::SHORT_URLS_COUNT)
+ ->orderingDescBy(TagsListOrderField::TAG),
true,
];
yield 'override towards non-paginable' => [
- fn () => TagsFilter::create()->orderingDescBy(TagsListOrderField::TAG)
- ->orderingAscBy(TagsListOrderField::VISITS_COUNT),
+ static fn () => TagsFilter::create()
+ ->orderingDescBy(TagsListOrderField::TAG)
+ ->orderingAscBy(TagsListOrderField::VISITS_COUNT),
false,
];
}
diff --git a/test/Tags/TagsClientTest.php b/test/Tags/TagsClientTest.php
index 35cfd15..fb86363 100644
--- a/test/Tags/TagsClientTest.php
+++ b/test/Tags/TagsClientTest.php
@@ -28,7 +28,7 @@
class TagsClientTest extends TestCase
{
private TagsClient $tagsClient;
- private MockObject & HttpClientInterface $httpClient;
+ private MockObject&HttpClientInterface $httpClient;
public function setUp(): void
{
@@ -63,26 +63,29 @@ public function listTagsWithStatsReturnsExpectedResponse(): void
$this->assertListTags(
['/tags/stats', $this->isArray()],
[[], [], [], [], []],
- fn (): array => array_map(fn () => [], [...$this->tagsClient->listTagsWithStats()]),
+ fn (): array => array_map(static fn () => [], [...$this->tagsClient->listTagsWithStats()]),
);
}
#[Test]
public function listTagsWithStatsReturnsExpectedVisitsCount(): void
{
- $this->httpClient->expects($this->once())->method('getFromShlink')->willReturn([
- 'tags' => [
- 'data' => [[
- 'tag' => 'foo',
- 'shortUrlsCount' => 1,
- 'visitsSummary' => [
- 'total' => 3,
- 'nonBots' => 2,
- 'bots' => 1,
- ],
- ]],
- ],
- ]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('getFromShlink')
+ ->willReturn([
+ 'tags' => [
+ 'data' => [[
+ 'tag' => 'foo',
+ 'shortUrlsCount' => 1,
+ 'visitsSummary' => [
+ 'total' => 3,
+ 'nonBots' => 2,
+ 'bots' => 1,
+ ],
+ ]],
+ ],
+ ]);
$list = $this->tagsClient->listTagsWithStats();
@@ -100,26 +103,33 @@ public function listTagsWithStatsWithFilterReturnsExpectedResponse(): void
{
$filter = TagsFilter::create()->searchingBy('foo')->orderingAscBy(TagsListOrderField::TAG);
$this->assertListTags(
- ['/tags/stats', $this->callback(function (array $arg) use ($filter) {
- $filterArray = $filter->toArray();
- foreach ($filterArray as $key => $expectedValue) {
- Assert::assertEquals($expectedValue, $arg[$key]);
- }
-
- return true;
- })],
+ [
+ '/tags/stats',
+ $this->callback(static function (array $arg) use ($filter) {
+ $filterArray = $filter->toArray();
+ foreach ($filterArray as $key => $expectedValue) {
+ Assert::assertEquals($expectedValue, $arg[$key]);
+ }
+
+ return true;
+ }),
+ ],
[[], [], [], [], []],
- fn (): array => array_map(fn () => [], [...$this->tagsClient->listTagsWithStatsWithFilter($filter)]),
+ fn (): array => array_map(static fn () => [], [...$this->tagsClient->listTagsWithStatsWithFilter($filter)]),
);
}
private function assertListTags(array $expectedArgs, array $expectedData, callable $listTags): void
{
- $this->httpClient->expects($this->once())->method('getFromShlink')->with(...$expectedArgs)->willReturn([
- 'tags' => [
- 'data' => $expectedData,
- ],
- ]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('getFromShlink')
+ ->with(...$expectedArgs)
+ ->willReturn([
+ 'tags' => [
+ 'data' => $expectedData,
+ ],
+ ]);
$result = $listTags();
@@ -150,20 +160,20 @@ public function renameTagThrowsProperExceptionOnError(HttpException $original, s
public static function provideRenameExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_ARGUMENT' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_ARGUMENT' => [
HttpException::fromPayload(['type' => ErrorType::INVALID_DATA->value]),
InvalidDataException::class,
];
- yield 'FORBIDDEN_OPERATION' => [
+ yield 'FORBIDDEN_OPERATION' => [
HttpException::fromPayload(['type' => ErrorType::FORBIDDEN_TAG_OPERATION->value]),
ForbiddenTagOperationException::class,
];
- yield 'TAG_NOT_FOUND' => [
+ yield 'TAG_NOT_FOUND' => [
HttpException::fromPayload(['type' => ErrorType::TAG_NOT_FOUND->value]),
TagNotFoundException::class,
];
- yield 'TAG_CONFLICT' => [
+ yield 'TAG_CONFLICT' => [
HttpException::fromPayload(['type' => ErrorType::TAG_CONFLICT->value]),
TagConflictException::class,
];
@@ -173,12 +183,15 @@ public static function provideRenameExceptions(): iterable
public function deleteTagsCallsApi(): void
{
$tags = ['foo', 'bar', 'baz'];
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- '/tags',
- 'DELETE',
- [],
- ['tags' => $tags],
- );
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ '/tags',
+ 'DELETE',
+ [],
+ ['tags' => $tags],
+ );
$this->tagsClient->deleteTags(...$tags);
}
@@ -198,8 +211,8 @@ public function deleteTagsThrowsProperExceptionOnError(HttpException $original,
public static function provideDeleteExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'FORBIDDEN_OPERATION' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'FORBIDDEN_OPERATION' => [
HttpException::fromPayload(['type' => ErrorType::FORBIDDEN_TAG_OPERATION->value]),
ForbiddenTagOperationException::class,
];
diff --git a/test/Visits/Model/OrphanVisitTest.php b/test/Visits/Model/OrphanVisitTest.php
index 626e909..2ad625c 100644
--- a/test/Visits/Model/OrphanVisitTest.php
+++ b/test/Visits/Model/OrphanVisitTest.php
@@ -42,9 +42,18 @@ public static function providePayloads(): iterable
$now = DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01');
$formattedDate = $now->format(DateTimeInterface::ATOM); // @phpstan-ignore-line
- yield 'defaults' => [[
- 'date' => $formattedDate,
- ], '', $now, '', false, null, '', OrphanVisitType::REGULAR_NOT_FOUND];
+ yield 'defaults' => [
+ [
+ 'date' => $formattedDate,
+ ],
+ '',
+ $now,
+ '',
+ false,
+ null,
+ '',
+ OrphanVisitType::REGULAR_NOT_FOUND,
+ ];
yield 'all data' => [
[
'referer' => 'referer',
diff --git a/test/Visits/Model/VisitsFilterTest.php b/test/Visits/Model/VisitsFilterTest.php
index 64daf93..623cbe0 100644
--- a/test/Visits/Model/VisitsFilterTest.php
+++ b/test/Visits/Model/VisitsFilterTest.php
@@ -25,11 +25,14 @@ public static function providePayloads(): iterable
{
$now = new DateTimeImmutable();
- yield [fn () => VisitsFilter::create(), []];
- yield [fn () => VisitsFilter::create()->since($now), ['startDate' => $now->format(DateTimeInterface::ATOM)]];
- yield [fn () => VisitsFilter::create()->excludingBots(), ['excludeBots' => 'true']];
+ yield [VisitsFilter::create(...), []];
yield [
- fn () => VisitsFilter::create()
+ static fn () => VisitsFilter::create()->since($now),
+ ['startDate' => $now->format(DateTimeInterface::ATOM)],
+ ];
+ yield [static fn () => VisitsFilter::create()->excludingBots(), ['excludeBots' => 'true']];
+ yield [
+ static fn () => VisitsFilter::create()
->excludingBots()
->since($now)
->until($now),
diff --git a/test/Visits/VisitsClientTest.php b/test/Visits/VisitsClientTest.php
index a65b81d..244a0f0 100644
--- a/test/Visits/VisitsClientTest.php
+++ b/test/Visits/VisitsClientTest.php
@@ -33,33 +33,37 @@
class VisitsClientTest extends TestCase
{
private VisitsClient $visitsClient;
- private MockObject & HttpClientInterface $httpClient;
+ private MockObject&HttpClientInterface $httpClient;
private string $now;
public function setUp(): void
{
$this->httpClient = $this->createMock(HttpClientInterface::class);
$this->visitsClient = new VisitsClient($this->httpClient);
- $this->now = (new DateTimeImmutable())->format(DateTimeInterface::ATOM);
+ $this->now = new DateTimeImmutable()->format(DateTimeInterface::ATOM);
}
#[Test]
public function getVisitsOverviewPerformsExpectedCall(): void
{
- $this->httpClient->expects($this->once())->method('getFromShlink')->with('/visits')->willReturn([
- 'visits' => [
- 'nonOrphanVisits' => [
- 'total' => 200,
- 'nonBots' => 150,
- 'bots' => 50,
- ],
- 'orphanVisits' => [
- 'total' => 38,
- 'nonBots' => 30,
- 'bots' => 8,
+ $this->httpClient
+ ->expects($this->once())
+ ->method('getFromShlink')
+ ->with('/visits')
+ ->willReturn([
+ 'visits' => [
+ 'nonOrphanVisits' => [
+ 'total' => 200,
+ 'nonBots' => 150,
+ 'bots' => 50,
+ ],
+ 'orphanVisits' => [
+ 'total' => 38,
+ 'nonBots' => 30,
+ 'bots' => 8,
+ ],
],
- ],
- ]);
+ ]);
$result = $this->visitsClient->getVisitsOverview();
@@ -77,13 +81,17 @@ public function listShortUrlVisitsPerformsExpectedCall(ShortUrlIdentifier $ident
{
$amountOfPages = 3;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- sprintf('/short-urls/%s/visits', $identifier->shortCode),
- $this->callback(function (array $query) use ($identifier) {
- $domain = $identifier->domain;
- return $domain === null ? ! array_key_exists('domain', $query) : $query['domain'] === $domain;
- }),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ sprintf('/short-urls/%s/visits', $identifier->shortCode),
+ $this->callback(static function (array $query) use ($identifier) {
+ $domain = $identifier->domain;
+ return $domain === null ? !array_key_exists('domain', $query) : $query['domain'] === $domain;
+ }),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listShortUrlVisits($identifier);
@@ -111,8 +119,8 @@ public function listShortUrlVisitsThrowsProperExceptionOnError(HttpException $or
public static function provideShortUrlExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'INVALID_SHORTCODE' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'INVALID_SHORTCODE' => [
HttpException::fromPayload(['type' => ErrorType::SHORT_URL_NOT_FOUND->value]),
ShortUrlNotFoundException::class,
];
@@ -122,10 +130,14 @@ public static function provideShortUrlExceptions(): iterable
public function listTagVisitsPerformsExpectedCall(): void
{
$amountOfPages = 5;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/tags/foo/visits',
- $this->anything(),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/tags/foo/visits',
+ $this->anything(),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listTagVisits('foo');
@@ -147,8 +159,8 @@ public function listTagVisitsThrowsProperExceptionOnError(HttpException $origina
public static function provideTagExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'TAG_NOT_FOUND' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'TAG_NOT_FOUND' => [
HttpException::fromPayload(['type' => ErrorType::TAG_NOT_FOUND->value]),
TagNotFoundException::class,
];
@@ -158,10 +170,14 @@ public static function provideTagExceptions(): iterable
public function listDomainVisitsPerformsExpectedCall(): void
{
$amountOfPages = 5;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/domains/foo.com/visits',
- $this->anything(),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/domains/foo.com/visits',
+ $this->anything(),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listDomainVisits('foo.com');
@@ -172,10 +188,14 @@ public function listDomainVisitsPerformsExpectedCall(): void
public function listDefaultDomainVisitsPerformsExpectedCall(): void
{
$amountOfPages = 5;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/domains/DEFAULT/visits',
- $this->anything(),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/domains/DEFAULT/visits',
+ $this->anything(),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listDefaultDomainVisits();
@@ -209,8 +229,8 @@ public function listDefaultDomainVisitsThrowsProperExceptionOnError(HttpExceptio
public static function provideDomainExceptions(): iterable
{
yield 'no type' => [HttpException::fromPayload([]), HttpException::class];
- yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
- yield 'DOMAIN_NOT_FOUND' => [
+ yield 'not expected type' => [HttpException::fromPayload(['type' => 'something else']), HttpException::class];
+ yield 'DOMAIN_NOT_FOUND' => [
HttpException::fromPayload(['type' => ErrorType::DOMAIN_NOT_FOUND->value]),
DomainNotFoundException::class,
];
@@ -220,10 +240,14 @@ public static function provideDomainExceptions(): iterable
public function listOrphanVisitsPerformsExpectedCall(): void
{
$amountOfPages = 1;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/visits/orphan',
- $this->anything(),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/visits/orphan',
+ $this->anything(),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listOrphanVisits();
@@ -246,13 +270,18 @@ public function listOrphanVisitsWithFilterPerformsExpectedCall(OrphanVisitType|n
$amountOfPages = 1;
$rawType = $visitsFilter->toArray()['type'] ?? null;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/visits/orphan',
- $this->callback(
- fn (array $query)
- => $rawType === null ? ! array_key_exists('type', $query) : $query['type'] === $rawType,
- ),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/visits/orphan',
+ $this->callback(
+ static fn (array $query) => $rawType === null
+ ? !array_key_exists('type', $query)
+ : $query['type'] === $rawType,
+ ),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listOrphanVisitsWithFilter($visitsFilter);
@@ -263,10 +292,14 @@ public function listOrphanVisitsWithFilterPerformsExpectedCall(OrphanVisitType|n
public function listNonOrphanVisitsPerformsExpectedCall(): void
{
$amountOfPages = 1;
- $this->httpClient->expects($this->exactly($amountOfPages))->method('getFromShlink')->with(
- '/visits/non-orphan',
- $this->anything(),
- )->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
+ $this->httpClient
+ ->expects($this->exactly($amountOfPages))
+ ->method('getFromShlink')
+ ->with(
+ '/visits/non-orphan',
+ $this->anything(),
+ )
+ ->willReturnCallback($this->buildPaginationImplementation($amountOfPages));
$result = $this->visitsClient->listNonOrphanVisits();
@@ -286,8 +319,8 @@ private function assertPaginator(VisitsList $result, int $amountOfPages): void
$count++;
self::assertStringStartsWith('referer_', $visit->referer());
self::assertStringStartsWith('userAgent_', $visit->userAgent());
- self::assertStringEndsWith($index % 2 === 0 ? '_1' : '_2', $visit->referer());
- self::assertStringEndsWith($index % 2 === 0 ? '_1' : '_2', $visit->userAgent());
+ self::assertStringEndsWith(($index % 2) === 0 ? '_1' : '_2', $visit->referer());
+ self::assertStringEndsWith(($index % 2) === 0 ? '_1' : '_2', $visit->userAgent());
self::assertStringStartsWith($visit->date()->format('Y-m-d'), $this->now);
}
@@ -297,7 +330,7 @@ private function assertPaginator(VisitsList $result, int $amountOfPages): void
private function buildPaginationImplementation(int $amountOfPages): Closure
{
$now = $this->now;
- return function ($_, array $query) use ($amountOfPages, $now) {
+ return static function ($_, array $query) use ($amountOfPages, $now) {
$page = $query['page'];
$data = [
[
@@ -328,11 +361,15 @@ private function buildPaginationImplementation(int $amountOfPages): Closure
#[Test]
public function deleteOrphanVisitsPerformsExpectedCall(): void
{
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- '/visits/orphan',
- 'DELETE',
- [],
- )->willReturn(['deletedVisits' => 5562]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ '/visits/orphan',
+ 'DELETE',
+ [],
+ )
+ ->willReturn(['deletedVisits' => 5562]);
$result = $this->visitsClient->deleteOrphanVisits();
@@ -344,11 +381,15 @@ public function deleteOrphanVisitsPerformsExpectedCall(): void
public function deleteShortUrlVisitsPerformsExpectedCall(ShortUrlIdentifier $identifier): void
{
[$shortCode, $query] = $identifier->toShortCodeAndQuery();
- $this->httpClient->expects($this->once())->method('callShlinkWithBody')->with(
- sprintf('/short-urls/%s/visits', $shortCode),
- 'DELETE',
- $query,
- )->willReturn(['deletedVisits' => 5562]);
+ $this->httpClient
+ ->expects($this->once())
+ ->method('callShlinkWithBody')
+ ->with(
+ sprintf('/short-urls/%s/visits', $shortCode),
+ 'DELETE',
+ $query,
+ )
+ ->willReturn(['deletedVisits' => 5562]);
$result = $this->visitsClient->deleteShortUrlVisits($identifier);