mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-24 09:50:17 -06:00
Update to PHPUnit 10
This commit is contained in:
parent
ad44a8441a
commit
650a286982
@ -20,63 +20,62 @@
|
|||||||
"akrabat/ip-address-middleware": "^2.1",
|
"akrabat/ip-address-middleware": "^2.1",
|
||||||
"cakephp/chronos": "^2.3",
|
"cakephp/chronos": "^2.3",
|
||||||
"doctrine/migrations": "^3.5",
|
"doctrine/migrations": "^3.5",
|
||||||
"doctrine/orm": "^2.13.3",
|
"doctrine/orm": "^2.14",
|
||||||
"endroid/qr-code": "^4.6",
|
"endroid/qr-code": "^4.7",
|
||||||
"geoip2/geoip2": "^2.13",
|
"geoip2/geoip2": "^2.13",
|
||||||
"guzzlehttp/guzzle": "^7.5",
|
"guzzlehttp/guzzle": "^7.5",
|
||||||
"happyr/doctrine-specification": "^2.0",
|
"happyr/doctrine-specification": "^2.0",
|
||||||
"jaybizzle/crawler-detect": "^1.2.112",
|
"jaybizzle/crawler-detect": "^1.2.112",
|
||||||
"laminas/laminas-config": "^3.7",
|
"laminas/laminas-config": "^3.8",
|
||||||
"laminas/laminas-config-aggregator": "^1.11",
|
"laminas/laminas-config-aggregator": "^1.13",
|
||||||
"laminas/laminas-diactoros": "^2.19",
|
"laminas/laminas-diactoros": "^2.24",
|
||||||
"laminas/laminas-inputfilter": "^2.22",
|
"laminas/laminas-inputfilter": "^2.24",
|
||||||
"laminas/laminas-servicemanager": "^3.19",
|
"laminas/laminas-servicemanager": "^3.20",
|
||||||
"laminas/laminas-stdlib": "^3.15",
|
"laminas/laminas-stdlib": "^3.16",
|
||||||
"lcobucci/jwt": "^4.2",
|
"lcobucci/jwt": "^4.3",
|
||||||
"league/uri": "^6.8",
|
"league/uri": "^6.8",
|
||||||
"lstrojny/functional-php": "^1.17",
|
"lstrojny/functional-php": "^1.17",
|
||||||
"mezzio/mezzio": "^3.13",
|
"mezzio/mezzio": "^3.15",
|
||||||
"mezzio/mezzio-fastroute": "^3.7",
|
"mezzio/mezzio-fastroute": "^3.8",
|
||||||
"mezzio/mezzio-problem-details": "^1.7",
|
"mezzio/mezzio-problem-details": "^1.11",
|
||||||
"mezzio/mezzio-swoole": "^4.5",
|
"mezzio/mezzio-swoole": "^4.6",
|
||||||
"mlocati/ip-lib": "^1.18",
|
"mlocati/ip-lib": "^1.18",
|
||||||
"mobiledetect/mobiledetectlib": "^3.74",
|
"mobiledetect/mobiledetectlib": "^3.74",
|
||||||
"ocramius/proxy-manager": "^2.14",
|
"ocramius/proxy-manager": "^2.14",
|
||||||
"pagerfanta/core": "^3.6",
|
"pagerfanta/core": "^3.7",
|
||||||
"php-middleware/request-id": "^4.1",
|
"php-middleware/request-id": "^4.1",
|
||||||
"pugx/shortid-php": "^1.1",
|
"pugx/shortid-php": "^1.1",
|
||||||
"ramsey/uuid": "^4.5",
|
"ramsey/uuid": "^4.7",
|
||||||
"shlinkio/shlink-common": "^5.3.1",
|
"shlinkio/shlink-common": "^5.3.1",
|
||||||
"shlinkio/shlink-config": "^2.4",
|
"shlinkio/shlink-config": "^2.4",
|
||||||
"shlinkio/shlink-event-dispatcher": "^2.6",
|
"shlinkio/shlink-event-dispatcher": "^2.6",
|
||||||
"shlinkio/shlink-importer": "^5.0",
|
"shlinkio/shlink-importer": "^5.0",
|
||||||
"shlinkio/shlink-installer": "^8.3",
|
"shlinkio/shlink-installer": "^8.3",
|
||||||
"shlinkio/shlink-ip-geolocation": "^3.2",
|
"shlinkio/shlink-ip-geolocation": "^3.2",
|
||||||
"spiral/roadrunner": "^2.11",
|
"spiral/roadrunner": "^2.12",
|
||||||
"spiral/roadrunner-jobs": "^2.5",
|
"spiral/roadrunner-jobs": "^2.7",
|
||||||
"symfony/console": "^6.1",
|
"symfony/console": "^6.2",
|
||||||
"symfony/filesystem": "^6.1",
|
"symfony/filesystem": "^6.2",
|
||||||
"symfony/lock": "^6.1",
|
"symfony/lock": "^6.2",
|
||||||
"symfony/process": "^6.1",
|
"symfony/process": "^6.2",
|
||||||
"symfony/string": "^6.1"
|
"symfony/string": "^6.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"cebe/php-openapi": "^1.7",
|
"cebe/php-openapi": "^1.7",
|
||||||
"devster/ubench": "^2.1",
|
"devster/ubench": "^2.1",
|
||||||
"dms/phpunit-arraysubset-asserts": "^0.4.0",
|
"infection/infection": "^0.26.19",
|
||||||
"infection/infection": "^0.26.15",
|
|
||||||
"openswoole/ide-helper": "~4.11.5",
|
"openswoole/ide-helper": "~4.11.5",
|
||||||
"phpstan/phpstan": "^1.8",
|
"phpstan/phpstan": "^1.9",
|
||||||
"phpstan/phpstan-doctrine": "^1.3",
|
"phpstan/phpstan-doctrine": "^1.3",
|
||||||
"phpstan/phpstan-phpunit": "^1.1",
|
"phpstan/phpstan-phpunit": "^1.3",
|
||||||
"phpstan/phpstan-symfony": "^1.2",
|
"phpstan/phpstan-symfony": "^1.2",
|
||||||
"phpunit/php-code-coverage": "^9.2",
|
"phpunit/php-code-coverage": "^10.0",
|
||||||
"phpunit/phpunit": "^9.5",
|
"phpunit/phpunit": "^10.0",
|
||||||
"roave/security-advisories": "dev-master",
|
"roave/security-advisories": "dev-master",
|
||||||
"shlinkio/php-coding-standard": "~2.3.0",
|
"shlinkio/php-coding-standard": "~2.3.0",
|
||||||
"shlinkio/shlink-test-utils": "^3.4",
|
"shlinkio/shlink-test-utils": "^3.5",
|
||||||
"symfony/var-dumper": "^6.1",
|
"symfony/var-dumper": "^6.2",
|
||||||
"veewee/composer-run-parallel": "^1.1"
|
"veewee/composer-run-parallel": "^1.2"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@ -133,7 +132,7 @@
|
|||||||
"test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml --log-junit=build/coverage-cli/junit.xml",
|
"test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml --log-junit=build/coverage-cli/junit.xml",
|
||||||
"test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli",
|
"test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli",
|
||||||
"test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli",
|
"test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli",
|
||||||
"infect:ci:base": "infection --threads=max --only-covered --only-covering-test-cases --skip-initial-tests",
|
"infect:ci:base": "infection --threads=max --only-covered --skip-initial-tests",
|
||||||
"infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=80",
|
"infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=80",
|
||||||
"infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json5",
|
"infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json5",
|
||||||
"infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=80 --configuration=infection-api.json5",
|
"infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=80 --configuration=infection-api.json5",
|
||||||
|
@ -23,7 +23,7 @@ class ListApiKeysTest extends CliTestCase
|
|||||||
self::assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode);
|
self::assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFlags(): iterable
|
public static function provideFlags(): iterable
|
||||||
{
|
{
|
||||||
$expiredApiKeyDate = Chronos::now()->subDay()->startOfDay()->toAtomString();
|
$expiredApiKeyDate = Chronos::now()->subDay()->startOfDay()->toAtomString();
|
||||||
$enabledOnlyOutput = <<<OUT
|
$enabledOnlyOutput = <<<OUT
|
||||||
|
@ -19,7 +19,7 @@ class ListShortUrlsTest extends CliTestCase
|
|||||||
self::assertStringContainsString($expectedOutput, $output);
|
self::assertStringContainsString($expectedOutput, $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFlagsAndOutput(): iterable
|
public static function provideFlagsAndOutput(): iterable
|
||||||
{
|
{
|
||||||
// phpcs:disable Generic.Files.LineLength
|
// phpcs:disable Generic.Files.LineLength
|
||||||
yield 'no flags' => [[], <<<OUTPUT
|
yield 'no flags' => [[], <<<OUTPUT
|
||||||
|
@ -32,24 +32,25 @@ class RoleResolverTest extends TestCase
|
|||||||
* @dataProvider provideRoles
|
* @dataProvider provideRoles
|
||||||
*/
|
*/
|
||||||
public function properRolesAreResolvedBasedOnInput(
|
public function properRolesAreResolvedBasedOnInput(
|
||||||
InputInterface $input,
|
callable $createInput,
|
||||||
array $expectedRoles,
|
array $expectedRoles,
|
||||||
int $expectedDomainCalls,
|
int $expectedDomainCalls,
|
||||||
): void {
|
): void {
|
||||||
|
$input = $createInput($this);
|
||||||
$this->domainService->expects($this->exactly($expectedDomainCalls))->method('getOrCreate')->with(
|
$this->domainService->expects($this->exactly($expectedDomainCalls))->method('getOrCreate')->with(
|
||||||
'example.com',
|
'example.com',
|
||||||
)->willReturn($this->domainWithId(Domain::withAuthority('example.com')));
|
)->willReturn(self::domainWithId(Domain::withAuthority('example.com')));
|
||||||
|
|
||||||
$result = $this->resolver->determineRoles($input);
|
$result = $this->resolver->determineRoles($input);
|
||||||
|
|
||||||
self::assertEquals($expectedRoles, $result);
|
self::assertEquals($expectedRoles, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRoles(): iterable
|
public static function provideRoles(): iterable
|
||||||
{
|
{
|
||||||
$domain = $this->domainWithId(Domain::withAuthority('example.com'));
|
$domain = self::domainWithId(Domain::withAuthority('example.com'));
|
||||||
$buildInput = function (array $definition): InputInterface {
|
$buildInput = static fn (array $definition) => function (TestCase $test) use ($definition): InputInterface {
|
||||||
$input = $this->createStub(InputInterface::class);
|
$input = $test->createStub(InputInterface::class);
|
||||||
$input->method('getOption')->willReturnMap(
|
$input->method('getOption')->willReturnMap(
|
||||||
map($definition, static fn (mixed $returnValue, string $param) => [$param, $returnValue]),
|
map($definition, static fn (mixed $returnValue, string $param) => [$param, $returnValue]),
|
||||||
);
|
);
|
||||||
@ -114,7 +115,7 @@ class RoleResolverTest extends TestCase
|
|||||||
$this->resolver->determineRoles($input);
|
$this->resolver->determineRoles($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function domainWithId(Domain $domain): Domain
|
private static function domainWithId(Domain $domain): Domain
|
||||||
{
|
{
|
||||||
$domain->setId('1');
|
$domain->setId('1');
|
||||||
return $domain;
|
return $domain;
|
||||||
|
@ -43,7 +43,7 @@ class ListKeysCommandTest extends TestCase
|
|||||||
self::assertEquals($expected, $output);
|
self::assertEquals($expected, $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideKeysAndOutputs(): iterable
|
public static function provideKeysAndOutputs(): iterable
|
||||||
{
|
{
|
||||||
$dateInThePast = Chronos::createFromFormat('Y-m-d H:i:s', '2020-01-01 00:00:00');
|
$dateInThePast = Chronos::createFromFormat('Y-m-d H:i:s', '2020-01-01 00:00:00');
|
||||||
|
|
||||||
@ -84,14 +84,14 @@ class ListKeysCommandTest extends TestCase
|
|||||||
yield 'with roles' => [
|
yield 'with roles' => [
|
||||||
[
|
[
|
||||||
$apiKey1 = ApiKey::create(),
|
$apiKey1 = ApiKey::create(),
|
||||||
$apiKey2 = $this->apiKeyWithRoles([RoleDefinition::forAuthoredShortUrls()]),
|
$apiKey2 = self::apiKeyWithRoles([RoleDefinition::forAuthoredShortUrls()]),
|
||||||
$apiKey3 = $this->apiKeyWithRoles(
|
$apiKey3 = self::apiKeyWithRoles(
|
||||||
[RoleDefinition::forDomain($this->domainWithId(Domain::withAuthority('example.com')))],
|
[RoleDefinition::forDomain(self::domainWithId(Domain::withAuthority('example.com')))],
|
||||||
),
|
),
|
||||||
$apiKey4 = ApiKey::create(),
|
$apiKey4 = ApiKey::create(),
|
||||||
$apiKey5 = $this->apiKeyWithRoles([
|
$apiKey5 = self::apiKeyWithRoles([
|
||||||
RoleDefinition::forAuthoredShortUrls(),
|
RoleDefinition::forAuthoredShortUrls(),
|
||||||
RoleDefinition::forDomain($this->domainWithId(Domain::withAuthority('example.com'))),
|
RoleDefinition::forDomain(self::domainWithId(Domain::withAuthority('example.com'))),
|
||||||
]),
|
]),
|
||||||
$apiKey6 = ApiKey::create(),
|
$apiKey6 = ApiKey::create(),
|
||||||
],
|
],
|
||||||
@ -141,7 +141,7 @@ class ListKeysCommandTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function apiKeyWithRoles(array $roles): ApiKey
|
private static function apiKeyWithRoles(array $roles): ApiKey
|
||||||
{
|
{
|
||||||
$apiKey = ApiKey::create();
|
$apiKey = ApiKey::create();
|
||||||
foreach ($roles as $role) {
|
foreach ($roles as $role) {
|
||||||
@ -151,7 +151,7 @@ class ListKeysCommandTest extends TestCase
|
|||||||
return $apiKey;
|
return $apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function domainWithId(Domain $domain): Domain
|
private static function domainWithId(Domain $domain): Domain
|
||||||
{
|
{
|
||||||
$domain->setId('1');
|
$domain->setId('1');
|
||||||
return $domain;
|
return $domain;
|
||||||
|
@ -124,7 +124,7 @@ class CreateDatabaseCommandTest extends TestCase
|
|||||||
self::assertStringContainsString('Database properly created!', $output);
|
self::assertStringContainsString('Database properly created!', $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideEmptyDatabase(): iterable
|
public static function provideEmptyDatabase(): iterable
|
||||||
{
|
{
|
||||||
yield 'no tables' => [[]];
|
yield 'no tables' => [[]];
|
||||||
yield 'migrations table' => [[MIGRATIONS_TABLE]];
|
yield 'migrations table' => [[MIGRATIONS_TABLE]];
|
||||||
|
@ -60,7 +60,7 @@ class DomainRedirectsCommandTest extends TestCase
|
|||||||
self::assertEquals(3, substr_count($output, '(Leave empty for no redirect)'));
|
self::assertEquals(3, substr_count($output, '(Leave empty for no redirect)'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'no domain' => [null];
|
yield 'no domain' => [null];
|
||||||
yield 'domain without redirects' => [Domain::withAuthority('')];
|
yield 'domain without redirects' => [Domain::withAuthority('')];
|
||||||
|
@ -57,7 +57,7 @@ class ListDomainsCommandTest extends TestCase
|
|||||||
self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode());
|
self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInputsAndOutputs(): iterable
|
public static function provideInputsAndOutputs(): iterable
|
||||||
{
|
{
|
||||||
$withoutRedirectsOutput = <<<OUTPUT
|
$withoutRedirectsOutput = <<<OUTPUT
|
||||||
+---------+------------+
|
+---------+------------+
|
||||||
|
@ -139,7 +139,7 @@ class CreateShortUrlCommandTest extends TestCase
|
|||||||
self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode());
|
self::assertEquals(ExitCodes::EXIT_SUCCESS, $this->commandTester->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'no domain' => [[], null];
|
yield 'no domain' => [[], null];
|
||||||
yield 'non-default domain foo' => [['--domain' => 'foo.com'], 'foo.com'];
|
yield 'non-default domain foo' => [['--domain' => 'foo.com'], 'foo.com'];
|
||||||
@ -166,7 +166,7 @@ class CreateShortUrlCommandTest extends TestCase
|
|||||||
$this->commandTester->execute($options);
|
$this->commandTester->execute($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFlags(): iterable
|
public static function provideFlags(): iterable
|
||||||
{
|
{
|
||||||
yield 'no flags' => [[], null];
|
yield 'no flags' => [[], null];
|
||||||
yield 'validate-url' => [['--validate-url' => true], true];
|
yield 'validate-url' => [['--validate-url' => true], true];
|
||||||
|
@ -98,7 +98,7 @@ class DeleteShortUrlCommandTest extends TestCase
|
|||||||
self::assertStringContainsString($expectedMessage, $output);
|
self::assertStringContainsString($expectedMessage, $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRetryDeleteAnswers(): iterable
|
public static function provideRetryDeleteAnswers(): iterable
|
||||||
{
|
{
|
||||||
yield 'answering yes to retry' => [['yes'], 2, 'Short URL with short code "abc123" successfully deleted.'];
|
yield 'answering yes to retry' => [['yes'], 2, 'Short URL with short code "abc123" successfully deleted.'];
|
||||||
yield 'answering no to retry' => [['no'], 1, 'Short URL was not deleted.'];
|
yield 'answering no to retry' => [['no'], 1, 'Short URL was not deleted.'];
|
||||||
|
@ -137,7 +137,7 @@ class ListShortUrlsCommandTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideOptionalFlags(): iterable
|
public static function provideOptionalFlags(): iterable
|
||||||
{
|
{
|
||||||
$apiKey = ApiKey::fromMeta(ApiKeyMeta::withName('my api key'));
|
$apiKey = ApiKey::fromMeta(ApiKeyMeta::withName('my api key'));
|
||||||
$key = $apiKey->toString();
|
$key = $apiKey->toString();
|
||||||
@ -200,7 +200,7 @@ class ListShortUrlsCommandTest extends TestCase
|
|||||||
$this->commandTester->execute($commandArgs);
|
$this->commandTester->execute($commandArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideArgs(): iterable
|
public static function provideArgs(): iterable
|
||||||
{
|
{
|
||||||
yield [[], 1, null, [], TagsMode::ANY->value];
|
yield [[], 1, null, [], TagsMode::ANY->value];
|
||||||
yield [['--page' => $page = 3], $page, null, [], TagsMode::ANY->value];
|
yield [['--page' => $page = 3], $page, null, [], TagsMode::ANY->value];
|
||||||
@ -255,7 +255,7 @@ class ListShortUrlsCommandTest extends TestCase
|
|||||||
$this->commandTester->execute($commandArgs);
|
$this->commandTester->execute($commandArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideOrderBy(): iterable
|
public static function provideOrderBy(): iterable
|
||||||
{
|
{
|
||||||
yield [[], null];
|
yield [[], null];
|
||||||
yield [['--order-by' => 'visits'], 'visits'];
|
yield [['--order-by' => 'visits'], 'visits'];
|
||||||
|
@ -61,7 +61,7 @@ class DownloadGeoLiteDbCommandTest extends TestCase
|
|||||||
self::assertSame($expectedExitCode, $exitCode);
|
self::assertSame($expectedExitCode, $exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFailureParams(): iterable
|
public static function provideFailureParams(): iterable
|
||||||
{
|
{
|
||||||
yield 'existing db' => [
|
yield 'existing db' => [
|
||||||
true,
|
true,
|
||||||
@ -93,7 +93,7 @@ class DownloadGeoLiteDbCommandTest extends TestCase
|
|||||||
self::assertSame(ExitCodes::EXIT_SUCCESS, $exitCode);
|
self::assertSame(ExitCodes::EXIT_SUCCESS, $exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideSuccessParams(): iterable
|
public static function provideSuccessParams(): iterable
|
||||||
{
|
{
|
||||||
yield 'up to date db' => [fn () => GeolocationResult::CHECK_SKIPPED, '[INFO] GeoLite2 db file is up to date.'];
|
yield 'up to date db' => [fn () => GeolocationResult::CHECK_SKIPPED, '[INFO] GeoLite2 db file is up to date.'];
|
||||||
yield 'outdated db' => [function (callable $beforeDownload): GeolocationResult {
|
yield 'outdated db' => [function (callable $beforeDownload): GeolocationResult {
|
||||||
|
@ -100,7 +100,7 @@ class LocateVisitsCommandTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideArgs(): iterable
|
public static function provideArgs(): iterable
|
||||||
{
|
{
|
||||||
yield 'no args' => [1, 0, 0, false, []];
|
yield 'no args' => [1, 0, 0, false, []];
|
||||||
yield 'retry' => [1, 1, 0, false, ['--retry' => true]];
|
yield 'retry' => [1, 1, 0, false, ['--retry' => true]];
|
||||||
@ -131,7 +131,7 @@ class LocateVisitsCommandTest extends TestCase
|
|||||||
self::assertStringContainsString($message, $output);
|
self::assertStringContainsString($message, $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideIgnoredAddresses(): iterable
|
public static function provideIgnoredAddresses(): iterable
|
||||||
{
|
{
|
||||||
yield 'empty address' => [IpCannotBeLocatedException::forEmptyAddress(), 'Ignored visit with no IP address'];
|
yield 'empty address' => [IpCannotBeLocatedException::forEmptyAddress(), 'Ignored visit with no IP address'];
|
||||||
yield 'localhost address' => [IpCannotBeLocatedException::forLocalhost(), 'Ignored localhost address'];
|
yield 'localhost address' => [IpCannotBeLocatedException::forLocalhost(), 'Ignored localhost address'];
|
||||||
@ -226,7 +226,7 @@ class LocateVisitsCommandTest extends TestCase
|
|||||||
$this->commandTester->execute(['--all' => true, '--retry' => true]);
|
$this->commandTester->execute(['--all' => true, '--retry' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideAbortInputs(): iterable
|
public static function provideAbortInputs(): iterable
|
||||||
{
|
{
|
||||||
yield 'n' => [['n']];
|
yield 'n' => [['n']];
|
||||||
yield 'no' => [['no']];
|
yield 'no' => [['no']];
|
||||||
|
@ -46,7 +46,7 @@ class GeolocationDbUpdateFailedExceptionTest extends TestCase
|
|||||||
self::assertEquals($prev, $e->getPrevious());
|
self::assertEquals($prev, $e->getPrevious());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providePrev(): iterable
|
public static function providePrev(): iterable
|
||||||
{
|
{
|
||||||
yield 'no prev' => [null];
|
yield 'no prev' => [null];
|
||||||
yield 'RuntimeException' => [new RuntimeException('prev')];
|
yield 'RuntimeException' => [new RuntimeException('prev')];
|
||||||
|
@ -84,7 +84,7 @@ class GeolocationDbUpdaterTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideBigDays(): iterable
|
public static function provideBigDays(): iterable
|
||||||
{
|
{
|
||||||
yield [36];
|
yield [36];
|
||||||
yield [50];
|
yield [50];
|
||||||
@ -109,7 +109,7 @@ class GeolocationDbUpdaterTest extends TestCase
|
|||||||
self::assertEquals(GeolocationResult::DB_IS_UP_TO_DATE, $result);
|
self::assertEquals(GeolocationResult::DB_IS_UP_TO_DATE, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideSmallDays(): iterable
|
public static function provideSmallDays(): iterable
|
||||||
{
|
{
|
||||||
$generateParamsWithTimestamp = static function (int $days) {
|
$generateParamsWithTimestamp = static function (int $days) {
|
||||||
$timestamp = Chronos::now()->subDays($days)->getTimestamp();
|
$timestamp = Chronos::now()->subDays($days)->getTimestamp();
|
||||||
@ -164,7 +164,7 @@ class GeolocationDbUpdaterTest extends TestCase
|
|||||||
self::assertEquals(GeolocationResult::CHECK_SKIPPED, $result);
|
self::assertEquals(GeolocationResult::CHECK_SKIPPED, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTrackingOptions(): iterable
|
public static function provideTrackingOptions(): iterable
|
||||||
{
|
{
|
||||||
yield 'disableTracking' => [new TrackingOptions(disableTracking: true)];
|
yield 'disableTracking' => [new TrackingOptions(disableTracking: true)];
|
||||||
yield 'disableIpTracking' => [new TrackingOptions(disableIpTracking: true)];
|
yield 'disableIpTracking' => [new TrackingOptions(disableIpTracking: true)];
|
||||||
|
@ -22,7 +22,7 @@ class RedirectTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedRedirect, $response->getHeaderLine('Location'));
|
self::assertEquals($expectedRedirect, $response->getHeaderLine('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideUserAgents(): iterable
|
public static function provideUserAgents(): iterable
|
||||||
{
|
{
|
||||||
yield 'android' => [ANDROID_USER_AGENT, 'https://blog.alejandrocelaya.com/android'];
|
yield 'android' => [ANDROID_USER_AGENT, 'https://blog.alejandrocelaya.com/android'];
|
||||||
yield 'ios' => [IOS_USER_AGENT, 'https://blog.alejandrocelaya.com/ios'];
|
yield 'ios' => [IOS_USER_AGENT, 'https://blog.alejandrocelaya.com/ios'];
|
||||||
|
@ -52,7 +52,7 @@ class TagsPaginatorAdapterTest extends DatabaseTestCase
|
|||||||
self::assertEquals($expectedTotalCount, $adapter->getNbResults());
|
self::assertEquals($expectedTotalCount, $adapter->getNbResults());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFilters(): iterable
|
public static function provideFilters(): iterable
|
||||||
{
|
{
|
||||||
yield [null, null, 0, 10, ['another', 'bar', 'baz', 'foo'], 4];
|
yield [null, null, 0, 10, ['another', 'bar', 'baz', 'foo'], 4];
|
||||||
yield [null, null, 2, 10, ['baz', 'foo'], 4];
|
yield [null, null, 2, 10, ['baz', 'foo'], 4];
|
||||||
|
@ -109,7 +109,7 @@ class TagRepositoryTest extends DatabaseTestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFilters(): iterable
|
public static function provideFilters(): iterable
|
||||||
{
|
{
|
||||||
$defaultList = [
|
$defaultList = [
|
||||||
['another', 0, 0, 0],
|
['another', 0, 0, 0],
|
||||||
|
@ -56,7 +56,7 @@ class VisitLocationRepositoryTest extends DatabaseTestCase
|
|||||||
self::assertCount(6, [...$all]);
|
self::assertCount(6, [...$all]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideBlockSize(): iterable
|
public static function provideBlockSize(): iterable
|
||||||
{
|
{
|
||||||
return map(range(1, 10), fn (int $value) => [$value]);
|
return map(range(1, 10), fn (int $value) => [$value]);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ class QrCodeActionTest extends TestCase
|
|||||||
self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type'));
|
self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideQueries(): iterable
|
public static function provideQueries(): iterable
|
||||||
{
|
{
|
||||||
yield 'no format, png default' => ['png', [], 'image/png'];
|
yield 'no format, png default' => ['png', [], 'image/png'];
|
||||||
yield 'no format, svg default' => ['svg', [], 'image/svg+xml'];
|
yield 'no format, svg default' => ['svg', [], 'image/svg+xml'];
|
||||||
@ -122,7 +122,7 @@ class QrCodeActionTest extends TestCase
|
|||||||
self::assertEquals($expectedSize, $size);
|
self::assertEquals($expectedSize, $size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRequestsWithSize(): iterable
|
public static function provideRequestsWithSize(): iterable
|
||||||
{
|
{
|
||||||
yield 'different margin and size defaults' => [
|
yield 'different margin and size defaults' => [
|
||||||
new QrCodeOptions(size: 660, margin: 40),
|
new QrCodeOptions(size: 660, margin: 40),
|
||||||
@ -215,7 +215,7 @@ class QrCodeActionTest extends TestCase
|
|||||||
self::assertEquals($color, $expectedColor);
|
self::assertEquals($color, $expectedColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRoundBlockSize(): iterable
|
public static function provideRoundBlockSize(): iterable
|
||||||
{
|
{
|
||||||
yield 'no round block param' => [new QrCodeOptions(), null, self::WHITE];
|
yield 'no round block param' => [new QrCodeOptions(), null, self::WHITE];
|
||||||
yield 'no round block param, but disabled by default' => [
|
yield 'no round block param, but disabled by default' => [
|
||||||
|
@ -39,7 +39,7 @@ class RobotsActionTest extends TestCase
|
|||||||
self::assertEquals('text/plain', $response->getHeaderLine('Content-Type'));
|
self::assertEquals('text/plain', $response->getHeaderLine('Content-Type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideShortCodes(): iterable
|
public static function provideShortCodes(): iterable
|
||||||
{
|
{
|
||||||
yield 'three short codes' => [['foo', 'bar', 'baz'], <<<ROBOTS
|
yield 'three short codes' => [['foo', 'bar', 'baz'], <<<ROBOTS
|
||||||
# For more information about the robots.txt standard, see:
|
# For more information about the robots.txt standard, see:
|
||||||
|
@ -32,7 +32,7 @@ class EnvVarsTest extends TestCase
|
|||||||
self::assertEquals($exists, $envVar->existsInEnv());
|
self::assertEquals($exists, $envVar->existsInEnv());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExistingEnvVars(): iterable
|
public static function provideExistingEnvVars(): iterable
|
||||||
{
|
{
|
||||||
yield 'DB_NAME' => [EnvVars::DB_NAME, true];
|
yield 'DB_NAME' => [EnvVars::DB_NAME, true];
|
||||||
yield 'BASE_PATH' => [EnvVars::BASE_PATH, true];
|
yield 'BASE_PATH' => [EnvVars::BASE_PATH, true];
|
||||||
@ -49,7 +49,7 @@ class EnvVarsTest extends TestCase
|
|||||||
self::assertEquals($expected, $envVar->loadFromEnv($default));
|
self::assertEquals($expected, $envVar->loadFromEnv($default));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideEnvVarsValues(): iterable
|
public static function provideEnvVarsValues(): iterable
|
||||||
{
|
{
|
||||||
yield 'DB_NAME without default' => [EnvVars::DB_NAME, 'shlink', null];
|
yield 'DB_NAME without default' => [EnvVars::DB_NAME, 'shlink', null];
|
||||||
yield 'DB_NAME with default' => [EnvVars::DB_NAME, 'shlink', 'foobar'];
|
yield 'DB_NAME with default' => [EnvVars::DB_NAME, 'shlink', 'foobar'];
|
||||||
|
@ -13,7 +13,6 @@ use PHPUnit\Framework\MockObject\MockObject;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Message\UriInterface;
|
use Psr\Http\Message\UriInterface;
|
||||||
use Psr\Http\Server\MiddlewareInterface;
|
|
||||||
use Psr\Log\NullLogger;
|
use Psr\Log\NullLogger;
|
||||||
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
||||||
use Shlinkio\Shlink\Core\Config\NotFoundRedirectResolver;
|
use Shlinkio\Shlink\Core\Config\NotFoundRedirectResolver;
|
||||||
@ -21,6 +20,8 @@ use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
|
|||||||
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
|
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
|
||||||
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;
|
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;
|
||||||
|
|
||||||
|
use function Laminas\Stratigility\middleware;
|
||||||
|
|
||||||
class NotFoundRedirectResolverTest extends TestCase
|
class NotFoundRedirectResolverTest extends TestCase
|
||||||
{
|
{
|
||||||
private NotFoundRedirectResolver $resolver;
|
private NotFoundRedirectResolver $resolver;
|
||||||
@ -52,47 +53,47 @@ class NotFoundRedirectResolverTest extends TestCase
|
|||||||
self::assertSame($expectedResp, $resp);
|
self::assertSame($expectedResp, $resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRedirects(): iterable
|
public static function provideRedirects(): iterable
|
||||||
{
|
{
|
||||||
yield 'base URL with trailing slash' => [
|
yield 'base URL with trailing slash' => [
|
||||||
$uri = new Uri('/'),
|
$uri = new Uri('/'),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(baseUrl: 'baseUrl'),
|
new NotFoundRedirectOptions(baseUrl: 'baseUrl'),
|
||||||
'baseUrl',
|
'baseUrl',
|
||||||
];
|
];
|
||||||
yield 'base URL with domain placeholder' => [
|
yield 'base URL with domain placeholder' => [
|
||||||
$uri = new Uri('https://s.test'),
|
$uri = new Uri('https://s.test'),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/{DOMAIN}'),
|
new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/{DOMAIN}'),
|
||||||
'https://redirect-here.com/s.test',
|
'https://redirect-here.com/s.test',
|
||||||
];
|
];
|
||||||
yield 'base URL with domain placeholder in query' => [
|
yield 'base URL with domain placeholder in query' => [
|
||||||
$uri = new Uri('https://s.test'),
|
$uri = new Uri('https://s.test'),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/?domain={DOMAIN}'),
|
new NotFoundRedirectOptions(baseUrl: 'https://redirect-here.com/?domain={DOMAIN}'),
|
||||||
'https://redirect-here.com/?domain=s.test',
|
'https://redirect-here.com/?domain=s.test',
|
||||||
];
|
];
|
||||||
yield 'base URL without trailing slash' => [
|
yield 'base URL without trailing slash' => [
|
||||||
$uri = new Uri(''),
|
$uri = new Uri(''),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(baseUrl: 'baseUrl'),
|
new NotFoundRedirectOptions(baseUrl: 'baseUrl'),
|
||||||
'baseUrl',
|
'baseUrl',
|
||||||
];
|
];
|
||||||
yield 'regular 404' => [
|
yield 'regular 404' => [
|
||||||
$uri = new Uri('/foo/bar'),
|
$uri = new Uri('/foo/bar'),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(regular404: 'regular404'),
|
new NotFoundRedirectOptions(regular404: 'regular404'),
|
||||||
'regular404',
|
'regular404',
|
||||||
];
|
];
|
||||||
yield 'regular 404 with path placeholder in query' => [
|
yield 'regular 404 with path placeholder in query' => [
|
||||||
$uri = new Uri('/foo/bar'),
|
$uri = new Uri('/foo/bar'),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(regular404: 'https://redirect-here.com/?path={ORIGINAL_PATH}'),
|
new NotFoundRedirectOptions(regular404: 'https://redirect-here.com/?path={ORIGINAL_PATH}'),
|
||||||
'https://redirect-here.com/?path=%2Ffoo%2Fbar',
|
'https://redirect-here.com/?path=%2Ffoo%2Fbar',
|
||||||
];
|
];
|
||||||
yield 'regular 404 with multiple placeholders' => [
|
yield 'regular 404 with multiple placeholders' => [
|
||||||
$uri = new Uri('https://s.test/foo/bar'),
|
$uri = new Uri('https://s.test/foo/bar'),
|
||||||
$this->notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
self::notFoundType(ServerRequestFactory::fromGlobals()->withUri($uri)),
|
||||||
new NotFoundRedirectOptions(
|
new NotFoundRedirectOptions(
|
||||||
regular404: 'https://redirect-here.com/{ORIGINAL_PATH}/{DOMAIN}/?d={DOMAIN}&p={ORIGINAL_PATH}',
|
regular404: 'https://redirect-here.com/{ORIGINAL_PATH}/{DOMAIN}/?d={DOMAIN}&p={ORIGINAL_PATH}',
|
||||||
),
|
),
|
||||||
@ -100,13 +101,13 @@ class NotFoundRedirectResolverTest extends TestCase
|
|||||||
];
|
];
|
||||||
yield 'invalid short URL' => [
|
yield 'invalid short URL' => [
|
||||||
new Uri('/foo'),
|
new Uri('/foo'),
|
||||||
$this->notFoundType($this->requestForRoute(RedirectAction::class)),
|
self::notFoundType(self::requestForRoute(RedirectAction::class)),
|
||||||
new NotFoundRedirectOptions(invalidShortUrl: 'invalidShortUrl'),
|
new NotFoundRedirectOptions(invalidShortUrl: 'invalidShortUrl'),
|
||||||
'invalidShortUrl',
|
'invalidShortUrl',
|
||||||
];
|
];
|
||||||
yield 'invalid short URL with path placeholder' => [
|
yield 'invalid short URL with path placeholder' => [
|
||||||
new Uri('/foo'),
|
new Uri('/foo'),
|
||||||
$this->notFoundType($this->requestForRoute(RedirectAction::class)),
|
self::notFoundType(self::requestForRoute(RedirectAction::class)),
|
||||||
new NotFoundRedirectOptions(invalidShortUrl: 'https://redirect-here.com/{ORIGINAL_PATH}'),
|
new NotFoundRedirectOptions(invalidShortUrl: 'https://redirect-here.com/{ORIGINAL_PATH}'),
|
||||||
'https://redirect-here.com/foo',
|
'https://redirect-here.com/foo',
|
||||||
];
|
];
|
||||||
@ -115,7 +116,7 @@ class NotFoundRedirectResolverTest extends TestCase
|
|||||||
/** @test */
|
/** @test */
|
||||||
public function noResponseIsReturnedIfNoConditionsMatch(): void
|
public function noResponseIsReturnedIfNoConditionsMatch(): void
|
||||||
{
|
{
|
||||||
$notFoundType = $this->notFoundType($this->requestForRoute('foo'));
|
$notFoundType = self::notFoundType(self::requestForRoute('foo'));
|
||||||
$this->helper->expects($this->never())->method('buildRedirectResponse');
|
$this->helper->expects($this->never())->method('buildRedirectResponse');
|
||||||
|
|
||||||
$result = $this->resolver->resolveRedirectResponse($notFoundType, new NotFoundRedirectOptions(), new Uri());
|
$result = $this->resolver->resolveRedirectResponse($notFoundType, new NotFoundRedirectOptions(), new Uri());
|
||||||
@ -123,12 +124,12 @@ class NotFoundRedirectResolverTest extends TestCase
|
|||||||
self::assertNull($result);
|
self::assertNull($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function notFoundType(ServerRequestInterface $req): NotFoundType
|
private static function notFoundType(ServerRequestInterface $req): NotFoundType
|
||||||
{
|
{
|
||||||
return NotFoundType::fromRequest($req, '');
|
return NotFoundType::fromRequest($req, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function requestForRoute(string $routeName): ServerRequestInterface
|
private static function requestForRoute(string $routeName): ServerRequestInterface
|
||||||
{
|
{
|
||||||
return ServerRequestFactory::fromGlobals()
|
return ServerRequestFactory::fromGlobals()
|
||||||
->withAttribute(
|
->withAttribute(
|
||||||
@ -136,7 +137,8 @@ class NotFoundRedirectResolverTest extends TestCase
|
|||||||
RouteResult::fromRoute(
|
RouteResult::fromRoute(
|
||||||
new Route(
|
new Route(
|
||||||
'foo',
|
'foo',
|
||||||
$this->createMock(MiddlewareInterface::class),
|
middleware(function (): void {
|
||||||
|
}),
|
||||||
['GET'],
|
['GET'],
|
||||||
$routeName,
|
$routeName,
|
||||||
),
|
),
|
||||||
|
@ -31,7 +31,7 @@ class BasePathPrefixerTest extends TestCase
|
|||||||
self::assertEquals($expectedMiddlewares, $middlewares);
|
self::assertEquals($expectedMiddlewares, $middlewares);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideConfig(): iterable
|
public static function provideConfig(): iterable
|
||||||
{
|
{
|
||||||
yield 'with empty options' => [['routes' => []], [], []];
|
yield 'with empty options' => [['routes' => []], [], []];
|
||||||
yield 'with non-empty options' => [
|
yield 'with non-empty options' => [
|
||||||
|
@ -25,7 +25,7 @@ class MultiSegmentSlugProcessorTest extends TestCase
|
|||||||
self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? []);
|
self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideConfigs(): iterable
|
public static function provideConfigs(): iterable
|
||||||
{
|
{
|
||||||
yield [[], []];
|
yield [[], []];
|
||||||
yield [['url_shortener' => []], []];
|
yield [['url_shortener' => []], []];
|
||||||
|
@ -29,7 +29,7 @@ class ShortUrlMethodsProcessorTest extends TestCase
|
|||||||
self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? null);
|
self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideConfigs(): iterable
|
public static function provideConfigs(): iterable
|
||||||
{
|
{
|
||||||
$buildConfigWithStatus = static fn (int $status, ?array $expectedAllowedMethods) => [[
|
$buildConfigWithStatus = static fn (int $status, ?array $expectedAllowedMethods) => [[
|
||||||
'routes' => [
|
'routes' => [
|
||||||
|
@ -44,7 +44,7 @@ class DomainServiceTest extends TestCase
|
|||||||
self::assertEquals($expectedResult, $result);
|
self::assertEquals($expectedResult, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExcludedDomains(): iterable
|
public static function provideExcludedDomains(): iterable
|
||||||
{
|
{
|
||||||
$default = DomainItem::forDefaultDomain('default.com', new EmptyNotFoundRedirectConfig());
|
$default = DomainItem::forDefaultDomain('default.com', new EmptyNotFoundRedirectConfig());
|
||||||
$adminApiKey = ApiKey::create();
|
$adminApiKey = ApiKey::create();
|
||||||
@ -190,7 +190,7 @@ class DomainServiceTest extends TestCase
|
|||||||
self::assertEquals('baz.com', $result->invalidShortUrlRedirect());
|
self::assertEquals('baz.com', $result->invalidShortUrlRedirect());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFoundDomains(): iterable
|
public static function provideFoundDomains(): iterable
|
||||||
{
|
{
|
||||||
$domain = Domain::withAuthority('');
|
$domain = Domain::withAuthority('');
|
||||||
$adminApiKey = ApiKey::create();
|
$adminApiKey = ApiKey::create();
|
||||||
|
@ -6,6 +6,7 @@ namespace ShlinkioTest\Shlink\Core\ErrorHandler;
|
|||||||
|
|
||||||
use Laminas\Diactoros\Response;
|
use Laminas\Diactoros\Response;
|
||||||
use Laminas\Diactoros\ServerRequestFactory;
|
use Laminas\Diactoros\ServerRequestFactory;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
@ -58,40 +59,39 @@ class NotFoundRedirectHandlerTest extends TestCase
|
|||||||
self::assertSame($expectedResp, $result);
|
self::assertSame($expectedResp, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonRedirectScenarios(): iterable
|
public static function provideNonRedirectScenarios(): iterable
|
||||||
{
|
{
|
||||||
yield 'no domain' => [function (
|
yield 'no domain' => [function (
|
||||||
MockObject&DomainServiceInterface $domainService,
|
MockObject&DomainServiceInterface $domainService,
|
||||||
MockObject&NotFoundRedirectResolverInterface $resolver,
|
MockObject&NotFoundRedirectResolverInterface $resolver,
|
||||||
): void {
|
): void {
|
||||||
$domainService->expects($this->once())->method('findByAuthority')->withAnyParameters()->willReturn(
|
$domainService->expects(self::once())->method('findByAuthority')->withAnyParameters()->willReturn(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
$resolver->expects($this->once())->method('resolveRedirectResponse')->with(
|
$resolver->expects(self::once())->method('resolveRedirectResponse')->with(
|
||||||
$this->isInstanceOf(NotFoundType::class),
|
self::isInstanceOf(NotFoundType::class),
|
||||||
$this->isInstanceOf(NotFoundRedirectOptions::class),
|
self::isInstanceOf(NotFoundRedirectOptions::class),
|
||||||
$this->isInstanceOf(UriInterface::class),
|
self::isInstanceOf(UriInterface::class),
|
||||||
)->willReturn(null);
|
)->willReturn(null);
|
||||||
}];
|
}];
|
||||||
yield 'non-redirecting domain' => [function (
|
yield 'non-redirecting domain' => [function (
|
||||||
MockObject&DomainServiceInterface $domainService,
|
MockObject&DomainServiceInterface $domainService,
|
||||||
MockObject&NotFoundRedirectResolverInterface $resolver,
|
MockObject&NotFoundRedirectResolverInterface $resolver,
|
||||||
): void {
|
): void {
|
||||||
$domainService->expects($this->once())->method('findByAuthority')->withAnyParameters()->willReturn(
|
$domainService->expects(self::once())->method('findByAuthority')->withAnyParameters()->willReturn(
|
||||||
Domain::withAuthority(''),
|
Domain::withAuthority(''),
|
||||||
);
|
);
|
||||||
$resolver->expects($this->exactly(2))->method('resolveRedirectResponse')->withConsecutive(
|
$callCount = 0;
|
||||||
[
|
$resolver->expects(self::exactly(2))->method('resolveRedirectResponse')->willReturnCallback(
|
||||||
$this->isInstanceOf(NotFoundType::class),
|
function (mixed $arg1, mixed $arg2, mixed $arg3) use (&$callCount) {
|
||||||
$this->isInstanceOf(Domain::class),
|
Assert::assertInstanceOf(NotFoundType::class, $arg1);
|
||||||
$this->isInstanceOf(UriInterface::class),
|
Assert::assertInstanceOf($callCount === 0 ? Domain::class : NotFoundRedirectOptions::class, $arg2);
|
||||||
],
|
Assert::assertInstanceOf(UriInterface::class, $arg3);
|
||||||
[
|
|
||||||
$this->isInstanceOf(NotFoundType::class),
|
$callCount++;
|
||||||
$this->isInstanceOf(NotFoundRedirectOptions::class),
|
return null;
|
||||||
$this->isInstanceOf(UriInterface::class),
|
},
|
||||||
],
|
);
|
||||||
)->willReturn(null);
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,12 @@ use Mezzio\Router\Route;
|
|||||||
use Mezzio\Router\RouteResult;
|
use Mezzio\Router\RouteResult;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\MiddlewareInterface;
|
|
||||||
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
||||||
use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
|
use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
|
||||||
use Shlinkio\Shlink\Core\ErrorHandler\NotFoundTemplateHandler;
|
use Shlinkio\Shlink\Core\ErrorHandler\NotFoundTemplateHandler;
|
||||||
|
|
||||||
|
use function Laminas\Stratigility\middleware;
|
||||||
|
|
||||||
class NotFoundTemplateHandlerTest extends TestCase
|
class NotFoundTemplateHandlerTest extends TestCase
|
||||||
{
|
{
|
||||||
private NotFoundTemplateHandler $handler;
|
private NotFoundTemplateHandler $handler;
|
||||||
@ -44,19 +45,20 @@ class NotFoundTemplateHandlerTest extends TestCase
|
|||||||
self::assertTrue($this->readFileCalled);
|
self::assertTrue($this->readFileCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTemplates(): iterable
|
public static function provideTemplates(): iterable
|
||||||
{
|
{
|
||||||
$request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/foo'));
|
$request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/foo'));
|
||||||
|
|
||||||
yield 'base url' => [$this->withNotFoundType($request, '/foo'), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE];
|
yield 'base url' => [self::withNotFoundType($request, '/foo'), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE];
|
||||||
yield 'regular not found' => [$this->withNotFoundType($request), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE];
|
yield 'regular not found' => [self::withNotFoundType($request), NotFoundTemplateHandler::NOT_FOUND_TEMPLATE];
|
||||||
yield 'invalid short code' => [
|
yield 'invalid short code' => [
|
||||||
$this->withNotFoundType($request->withAttribute(
|
self::withNotFoundType($request->withAttribute(
|
||||||
RouteResult::class,
|
RouteResult::class,
|
||||||
RouteResult::fromRoute(
|
RouteResult::fromRoute(
|
||||||
new Route(
|
new Route(
|
||||||
'foo',
|
'foo',
|
||||||
$this->createMock(MiddlewareInterface::class),
|
middleware(function (): void {
|
||||||
|
}),
|
||||||
['GET'],
|
['GET'],
|
||||||
RedirectAction::class,
|
RedirectAction::class,
|
||||||
),
|
),
|
||||||
@ -66,7 +68,7 @@ class NotFoundTemplateHandlerTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function withNotFoundType(ServerRequestInterface $req, string $baseUrl = ''): ServerRequestInterface
|
private static function withNotFoundType(ServerRequestInterface $req, string $baseUrl = ''): ServerRequestInterface
|
||||||
{
|
{
|
||||||
$type = NotFoundType::fromRequest($req, $baseUrl);
|
$type = NotFoundType::fromRequest($req, $baseUrl);
|
||||||
return $req->withAttribute(NotFoundType::class, $type);
|
return $req->withAttribute(NotFoundType::class, $type);
|
||||||
|
@ -46,7 +46,7 @@ class CloseDbConnectionEventListenerTest extends TestCase
|
|||||||
self::assertTrue($wrappedWasCalled);
|
self::assertTrue($wrappedWasCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideWrapped(): iterable
|
public static function provideWrapped(): iterable
|
||||||
{
|
{
|
||||||
yield 'does not throw exception' => (static function (): array {
|
yield 'does not throw exception' => (static function (): array {
|
||||||
$wrappedWasCalled = false;
|
$wrappedWasCalled = false;
|
||||||
|
@ -146,7 +146,7 @@ class LocateVisitTest extends TestCase
|
|||||||
self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation(Location::emptyInstance()));
|
self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation(Location::emptyInstance()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonLocatableVisits(): iterable
|
public static function provideNonLocatableVisits(): iterable
|
||||||
{
|
{
|
||||||
$shortUrl = ShortUrl::createFake();
|
$shortUrl = ShortUrl::createFake();
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ class LocateVisitTest extends TestCase
|
|||||||
self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation($location));
|
self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation($location));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideIpAddresses(): iterable
|
public static function provideIpAddresses(): iterable
|
||||||
{
|
{
|
||||||
yield 'no original IP address' => [
|
yield 'no original IP address' => [
|
||||||
Visit::forValidShortUrl(ShortUrl::createFake(), new Visitor('', '', '1.2.3.4', '')),
|
Visit::forValidShortUrl(ShortUrl::createFake(), new Visitor('', '', '1.2.3.4', '')),
|
||||||
|
@ -121,7 +121,7 @@ class NotifyVisitToMercureTest extends TestCase
|
|||||||
($this->listener)(new VisitLocated($visitId));
|
($this->listener)(new VisitLocated($visitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideOrphanVisits(): iterable
|
public static function provideOrphanVisits(): iterable
|
||||||
{
|
{
|
||||||
$visitor = Visitor::emptyInstance();
|
$visitor = Visitor::emptyInstance();
|
||||||
|
|
||||||
|
@ -120,13 +120,13 @@ class NotifyVisitToWebHooksTest extends TestCase
|
|||||||
$this->createListener($webhooks)(new VisitLocated('1'));
|
$this->createListener($webhooks)(new VisitLocated('1'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideVisits(): iterable
|
public static function provideVisits(): iterable
|
||||||
{
|
{
|
||||||
yield 'regular visit' => [
|
yield 'regular visit' => [
|
||||||
Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
Visit::forValidShortUrl(ShortUrl::createFake(), Visitor::emptyInstance()),
|
||||||
['shortUrl', 'visit'],
|
['shortUrl', 'visit'],
|
||||||
];
|
];
|
||||||
yield 'orphan visit' => [Visit::forBasePath(Visitor::emptyInstance()), ['visit'],];
|
yield 'orphan visit' => [Visit::forBasePath(Visitor::emptyInstance()), ['visit']];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createListener(array $webhooks, bool $notifyOrphanVisits = true): NotifyVisitToWebHooks
|
private function createListener(array $webhooks, bool $notifyOrphanVisits = true): NotifyVisitToWebHooks
|
||||||
|
@ -77,7 +77,7 @@ class PublishingUpdatesGeneratorTest extends TestCase
|
|||||||
], $update->payload);
|
], $update->payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMethod(): iterable
|
public static function provideMethod(): iterable
|
||||||
{
|
{
|
||||||
yield 'newVisitUpdate' => ['newVisitUpdate', 'https://shlink.io/new-visit', 'the cool title'];
|
yield 'newVisitUpdate' => ['newVisitUpdate', 'https://shlink.io/new-visit', 'the cool title'];
|
||||||
yield 'newShortUrlVisitUpdate' => ['newShortUrlVisitUpdate', 'https://shlink.io/new-visit/foo', null];
|
yield 'newShortUrlVisitUpdate' => ['newShortUrlVisitUpdate', 'https://shlink.io/new-visit/foo', null];
|
||||||
@ -105,7 +105,7 @@ class PublishingUpdatesGeneratorTest extends TestCase
|
|||||||
], $update->payload);
|
], $update->payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideOrphanVisits(): iterable
|
public static function provideOrphanVisits(): iterable
|
||||||
{
|
{
|
||||||
$visitor = Visitor::emptyInstance();
|
$visitor = Visitor::emptyInstance();
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class NotifyNewShortUrlToRabbitMqTest extends TestCase
|
|||||||
($this->listener())(new ShortUrlCreated($shortUrlId));
|
($this->listener())(new ShortUrlCreated($shortUrlId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExceptions(): iterable
|
public static function provideExceptions(): iterable
|
||||||
{
|
{
|
||||||
yield [new RuntimeException('RuntimeException Error')];
|
yield [new RuntimeException('RuntimeException Error')];
|
||||||
yield [new Exception('Exception Error')];
|
yield [new Exception('Exception Error')];
|
||||||
|
@ -91,7 +91,7 @@ class NotifyVisitToRabbitMqTest extends TestCase
|
|||||||
($this->listener())(new VisitLocated($visitId));
|
($this->listener())(new VisitLocated($visitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideVisits(): iterable
|
public static function provideVisits(): iterable
|
||||||
{
|
{
|
||||||
$visitor = Visitor::emptyInstance();
|
$visitor = Visitor::emptyInstance();
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ class NotifyVisitToRabbitMqTest extends TestCase
|
|||||||
($this->listener())(new VisitLocated($visitId));
|
($this->listener())(new VisitLocated($visitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExceptions(): iterable
|
public static function provideExceptions(): iterable
|
||||||
{
|
{
|
||||||
yield [new RuntimeException('RuntimeException Error')];
|
yield [new RuntimeException('RuntimeException Error')];
|
||||||
yield [new Exception('Exception Error')];
|
yield [new Exception('Exception Error')];
|
||||||
@ -155,14 +155,14 @@ class NotifyVisitToRabbitMqTest extends TestCase
|
|||||||
($this->listener(new RabbitMqOptions(true, $legacy)))(new VisitLocated($visitId));
|
($this->listener(new RabbitMqOptions(true, $legacy)))(new VisitLocated($visitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideLegacyPayloads(): iterable
|
public static function provideLegacyPayloads(): iterable
|
||||||
{
|
{
|
||||||
yield 'legacy non-orphan visit' => [
|
yield 'legacy non-orphan visit' => [
|
||||||
true,
|
true,
|
||||||
$visit = Visit::forValidShortUrl(ShortUrl::withLongUrl('longUrl'), Visitor::emptyInstance()),
|
$visit = Visit::forValidShortUrl(ShortUrl::withLongUrl('longUrl'), Visitor::emptyInstance()),
|
||||||
noop(...),
|
noop(...),
|
||||||
function (MockObject & PublishingHelperInterface $helper) use ($visit): void {
|
function (MockObject & PublishingHelperInterface $helper) use ($visit): void {
|
||||||
$helper->method('publishUpdate')->with($this->callback(function (Update $update) use ($visit): bool {
|
$helper->method('publishUpdate')->with(self::callback(function (Update $update) use ($visit): bool {
|
||||||
$payload = $update->payload;
|
$payload = $update->payload;
|
||||||
Assert::assertEquals($payload, $visit->jsonSerialize());
|
Assert::assertEquals($payload, $visit->jsonSerialize());
|
||||||
Assert::assertArrayNotHasKey('visitedUrl', $payload);
|
Assert::assertArrayNotHasKey('visitedUrl', $payload);
|
||||||
@ -179,7 +179,7 @@ class NotifyVisitToRabbitMqTest extends TestCase
|
|||||||
Visit::forBasePath(Visitor::emptyInstance()),
|
Visit::forBasePath(Visitor::emptyInstance()),
|
||||||
noop(...),
|
noop(...),
|
||||||
function (MockObject & PublishingHelperInterface $helper): void {
|
function (MockObject & PublishingHelperInterface $helper): void {
|
||||||
$helper->method('publishUpdate')->with($this->callback(function (Update $update): bool {
|
$helper->method('publishUpdate')->with(self::callback(function (Update $update): bool {
|
||||||
$payload = $update->payload;
|
$payload = $update->payload;
|
||||||
Assert::assertArrayHasKey('visitedUrl', $payload);
|
Assert::assertArrayHasKey('visitedUrl', $payload);
|
||||||
Assert::assertArrayHasKey('type', $payload);
|
Assert::assertArrayHasKey('type', $payload);
|
||||||
@ -193,14 +193,14 @@ class NotifyVisitToRabbitMqTest extends TestCase
|
|||||||
Visit::forValidShortUrl(ShortUrl::withLongUrl('longUrl'), Visitor::emptyInstance()),
|
Visit::forValidShortUrl(ShortUrl::withLongUrl('longUrl'), Visitor::emptyInstance()),
|
||||||
function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void {
|
function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void {
|
||||||
$update = Update::forTopicAndPayload('', []);
|
$update = Update::forTopicAndPayload('', []);
|
||||||
$updatesGenerator->expects($this->never())->method('newOrphanVisitUpdate');
|
$updatesGenerator->expects(self::never())->method('newOrphanVisitUpdate');
|
||||||
$updatesGenerator->expects($this->once())->method('newVisitUpdate')->withAnyParameters()->willReturn(
|
$updatesGenerator->expects(self::once())->method('newVisitUpdate')->withAnyParameters()->willReturn(
|
||||||
$update,
|
$update,
|
||||||
);
|
);
|
||||||
$updatesGenerator->expects($this->once())->method('newShortUrlVisitUpdate')->willReturn($update);
|
$updatesGenerator->expects(self::once())->method('newShortUrlVisitUpdate')->willReturn($update);
|
||||||
},
|
},
|
||||||
function (MockObject & PublishingHelperInterface $helper): void {
|
function (MockObject & PublishingHelperInterface $helper): void {
|
||||||
$helper->expects($this->exactly(2))->method('publishUpdate')->with($this->isInstanceOf(Update::class));
|
$helper->expects(self::exactly(2))->method('publishUpdate')->with(self::isInstanceOf(Update::class));
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
yield 'non-legacy orphan visit' => [
|
yield 'non-legacy orphan visit' => [
|
||||||
@ -208,12 +208,12 @@ class NotifyVisitToRabbitMqTest extends TestCase
|
|||||||
Visit::forBasePath(Visitor::emptyInstance()),
|
Visit::forBasePath(Visitor::emptyInstance()),
|
||||||
function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void {
|
function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void {
|
||||||
$update = Update::forTopicAndPayload('', []);
|
$update = Update::forTopicAndPayload('', []);
|
||||||
$updatesGenerator->expects($this->once())->method('newOrphanVisitUpdate')->willReturn($update);
|
$updatesGenerator->expects(self::once())->method('newOrphanVisitUpdate')->willReturn($update);
|
||||||
$updatesGenerator->expects($this->never())->method('newVisitUpdate');
|
$updatesGenerator->expects(self::never())->method('newVisitUpdate');
|
||||||
$updatesGenerator->expects($this->never())->method('newShortUrlVisitUpdate');
|
$updatesGenerator->expects(self::never())->method('newShortUrlVisitUpdate');
|
||||||
},
|
},
|
||||||
function (MockObject & PublishingHelperInterface $helper): void {
|
function (MockObject & PublishingHelperInterface $helper): void {
|
||||||
$helper->expects($this->once())->method('publishUpdate')->with($this->isInstanceOf(Update::class));
|
$helper->expects(self::once())->method('publishUpdate')->with(self::isInstanceOf(Update::class));
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ class NotifyNewShortUrlToRedisTest extends TestCase
|
|||||||
$this->createListener()(new ShortUrlCreated($shortUrlId));
|
$this->createListener()(new ShortUrlCreated($shortUrlId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExceptions(): iterable
|
public static function provideExceptions(): iterable
|
||||||
{
|
{
|
||||||
yield [new RuntimeException('RuntimeException Error')];
|
yield [new RuntimeException('RuntimeException Error')];
|
||||||
yield [new Exception('Exception Error')];
|
yield [new Exception('Exception Error')];
|
||||||
|
@ -68,7 +68,7 @@ class NotifyVisitToRedisTest extends TestCase
|
|||||||
$this->createListener()(new VisitLocated($visitId));
|
$this->createListener()(new VisitLocated($visitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExceptions(): iterable
|
public static function provideExceptions(): iterable
|
||||||
{
|
{
|
||||||
yield [new RuntimeException('RuntimeException Error')];
|
yield [new RuntimeException('RuntimeException Error')];
|
||||||
yield [new Exception('Exception Error')];
|
yield [new Exception('Exception Error')];
|
||||||
|
@ -67,7 +67,7 @@ class UpdateGeoLiteDbTest extends TestCase
|
|||||||
($this->listener)();
|
($this->listener)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFlags(): iterable
|
public static function provideFlags(): iterable
|
||||||
{
|
{
|
||||||
yield 'existing old db' => [true, 'Updating GeoLite2 db file...'];
|
yield 'existing old db' => [true, 'Updating GeoLite2 db file...'];
|
||||||
yield 'not existing old db' => [false, 'Downloading GeoLite2 db file...'];
|
yield 'not existing old db' => [false, 'Downloading GeoLite2 db file...'];
|
||||||
@ -101,7 +101,7 @@ class UpdateGeoLiteDbTest extends TestCase
|
|||||||
($this->listener)();
|
($this->listener)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDownloaded(): iterable
|
public static function provideDownloaded(): iterable
|
||||||
{
|
{
|
||||||
yield [100, 0, true, null];
|
yield [100, 0, true, null];
|
||||||
yield [100, 0, false, null];
|
yield [100, 0, false, null];
|
||||||
@ -129,7 +129,7 @@ class UpdateGeoLiteDbTest extends TestCase
|
|||||||
($this->listener)();
|
($this->listener)();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideGeolocationResults(): iterable
|
public static function provideGeolocationResults(): iterable
|
||||||
{
|
{
|
||||||
return map(GeolocationResult::cases(), static fn (GeolocationResult $value) => [
|
return map(GeolocationResult::cases(), static fn (GeolocationResult $value) => [
|
||||||
$value,
|
$value,
|
||||||
|
@ -41,7 +41,7 @@ class DeleteShortUrlExceptionTest extends TestCase
|
|||||||
self::assertEquals(422, $e->getStatus());
|
self::assertEquals(422, $e->getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideThresholds(): array
|
public static function provideThresholds(): array
|
||||||
{
|
{
|
||||||
return map(range(5, 50, 5), function (int $number) {
|
return map(range(5, 50, 5), function (int $number) {
|
||||||
return [$number, $shortCode = generateRandomShortCode(6), sprintf(
|
return [$number, $shortCode = generateRandomShortCode(6), sprintf(
|
||||||
|
@ -29,7 +29,7 @@ class ForbiddenTagOperationExceptionTest extends TestCase
|
|||||||
self::assertEquals(403, $e->getStatus());
|
self::assertEquals(403, $e->getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExceptions(): iterable
|
public static function provideExceptions(): iterable
|
||||||
{
|
{
|
||||||
yield 'deletion' => [ForbiddenTagOperationException::forDeletion(), 'You are not allowed to delete tags'];
|
yield 'deletion' => [ForbiddenTagOperationException::forDeletion(), 'You are not allowed to delete tags'];
|
||||||
yield 'renaming' => [ForbiddenTagOperationException::forRenaming(), 'You are not allowed to rename tags'];
|
yield 'renaming' => [ForbiddenTagOperationException::forRenaming(), 'You are not allowed to rename tags'];
|
||||||
|
@ -34,7 +34,7 @@ class InvalidUrlExceptionTest extends TestCase
|
|||||||
self::assertEquals($prev, $e->getPrevious());
|
self::assertEquals($prev, $e->getPrevious());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providePrevious(): iterable
|
public static function providePrevious(): iterable
|
||||||
{
|
{
|
||||||
yield 'null previous' => [null];
|
yield 'null previous' => [null];
|
||||||
yield 'instance previous' => [new Exception('Previous error', 10)];
|
yield 'instance previous' => [new Exception('Previous error', 10)];
|
||||||
|
@ -53,7 +53,7 @@ class IpCannotBeLocatedExceptionTest extends TestCase
|
|||||||
self::assertEquals(UnlocatableIpType::ERROR, $e->type);
|
self::assertEquals(UnlocatableIpType::ERROR, $e->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideErrors(): iterable
|
public static function provideErrors(): iterable
|
||||||
{
|
{
|
||||||
yield 'Simple exception with positive code' => [new Exception('Some message', 100)];
|
yield 'Simple exception with positive code' => [new Exception('Some message', 100)];
|
||||||
yield 'Runtime exception with negative code' => [new RuntimeException('Something went wrong', -50)];
|
yield 'Runtime exception with negative code' => [new RuntimeException('Something went wrong', -50)];
|
||||||
|
@ -30,7 +30,7 @@ class NonUniqueSlugExceptionTest extends TestCase
|
|||||||
self::assertEquals($expectedAdditional, $e->getAdditionalData());
|
self::assertEquals($expectedAdditional, $e->getAdditionalData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMessages(): iterable
|
public static function provideMessages(): iterable
|
||||||
{
|
{
|
||||||
yield 'without domain' => [
|
yield 'without domain' => [
|
||||||
'Provided slug "foo" is already in use.',
|
'Provided slug "foo" is already in use.',
|
||||||
|
@ -34,7 +34,7 @@ class ShortUrlNotFoundExceptionTest extends TestCase
|
|||||||
self::assertEquals($expectedAdditional, $e->getAdditionalData());
|
self::assertEquals($expectedAdditional, $e->getAdditionalData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMessages(): iterable
|
public static function provideMessages(): iterable
|
||||||
{
|
{
|
||||||
yield 'without domain' => [
|
yield 'without domain' => [
|
||||||
'No URL found with short code "abc123"',
|
'No URL found with short code "abc123"',
|
||||||
|
@ -46,7 +46,7 @@ class ValidationExceptionTest extends TestCase
|
|||||||
self::assertStringContainsString($expectedStringRepresentation, (string) $e);
|
self::assertStringContainsString($expectedStringRepresentation, (string) $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExceptions(): iterable
|
public static function provideExceptions(): iterable
|
||||||
{
|
{
|
||||||
return [[null], [new RuntimeException()], [new LogicException()]];
|
return [[null], [new RuntimeException()], [new LogicException()]];
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class FunctionsTest extends TestCase
|
|||||||
self::assertEquals($expectedValues, enumValues($enum));
|
self::assertEquals($expectedValues, enumValues($enum));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideEnums(): iterable
|
public static function provideEnums(): iterable
|
||||||
{
|
{
|
||||||
yield EnvVars::class => [EnvVars::class, map(EnvVars::cases(), static fn (EnvVars $envVar) => $envVar->value)];
|
yield EnvVars::class => [EnvVars::class, map(EnvVars::cases(), static fn (EnvVars $envVar) => $envVar->value)];
|
||||||
yield VisitType::class => [
|
yield VisitType::class => [
|
||||||
|
@ -188,7 +188,7 @@ class ImportedLinksProcessorTest extends TestCase
|
|||||||
$this->processor->process($this->io, ImportResult::withShortUrls([$importedUrl]), $this->buildParams());
|
$this->processor->process($this->io, ImportResult::withShortUrls([$importedUrl]), $this->buildParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideUrlsWithVisits(): iterable
|
public static function provideUrlsWithVisits(): iterable
|
||||||
{
|
{
|
||||||
$now = Chronos::now();
|
$now = Chronos::now();
|
||||||
$createImportedUrl = static fn (array $visits) =>
|
$createImportedUrl = static fn (array $visits) =>
|
||||||
@ -262,7 +262,7 @@ class ImportedLinksProcessorTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideOrphanVisits(): iterable
|
public static function provideOrphanVisits(): iterable
|
||||||
{
|
{
|
||||||
yield 'import orphan disable without visits' => [false, [], null, 0];
|
yield 'import orphan disable without visits' => [false, [], null, 0];
|
||||||
yield 'import orphan enabled without visits' => [true, [], null, 0];
|
yield 'import orphan enabled without visits' => [true, [], null, 0];
|
||||||
|
@ -41,7 +41,7 @@ class ShortUrlTest extends TestCase
|
|||||||
$shortUrl->regenerateShortCode(ShortUrlMode::STRICT);
|
$shortUrl->regenerateShortCode(ShortUrlMode::STRICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidShortUrls(): iterable
|
public static function provideInvalidShortUrls(): iterable
|
||||||
{
|
{
|
||||||
yield 'with custom slug' => [
|
yield 'with custom slug' => [
|
||||||
ShortUrl::create(ShortUrlCreation::fromRawData(['customSlug' => 'custom-slug', 'longUrl' => 'longUrl'])),
|
ShortUrl::create(ShortUrlCreation::fromRawData(['customSlug' => 'custom-slug', 'longUrl' => 'longUrl'])),
|
||||||
@ -68,7 +68,7 @@ class ShortUrlTest extends TestCase
|
|||||||
self::assertNotEquals($firstShortCode, $secondShortCode);
|
self::assertNotEquals($firstShortCode, $secondShortCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideValidShortUrls(): iterable
|
public static function provideValidShortUrls(): iterable
|
||||||
{
|
{
|
||||||
yield 'no custom slug' => [ShortUrl::createFake()];
|
yield 'no custom slug' => [ShortUrl::createFake()];
|
||||||
yield 'imported with custom slug' => [ShortUrl::fromImport(
|
yield 'imported with custom slug' => [ShortUrl::fromImport(
|
||||||
@ -90,7 +90,7 @@ class ShortUrlTest extends TestCase
|
|||||||
self::assertEquals($expectedLength, strlen($shortUrl->getShortCode()));
|
self::assertEquals($expectedLength, strlen($shortUrl->getShortCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideLengths(): iterable
|
public static function provideLengths(): iterable
|
||||||
{
|
{
|
||||||
yield [null, DEFAULT_SHORT_CODES_LENGTH];
|
yield [null, DEFAULT_SHORT_CODES_LENGTH];
|
||||||
yield from map(range(4, 10), fn (int $value) => [$value, $value]);
|
yield from map(range(4, 10), fn (int $value) => [$value, $value]);
|
||||||
|
@ -55,7 +55,7 @@ class ShortCodeUniquenessHelperTest extends TestCase
|
|||||||
self::assertTrue($result);
|
self::assertTrue($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'no domain' => [null, null];
|
yield 'no domain' => [null, null];
|
||||||
yield 'domain' => [Domain::withAuthority($authority = 's.test'), $authority];
|
yield 'domain' => [Domain::withAuthority($authority = 's.test'), $authority];
|
||||||
|
@ -50,7 +50,7 @@ class ShortUrlRedirectionBuilderTest extends TestCase
|
|||||||
self::assertEquals($expectedUrl, $result);
|
self::assertEquals($expectedUrl, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideData(): iterable
|
public static function provideData(): iterable
|
||||||
{
|
{
|
||||||
$request = static fn (array $query = []) => ServerRequestFactory::fromGlobals()->withQueryParams($query);
|
$request = static fn (array $query = []) => ServerRequestFactory::fromGlobals()->withQueryParams($query);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class ShortUrlStringifierTest extends TestCase
|
|||||||
self::assertEquals($expected, $stringifier->stringify($shortUrl));
|
self::assertEquals($expected, $stringifier->stringify($shortUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideConfigAndShortUrls(): iterable
|
public static function provideConfigAndShortUrls(): iterable
|
||||||
{
|
{
|
||||||
$shortUrlWithShortCode = fn (string $shortCode, ?string $domain = null) => ShortUrl::create(
|
$shortUrlWithShortCode = fn (string $shortCode, ?string $domain = null) => ShortUrl::create(
|
||||||
ShortUrlCreation::fromRawData([
|
ShortUrlCreation::fromRawData([
|
||||||
|
@ -42,7 +42,7 @@ class ShortUrlTitleResolutionHelperTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTitles(): iterable
|
public static function provideTitles(): iterable
|
||||||
{
|
{
|
||||||
yield 'no title' => [null, 1, 0];
|
yield 'no title' => [null, 1, 0];
|
||||||
yield 'title' => ['link title', 0, 1];
|
yield 'title' => ['link title', 0, 1];
|
||||||
|
@ -12,7 +12,6 @@ use Mezzio\Router\RouteResult;
|
|||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\MiddlewareInterface;
|
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
||||||
use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
|
use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
|
||||||
@ -26,6 +25,7 @@ use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
|
|||||||
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;
|
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;
|
||||||
use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface;
|
use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface;
|
||||||
|
|
||||||
|
use function Laminas\Stratigility\middleware;
|
||||||
use function str_starts_with;
|
use function str_starts_with;
|
||||||
|
|
||||||
class ExtraPathRedirectMiddlewareTest extends TestCase
|
class ExtraPathRedirectMiddlewareTest extends TestCase
|
||||||
@ -68,7 +68,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase
|
|||||||
$this->middleware($options)->process($request, $this->handler);
|
$this->middleware($options)->process($request, $this->handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonRedirectingRequests(): iterable
|
public static function provideNonRedirectingRequests(): iterable
|
||||||
{
|
{
|
||||||
$baseReq = ServerRequestFactory::fromGlobals();
|
$baseReq = ServerRequestFactory::fromGlobals();
|
||||||
$buildReq = static fn (?NotFoundType $type): ServerRequestInterface =>
|
$buildReq = static fn (?NotFoundType $type): ServerRequestInterface =>
|
||||||
@ -84,7 +84,8 @@ class ExtraPathRedirectMiddlewareTest extends TestCase
|
|||||||
RouteResult::class,
|
RouteResult::class,
|
||||||
RouteResult::fromRoute(new Route(
|
RouteResult::fromRoute(new Route(
|
||||||
'/foo',
|
'/foo',
|
||||||
$this->createMock(MiddlewareInterface::class),
|
middleware(function (): void {
|
||||||
|
}),
|
||||||
['GET'],
|
['GET'],
|
||||||
RedirectAction::class,
|
RedirectAction::class,
|
||||||
)),
|
)),
|
||||||
@ -170,7 +171,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase
|
|||||||
$this->middleware($options)->process($request, $this->handler);
|
$this->middleware($options)->process($request, $this->handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideResolves(): iterable
|
public static function provideResolves(): iterable
|
||||||
{
|
{
|
||||||
yield [false, 1, '/bar/baz'];
|
yield [false, 1, '/bar/baz'];
|
||||||
yield [true, 3, null];
|
yield [true, 3, null];
|
||||||
|
@ -43,7 +43,7 @@ class TrimTrailingSlashMiddlewareTest extends TestCase
|
|||||||
$this->middleware($trailingSlashEnabled)->process($inputRequest, $this->requestHandler);
|
$this->middleware($trailingSlashEnabled)->process($inputRequest, $this->requestHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRequests(): iterable
|
public static function provideRequests(): iterable
|
||||||
{
|
{
|
||||||
yield 'trailing slash disabled' => [
|
yield 'trailing slash disabled' => [
|
||||||
false,
|
false,
|
||||||
|
@ -31,7 +31,7 @@ class ShortUrlCreationTest extends TestCase
|
|||||||
ShortUrlCreation::fromRawData($data);
|
ShortUrlCreation::fromRawData($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidData(): iterable
|
public static function provideInvalidData(): iterable
|
||||||
{
|
{
|
||||||
yield [[]];
|
yield [[]];
|
||||||
yield [[
|
yield [[
|
||||||
@ -136,7 +136,7 @@ class ShortUrlCreationTest extends TestCase
|
|||||||
self::assertNull($creation->maxVisits);
|
self::assertNull($creation->maxVisits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideCustomSlugs(): iterable
|
public static function provideCustomSlugs(): iterable
|
||||||
{
|
{
|
||||||
yield ['🔥', '🔥'];
|
yield ['🔥', '🔥'];
|
||||||
yield ['🦣 🍅', '🦣-🍅'];
|
yield ['🦣 🍅', '🦣-🍅'];
|
||||||
@ -175,7 +175,7 @@ class ShortUrlCreationTest extends TestCase
|
|||||||
self::assertEquals($expectedTitle, $creation->title);
|
self::assertEquals($expectedTitle, $creation->title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTitles(): iterable
|
public static function provideTitles(): iterable
|
||||||
{
|
{
|
||||||
yield [null, null];
|
yield [null, null];
|
||||||
yield ['foo', 'foo'];
|
yield ['foo', 'foo'];
|
||||||
@ -201,7 +201,7 @@ class ShortUrlCreationTest extends TestCase
|
|||||||
self::assertSame($expectedDomain, $creation->domain);
|
self::assertSame($expectedDomain, $creation->domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'null domain' => [null, null];
|
yield 'null domain' => [null, null];
|
||||||
yield 'empty domain' => ['', null];
|
yield 'empty domain' => ['', null];
|
||||||
|
@ -27,7 +27,7 @@ class ShortUrlEditionTest extends TestCase
|
|||||||
self::assertEquals($expectedDevicesToRemove, $edition->devicesToRemove);
|
self::assertEquals($expectedDevicesToRemove, $edition->devicesToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDeviceLongUrls(): iterable
|
public static function provideDeviceLongUrls(): iterable
|
||||||
{
|
{
|
||||||
yield 'null' => [null, [], []];
|
yield 'null' => [null, [], []];
|
||||||
yield 'empty' => [[], [], []];
|
yield 'empty' => [[], [], []];
|
||||||
|
@ -18,7 +18,7 @@ class ShortUrlModeTest extends TestCase
|
|||||||
self::assertSame($expected, ShortUrlMode::tryDeprecated($mode));
|
self::assertSame($expected, ShortUrlMode::tryDeprecated($mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideModes(): iterable
|
public static function provideModes(): iterable
|
||||||
{
|
{
|
||||||
yield 'invalid' => ['invalid', null];
|
yield 'invalid' => ['invalid', null];
|
||||||
yield 'foo' => ['foo', null];
|
yield 'foo' => ['foo', null];
|
||||||
|
@ -29,7 +29,7 @@ class DeviceLongUrlsValidatorTest extends TestCase
|
|||||||
self::assertEquals(['NOT_ARRAY' => 'Provided value is not an array.'], $this->validator->getMessages());
|
self::assertEquals(['NOT_ARRAY' => 'Provided value is not an array.'], $this->validator->getMessages());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonArrayValues(): iterable
|
public static function provideNonArrayValues(): iterable
|
||||||
{
|
{
|
||||||
yield 'int' => [0];
|
yield 'int' => [0];
|
||||||
yield 'float' => [100.45];
|
yield 'float' => [100.45];
|
||||||
|
@ -79,7 +79,7 @@ class ShortUrlRepositoryAdapterTest extends TestCase
|
|||||||
$adapter->getNbResults();
|
$adapter->getNbResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFilteringArgs(): iterable
|
public static function provideFilteringArgs(): iterable
|
||||||
{
|
{
|
||||||
yield [];
|
yield [];
|
||||||
yield ['search'];
|
yield ['search'];
|
||||||
|
@ -55,7 +55,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase
|
|||||||
self::assertEquals($authority, $result->authority);
|
self::assertEquals($authority, $result->authority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFoundDomains(): iterable
|
public static function provideFoundDomains(): iterable
|
||||||
{
|
{
|
||||||
$authority = 's.test';
|
$authority = 's.test';
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase
|
|||||||
self::assertEquals($expectedTags, $result->toArray());
|
self::assertEquals($expectedTags, $result->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTags(): iterable
|
public static function provideTags(): iterable
|
||||||
{
|
{
|
||||||
yield 'no duplicated tags' => [['foo', 'bar', 'baz'], [new Tag('foo'), new Tag('bar'), new Tag('baz')]];
|
yield 'no duplicated tags' => [['foo', 'bar', 'baz'], [new Tag('foo'), new Tag('bar'), new Tag('baz')]];
|
||||||
yield 'duplicated tags' => [['foo', 'bar', 'bar'], [new Tag('foo'), new Tag('bar')]];
|
yield 'duplicated tags' => [['foo', 'bar', 'bar'], [new Tag('foo'), new Tag('bar')]];
|
||||||
|
@ -34,7 +34,7 @@ class SimpleShortUrlRelationResolverTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'empty domain' => [null];
|
yield 'empty domain' => [null];
|
||||||
yield 'non-empty domain' => ['domain.com'];
|
yield 'non-empty domain' => ['domain.com'];
|
||||||
|
@ -113,7 +113,7 @@ class ShortUrlResolverTest extends TestCase
|
|||||||
$this->urlResolver->resolveEnabledShortUrl(ShortUrlIdentifier::fromShortCodeAndDomain($shortCode));
|
$this->urlResolver->resolveEnabledShortUrl(ShortUrlIdentifier::fromShortCodeAndDomain($shortCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDisabledShortUrls(): iterable
|
public static function provideDisabledShortUrls(): iterable
|
||||||
{
|
{
|
||||||
$now = Chronos::now();
|
$now = Chronos::now();
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use Cake\Chronos\Chronos;
|
|||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
|
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
|
||||||
|
use PHPUnit\Framework\MockObject\Rule\InvokedCount;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Shlinkio\Shlink\Core\Model\DeviceType;
|
use Shlinkio\Shlink\Core\Model\DeviceType;
|
||||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||||
@ -93,23 +94,23 @@ class ShortUrlServiceTest extends TestCase
|
|||||||
self::assertEquals($resolveDeviceLongUrls(), $shortUrl->deviceLongUrls());
|
self::assertEquals($resolveDeviceLongUrls(), $shortUrl->deviceLongUrls());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideShortUrlEdits(): iterable
|
public static function provideShortUrlEdits(): iterable
|
||||||
{
|
{
|
||||||
yield 'no long URL' => [$this->never(), ShortUrlEdition::fromRawData([
|
yield 'no long URL' => [new InvokedCount(0), ShortUrlEdition::fromRawData([
|
||||||
'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
||||||
'validUntil' => Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
|
'validUntil' => Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
|
||||||
'maxVisits' => 5,
|
'maxVisits' => 5,
|
||||||
]), null];
|
]), null];
|
||||||
yield 'long URL and API key' => [$this->once(), ShortUrlEdition::fromRawData([
|
yield 'long URL and API key' => [new InvokedCount(1), ShortUrlEdition::fromRawData([
|
||||||
'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
||||||
'maxVisits' => 10,
|
'maxVisits' => 10,
|
||||||
'longUrl' => 'modifiedLongUrl',
|
'longUrl' => 'modifiedLongUrl',
|
||||||
]), ApiKey::create()];
|
]), ApiKey::create()];
|
||||||
yield 'long URL with validation' => [$this->once(), ShortUrlEdition::fromRawData([
|
yield 'long URL with validation' => [new InvokedCount(1), ShortUrlEdition::fromRawData([
|
||||||
'longUrl' => 'modifiedLongUrl',
|
'longUrl' => 'modifiedLongUrl',
|
||||||
'validateUrl' => true,
|
'validateUrl' => true,
|
||||||
]), null];
|
]), null];
|
||||||
yield 'device redirects' => [$this->never(), ShortUrlEdition::fromRawData([
|
yield 'device redirects' => [new InvokedCount(0), ShortUrlEdition::fromRawData([
|
||||||
'deviceLongUrls' => [
|
'deviceLongUrls' => [
|
||||||
DeviceType::IOS->value => 'iosLongUrl',
|
DeviceType::IOS->value => 'iosLongUrl',
|
||||||
DeviceType::ANDROID->value => 'androidLongUrl',
|
DeviceType::ANDROID->value => 'androidLongUrl',
|
||||||
|
@ -33,7 +33,7 @@ class ShortUrlDataTransformerTest extends TestCase
|
|||||||
self::assertEquals($expectedMeta, $meta);
|
self::assertEquals($expectedMeta, $meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideShortUrls(): iterable
|
public static function provideShortUrls(): iterable
|
||||||
{
|
{
|
||||||
$maxVisits = random_int(1, 1000);
|
$maxVisits = random_int(1, 1000);
|
||||||
$now = Chronos::now();
|
$now = Chronos::now();
|
||||||
|
@ -95,7 +95,7 @@ class UrlShortenerTest extends TestCase
|
|||||||
self::assertSame($expected, $result);
|
self::assertSame($expected, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExistingShortUrls(): iterable
|
public static function provideExistingShortUrls(): iterable
|
||||||
{
|
{
|
||||||
$url = 'http://foo.com';
|
$url = 'http://foo.com';
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class TagServiceTest extends TestCase
|
|||||||
self::assertEquals($expected, $result->getCurrentPageResults());
|
self::assertEquals($expected, $result->getCurrentPageResults());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiKeysAndSearchTerm(): iterable
|
public static function provideApiKeysAndSearchTerm(): iterable
|
||||||
{
|
{
|
||||||
yield 'no API key, no filter' => [
|
yield 'no API key, no filter' => [
|
||||||
null,
|
null,
|
||||||
@ -156,7 +156,7 @@ class TagServiceTest extends TestCase
|
|||||||
self::assertEquals($newName, (string) $tag);
|
self::assertEquals($newName, (string) $tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideValidRenames(): iterable
|
public static function provideValidRenames(): iterable
|
||||||
{
|
{
|
||||||
yield 'same names' => ['foo', 'foo', 1];
|
yield 'same names' => ['foo', 'foo', 1];
|
||||||
yield 'different names names' => ['foo', 'bar', 0];
|
yield 'different names names' => ['foo', 'bar', 0];
|
||||||
|
@ -8,7 +8,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
|||||||
|
|
||||||
trait ApiKeyHelpersTrait
|
trait ApiKeyHelpersTrait
|
||||||
{
|
{
|
||||||
public function provideAdminApiKeys(): iterable
|
public static function provideAdminApiKeys(): iterable
|
||||||
{
|
{
|
||||||
yield 'no API key' => [null];
|
yield 'no API key' => [null];
|
||||||
yield 'admin API key' => [ApiKey::create()];
|
yield 'admin API key' => [ApiKey::create()];
|
||||||
|
@ -43,7 +43,7 @@ class DoctrineBatchHelperTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideIterables(): iterable
|
public static function provideIterables(): iterable
|
||||||
{
|
{
|
||||||
yield [[], 100, 1];
|
yield [[], 100, 1];
|
||||||
yield [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3, 4];
|
yield [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3, 4];
|
||||||
|
@ -33,7 +33,7 @@ class RedirectResponseHelperTest extends TestCase
|
|||||||
self::assertEquals($expectedCacheControl ?? '', $response->getHeaderLine('Cache-Control'));
|
self::assertEquals($expectedCacheControl ?? '', $response->getHeaderLine('Cache-Control'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRedirectConfigs(): iterable
|
public static function provideRedirectConfigs(): iterable
|
||||||
{
|
{
|
||||||
yield 'status 302' => [302, 20, 302, null];
|
yield 'status 302' => [302, 20, 302, null];
|
||||||
yield 'status 307' => [307, 20, 307, null];
|
yield 'status 307' => [307, 20, 307, null];
|
||||||
|
@ -22,7 +22,7 @@ class VisitLocationTest extends TestCase
|
|||||||
self::assertEquals($isEmpty, $location->isEmpty());
|
self::assertEquals($isEmpty, $location->isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideArgs(): iterable
|
public static function provideArgs(): iterable
|
||||||
{
|
{
|
||||||
yield [['', '', '', '', 0.0, 0.0, ''], true];
|
yield [['', '', '', '', 0.0, 0.0, ''], true];
|
||||||
yield [['', '', '', '', 0.0, 0.0, 'dd'], false];
|
yield [['', '', '', '', 0.0, 0.0, 'dd'], false];
|
||||||
|
@ -29,7 +29,7 @@ class VisitTest extends TestCase
|
|||||||
], $visit->jsonSerialize());
|
], $visit->jsonSerialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideUserAgents(): iterable
|
public static function provideUserAgents(): iterable
|
||||||
{
|
{
|
||||||
yield 'Chrome' => [
|
yield 'Chrome' => [
|
||||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
|
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
|
||||||
@ -56,7 +56,7 @@ class VisitTest extends TestCase
|
|||||||
self::assertEquals($expectedAddress, $visit->getRemoteAddr());
|
self::assertEquals($expectedAddress, $visit->getRemoteAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideAddresses(): iterable
|
public static function provideAddresses(): iterable
|
||||||
{
|
{
|
||||||
yield 'anonymized null address' => [true, null, null];
|
yield 'anonymized null address' => [true, null, null];
|
||||||
yield 'non-anonymized null address' => [false, null, null];
|
yield 'non-anonymized null address' => [false, null, null];
|
||||||
|
@ -72,7 +72,7 @@ class VisitLocatorTest extends TestCase
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMethodNames(): iterable
|
public static function provideMethodNames(): iterable
|
||||||
{
|
{
|
||||||
yield 'locateUnlocatedVisits' => ['locateUnlocatedVisits', 'findUnlocatedVisits'];
|
yield 'locateUnlocatedVisits' => ['locateUnlocatedVisits', 'findUnlocatedVisits'];
|
||||||
yield 'locateVisitsWithEmptyLocation' => ['locateVisitsWithEmptyLocation', 'findVisitsWithEmptyLocation'];
|
yield 'locateVisitsWithEmptyLocation' => ['locateVisitsWithEmptyLocation', 'findVisitsWithEmptyLocation'];
|
||||||
@ -120,7 +120,7 @@ class VisitLocatorTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideIsNonLocatableAddress(): iterable
|
public static function provideIsNonLocatableAddress(): iterable
|
||||||
{
|
{
|
||||||
yield 'locateUnlocatedVisits - locatable address' => ['locateUnlocatedVisits', 'findUnlocatedVisits', false];
|
yield 'locateUnlocatedVisits - locatable address' => ['locateUnlocatedVisits', 'findUnlocatedVisits', false];
|
||||||
yield 'locateUnlocatedVisits - non-locatable address' => ['locateUnlocatedVisits', 'findUnlocatedVisits', true];
|
yield 'locateUnlocatedVisits - non-locatable address' => ['locateUnlocatedVisits', 'findUnlocatedVisits', true];
|
||||||
|
@ -39,7 +39,7 @@ class VisitToLocationHelperTest extends TestCase
|
|||||||
$this->helper->resolveVisitLocation($visit);
|
$this->helper->resolveVisitLocation($visit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonLocatableVisits(): iterable
|
public static function provideNonLocatableVisits(): iterable
|
||||||
{
|
{
|
||||||
yield [Visit::forBasePath(Visitor::emptyInstance()), IpCannotBeLocatedException::forEmptyAddress()];
|
yield [Visit::forBasePath(Visitor::emptyInstance()), IpCannotBeLocatedException::forEmptyAddress()];
|
||||||
yield [
|
yield [
|
||||||
|
@ -29,7 +29,7 @@ class VisitorTest extends TestCase
|
|||||||
self::assertEquals($remoteAddress, $visitor->remoteAddress);
|
self::assertEquals($remoteAddress, $visitor->remoteAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideParams(): iterable
|
public static function provideParams(): iterable
|
||||||
{
|
{
|
||||||
yield 'all values are bigger' => [
|
yield 'all values are bigger' => [
|
||||||
[str_repeat('a', 1000), str_repeat('b', 2000), str_repeat('c', 500), ''],
|
[str_repeat('a', 1000), str_repeat('b', 2000), str_repeat('c', 500), ''],
|
||||||
@ -49,8 +49,8 @@ class VisitorTest extends TestCase
|
|||||||
];
|
];
|
||||||
yield 'random strings' => [
|
yield 'random strings' => [
|
||||||
[
|
[
|
||||||
$userAgent = $this->generateRandomString(2000),
|
$userAgent = self::generateRandomString(2000),
|
||||||
$referer = $this->generateRandomString(50),
|
$referer = self::generateRandomString(50),
|
||||||
null,
|
null,
|
||||||
'',
|
'',
|
||||||
],
|
],
|
||||||
@ -62,7 +62,7 @@ class VisitorTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateRandomString(int $length): string
|
private static function generateRandomString(int $length): string
|
||||||
{
|
{
|
||||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
$charactersLength = strlen($characters);
|
$charactersLength = strlen($characters);
|
||||||
@ -77,10 +77,10 @@ class VisitorTest extends TestCase
|
|||||||
public function newNormalizedInstanceIsCreatedFromTrackingOptions(): void
|
public function newNormalizedInstanceIsCreatedFromTrackingOptions(): void
|
||||||
{
|
{
|
||||||
$visitor = new Visitor(
|
$visitor = new Visitor(
|
||||||
$this->generateRandomString(2000),
|
self::generateRandomString(2000),
|
||||||
$this->generateRandomString(2000),
|
self::generateRandomString(2000),
|
||||||
$this->generateRandomString(2000),
|
self::generateRandomString(2000),
|
||||||
$this->generateRandomString(2000),
|
self::generateRandomString(2000),
|
||||||
);
|
);
|
||||||
$normalizedVisitor = $visitor->normalizeForTrackingOptions(new TrackingOptions(
|
$normalizedVisitor = $visitor->normalizeForTrackingOptions(new TrackingOptions(
|
||||||
disableIpTracking: true,
|
disableIpTracking: true,
|
||||||
|
@ -67,7 +67,7 @@ class NonOrphanVisitsPaginatorAdapterTest extends TestCase
|
|||||||
self::assertEquals($list, $result);
|
self::assertEquals($list, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideLimitAndOffset(): iterable
|
public static function provideLimitAndOffset(): iterable
|
||||||
{
|
{
|
||||||
yield [1, 5];
|
yield [1, 5];
|
||||||
yield [10, 4];
|
yield [10, 4];
|
||||||
|
@ -59,7 +59,7 @@ class OrphanVisitsPaginatorAdapterTest extends TestCase
|
|||||||
self::assertEquals($list, $result);
|
self::assertEquals($list, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideLimitAndOffset(): iterable
|
public static function provideLimitAndOffset(): iterable
|
||||||
{
|
{
|
||||||
yield [1, 5];
|
yield [1, 5];
|
||||||
yield [10, 4];
|
yield [10, 4];
|
||||||
|
@ -57,7 +57,7 @@ class RequestTrackerTest extends TestCase
|
|||||||
$this->requestTracker->trackIfApplicable($shortUrl, $request);
|
$this->requestTracker->trackIfApplicable($shortUrl, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonTrackingRequests(): iterable
|
public static function provideNonTrackingRequests(): iterable
|
||||||
{
|
{
|
||||||
yield 'forwarded from head' => [ServerRequestFactory::fromGlobals()->withAttribute(
|
yield 'forwarded from head' => [ServerRequestFactory::fromGlobals()->withAttribute(
|
||||||
ImplicitHeadMiddleware::FORWARDED_HTTP_METHOD_ATTRIBUTE,
|
ImplicitHeadMiddleware::FORWARDED_HTTP_METHOD_ATTRIBUTE,
|
||||||
|
@ -34,7 +34,7 @@ class OrphanVisitDataTransformerTest extends TestCase
|
|||||||
self::assertEquals($expectedResult, $result);
|
self::assertEquals($expectedResult, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideVisits(): iterable
|
public static function provideVisits(): iterable
|
||||||
{
|
{
|
||||||
yield 'base path visit' => [
|
yield 'base path visit' => [
|
||||||
$visit = Visit::forBasePath(Visitor::emptyInstance()),
|
$visit = Visit::forBasePath(Visitor::emptyInstance()),
|
||||||
|
@ -6,6 +6,7 @@ namespace ShlinkioTest\Shlink\Core\Visit;
|
|||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Laminas\Stdlib\ArrayUtils;
|
use Laminas\Stdlib\ArrayUtils;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
|
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
|
||||||
@ -53,13 +54,17 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
public function returnsExpectedVisitsStats(int $expectedCount): void
|
public function returnsExpectedVisitsStats(int $expectedCount): void
|
||||||
{
|
{
|
||||||
$repo = $this->createMock(VisitRepository::class);
|
$repo = $this->createMock(VisitRepository::class);
|
||||||
$repo->expects($this->exactly(2))->method('countNonOrphanVisits')->withConsecutive(
|
$callCount = 0;
|
||||||
[new VisitsCountFiltering()],
|
$repo->expects($this->exactly(2))->method('countNonOrphanVisits')->willReturnCallback(
|
||||||
[new VisitsCountFiltering(excludeBots: true)],
|
function (VisitsCountFiltering $options) use ($expectedCount, &$callCount) {
|
||||||
)->willReturn($expectedCount * 3);
|
Assert::assertEquals($callCount !== 0, $options->excludeBots);
|
||||||
$repo->expects($this->exactly(2))->method('countOrphanVisits')->withConsecutive(
|
$callCount++;
|
||||||
[$this->isInstanceOf(VisitsCountFiltering::class)],
|
|
||||||
[$this->isInstanceOf(VisitsCountFiltering::class)],
|
return $expectedCount * 3;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
$repo->expects($this->exactly(2))->method('countOrphanVisits')->with(
|
||||||
|
$this->isInstanceOf(VisitsCountFiltering::class),
|
||||||
)->willReturn($expectedCount);
|
)->willReturn($expectedCount);
|
||||||
$this->em->expects($this->once())->method('getRepository')->with(Visit::class)->willReturn($repo);
|
$this->em->expects($this->once())->method('getRepository')->with(Visit::class)->willReturn($repo);
|
||||||
|
|
||||||
@ -68,7 +73,7 @@ class VisitsStatsHelperTest extends TestCase
|
|||||||
self::assertEquals(new VisitsStats($expectedCount * 3, $expectedCount), $stats);
|
self::assertEquals(new VisitsStats($expectedCount * 3, $expectedCount), $stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideCounts(): iterable
|
public static function provideCounts(): iterable
|
||||||
{
|
{
|
||||||
return map(range(0, 50, 5), fn (int $value) => [$value]);
|
return map(range(0, 50, 5), fn (int $value) => [$value]);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ class VisitsTrackerTest extends TestCase
|
|||||||
$this->visitsTracker(new TrackingOptions(disableTracking: true))->{$method}(...$args);
|
$this->visitsTracker(new TrackingOptions(disableTracking: true))->{$method}(...$args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTrackingMethodNames(): iterable
|
public static function provideTrackingMethodNames(): iterable
|
||||||
{
|
{
|
||||||
yield 'track' => ['track', [ShortUrl::createFake(), Visitor::emptyInstance()]];
|
yield 'track' => ['track', [ShortUrl::createFake(), Visitor::emptyInstance()]];
|
||||||
yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit', [Visitor::emptyInstance()]];
|
yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit', [Visitor::emptyInstance()]];
|
||||||
@ -77,7 +77,7 @@ class VisitsTrackerTest extends TestCase
|
|||||||
$this->visitsTracker(new TrackingOptions(trackOrphanVisits: false))->{$method}(Visitor::emptyInstance());
|
$this->visitsTracker(new TrackingOptions(trackOrphanVisits: false))->{$method}(Visitor::emptyInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideOrphanTrackingMethodNames(): iterable
|
public static function provideOrphanTrackingMethodNames(): iterable
|
||||||
{
|
{
|
||||||
yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit'];
|
yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit'];
|
||||||
yield 'trackBaseUrlVisit' => ['trackBaseUrlVisit'];
|
yield 'trackBaseUrlVisit' => ['trackBaseUrlVisit'];
|
||||||
|
@ -72,7 +72,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedType, $payload['type']);
|
self::assertEquals($expectedType, $payload['type']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDuplicatedSlugApiVersions(): iterable
|
public static function provideDuplicatedSlugApiVersions(): iterable
|
||||||
{
|
{
|
||||||
yield ['1', 'INVALID_SLUG'];
|
yield ['1', 'INVALID_SLUG'];
|
||||||
yield ['2', 'INVALID_SLUG'];
|
yield ['2', 'INVALID_SLUG'];
|
||||||
@ -91,7 +91,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedTags, $tags);
|
self::assertEquals($expectedTags, $tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTags(): iterable
|
public static function provideTags(): iterable
|
||||||
{
|
{
|
||||||
yield 'simple tags' => [$simpleTags = ['foo', 'bar', 'baz'], $simpleTags];
|
yield 'simple tags' => [$simpleTags = ['foo', 'bar', 'baz'], $simpleTags];
|
||||||
yield 'tags with spaces' => [['fo o', ' bar', 'b az'], ['fo-o', 'bar', 'b-az']];
|
yield 'tags with spaces' => [['fo o', ' bar', 'b az'], ['fo-o', 'bar', 'b-az']];
|
||||||
@ -116,7 +116,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals(self::STATUS_NOT_FOUND, $lastResp->getStatusCode());
|
self::assertEquals(self::STATUS_NOT_FOUND, $lastResp->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMaxVisits(): array
|
public static function provideMaxVisits(): array
|
||||||
{
|
{
|
||||||
return map(range(10, 15), fn(int $i) => [$i]);
|
return map(range(10, 15), fn(int $i) => [$i]);
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($firstShortCode, $secondShortCode);
|
self::assertEquals($firstShortCode, $secondShortCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMatchingBodies(): iterable
|
public static function provideMatchingBodies(): iterable
|
||||||
{
|
{
|
||||||
$longUrl = 'https://www.alejandrocelaya.com';
|
$longUrl = 'https://www.alejandrocelaya.com';
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals(self::STATUS_BAD_REQUEST, $secondStatusCode);
|
self::assertEquals(self::STATUS_BAD_REQUEST, $secondStatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideConflictingSlugs(): iterable
|
public static function provideConflictingSlugs(): iterable
|
||||||
{
|
{
|
||||||
yield 'without domain' => ['custom', null];
|
yield 'without domain' => ['custom', null];
|
||||||
yield 'with domain' => ['custom-with-domain', 'some-domain.com'];
|
yield 'with domain' => ['custom-with-domain', 'some-domain.com'];
|
||||||
@ -236,7 +236,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($payload['longUrl'], $longUrl);
|
self::assertEquals($payload['longUrl'], $longUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideIdn(): iterable
|
public static function provideIdn(): iterable
|
||||||
{
|
{
|
||||||
yield ['http://tést.shlink.io']; // Redirects to https://shlink.io
|
yield ['http://tést.shlink.io']; // Redirects to https://shlink.io
|
||||||
yield ['http://test.shlink.io']; // Redirects to http://tést.shlink.io
|
yield ['http://test.shlink.io']; // Redirects to http://tést.shlink.io
|
||||||
@ -261,7 +261,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($url, $payload['url']);
|
self::assertEquals($url, $payload['url']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidUrls(): iterable
|
public static function provideInvalidUrls(): iterable
|
||||||
{
|
{
|
||||||
yield 'API version 2' => ['https://this-has-to-be-invalid.com', '2', 'INVALID_URL'];
|
yield 'API version 2' => ['https://this-has-to-be-invalid.com', '2', 'INVALID_URL'];
|
||||||
yield 'API version 3' => ['https://this-has-to-be-invalid.com', '3', 'https://shlink.io/api/error/invalid-url'];
|
yield 'API version 3' => ['https://this-has-to-be-invalid.com', '3', 'https://shlink.io/api/error/invalid-url'];
|
||||||
@ -287,7 +287,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals('Invalid data', $payload['title']);
|
self::assertEquals('Invalid data', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidArgumentApiVersions(): iterable
|
public static function provideInvalidArgumentApiVersions(): iterable
|
||||||
{
|
{
|
||||||
yield 'missing long url v2' => [[], '2', 'INVALID_ARGUMENT'];
|
yield 'missing long url v2' => [[], '2', 'INVALID_ARGUMENT'];
|
||||||
yield 'missing long url v3' => [[], '3', 'https://shlink.io/api/error/invalid-data'];
|
yield 'missing long url v3' => [[], '3', 'https://shlink.io/api/error/invalid-data'];
|
||||||
@ -338,7 +338,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals('example.com', $returnedDomain);
|
self::assertEquals('example.com', $returnedDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'no domain' => [null];
|
yield 'no domain' => [null];
|
||||||
yield 'invalid domain' => ['this-will-be-overwritten.com'];
|
yield 'invalid domain' => ['this-will-be-overwritten.com'];
|
||||||
@ -355,7 +355,7 @@ class CreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals(self::STATUS_OK, $statusCode);
|
self::assertEquals(self::STATUS_OK, $statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTwitterUrls(): iterable
|
public static function provideTwitterUrls(): iterable
|
||||||
{
|
{
|
||||||
yield ['https://twitter.com/shlinkio'];
|
yield ['https://twitter.com/shlinkio'];
|
||||||
yield ['https://mobile.twitter.com/shlinkio'];
|
yield ['https://mobile.twitter.com/shlinkio'];
|
||||||
|
@ -50,7 +50,7 @@ class DeleteShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedType, $payload['type']);
|
self::assertEquals($expectedType, $payload['type']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiVersions(): iterable
|
public static function provideApiVersions(): iterable
|
||||||
{
|
{
|
||||||
yield ['1', 'INVALID_SHORTCODE'];
|
yield ['1', 'INVALID_SHORTCODE'];
|
||||||
yield ['2', 'INVALID_SHORTCODE'];
|
yield ['2', 'INVALID_SHORTCODE'];
|
||||||
|
@ -29,7 +29,7 @@ class DeleteTagsTest extends ApiTestCase
|
|||||||
self::assertEquals('Forbidden tag operation', $payload['title']);
|
self::assertEquals('Forbidden tag operation', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonAdminApiKeys(): iterable
|
public static function provideNonAdminApiKeys(): iterable
|
||||||
{
|
{
|
||||||
yield 'author' => ['author_api_key', '2', 'FORBIDDEN_OPERATION'];
|
yield 'author' => ['author_api_key', '2', 'FORBIDDEN_OPERATION'];
|
||||||
yield 'domain' => ['domain_api_key', '2', 'FORBIDDEN_OPERATION'];
|
yield 'domain' => ['domain_api_key', '2', 'FORBIDDEN_OPERATION'];
|
||||||
|
@ -27,7 +27,7 @@ class DomainRedirectsTest extends ApiTestCase
|
|||||||
self::assertEquals('Invalid data', $payload['title']);
|
self::assertEquals('Invalid data', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidDomains(): iterable
|
public static function provideInvalidDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'no domain' => [[]];
|
yield 'no domain' => [[]];
|
||||||
yield 'empty domain' => [['domain' => '']];
|
yield 'empty domain' => [['domain' => '']];
|
||||||
@ -50,7 +50,7 @@ class DomainRedirectsTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedResponse, $payload);
|
self::assertEquals($expectedResponse, $payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRequests(): iterable
|
public static function provideRequests(): iterable
|
||||||
{
|
{
|
||||||
yield 'new domain' => [[
|
yield 'new domain' => [[
|
||||||
'domain' => 'my-new-domain.com',
|
'domain' => 'my-new-domain.com',
|
||||||
|
@ -32,7 +32,7 @@ class DomainVisitsTest extends ApiTestCase
|
|||||||
self::assertCount($expectedVisitsAmount, $payload['visits']['data']);
|
self::assertCount($expectedVisitsAmount, $payload['visits']['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'example.com with admin API key' => ['valid_api_key', 'example.com', false, 0];
|
yield 'example.com with admin API key' => ['valid_api_key', 'example.com', false, 0];
|
||||||
yield 'DEFAULT with admin API key' => ['valid_api_key', 'DEFAULT', false, 7];
|
yield 'DEFAULT with admin API key' => ['valid_api_key', 'DEFAULT', false, 7];
|
||||||
@ -59,7 +59,7 @@ class DomainVisitsTest extends ApiTestCase
|
|||||||
self::assertEquals($domain, $payload['authority']);
|
self::assertEquals($domain, $payload['authority']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiKeysAndTags(): iterable
|
public static function provideApiKeysAndTags(): iterable
|
||||||
{
|
{
|
||||||
yield 'admin API key with invalid domain' => ['valid_api_key', 'invalid_domain.com'];
|
yield 'admin API key with invalid domain' => ['valid_api_key', 'invalid_domain.com'];
|
||||||
yield 'domain API key with not-owned valid domain' => ['domain_api_key', 'this_domain_is_detached.com'];
|
yield 'domain API key with not-owned valid domain' => ['domain_api_key', 'this_domain_is_detached.com'];
|
||||||
@ -78,7 +78,7 @@ class DomainVisitsTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedType, $payload['type']);
|
self::assertEquals($expectedType, $payload['type']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiVersions(): iterable
|
public static function provideApiVersions(): iterable
|
||||||
{
|
{
|
||||||
yield ['1', 'DOMAIN_NOT_FOUND'];
|
yield ['1', 'DOMAIN_NOT_FOUND'];
|
||||||
yield ['2', 'DOMAIN_NOT_FOUND'];
|
yield ['2', 'DOMAIN_NOT_FOUND'];
|
||||||
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||||||
namespace ShlinkioApiTest\Shlink\Rest\Action;
|
namespace ShlinkioApiTest\Shlink\Rest\Action;
|
||||||
|
|
||||||
use Cake\Chronos\Chronos;
|
use Cake\Chronos\Chronos;
|
||||||
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
|
||||||
use GuzzleHttp\Psr7\Query;
|
use GuzzleHttp\Psr7\Query;
|
||||||
use GuzzleHttp\RequestOptions;
|
use GuzzleHttp\RequestOptions;
|
||||||
use Laminas\Diactoros\Uri;
|
use Laminas\Diactoros\Uri;
|
||||||
@ -16,7 +15,6 @@ use function sprintf;
|
|||||||
|
|
||||||
class EditShortUrlTest extends ApiTestCase
|
class EditShortUrlTest extends ApiTestCase
|
||||||
{
|
{
|
||||||
use ArraySubsetAsserts;
|
|
||||||
use NotFoundUrlHelpersTrait;
|
use NotFoundUrlHelpersTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +45,14 @@ class EditShortUrlTest extends ApiTestCase
|
|||||||
self::assertArraySubset($meta, $metaAfterEditing);
|
self::assertArraySubset($meta, $metaAfterEditing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideMeta(): iterable
|
private static function assertArraySubset(array $a, array $b): void
|
||||||
|
{
|
||||||
|
foreach ($a as $key => $expectedValue) {
|
||||||
|
self::assertEquals($expectedValue, $b[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function provideMeta(): iterable
|
||||||
{
|
{
|
||||||
$now = Chronos::now();
|
$now = Chronos::now();
|
||||||
|
|
||||||
@ -92,7 +97,7 @@ class EditShortUrlTest extends ApiTestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideLongUrls(): iterable
|
public static function provideLongUrls(): iterable
|
||||||
{
|
{
|
||||||
yield 'valid URL' => ['https://shlink.io', self::STATUS_OK, null];
|
yield 'valid URL' => ['https://shlink.io', self::STATUS_OK, null];
|
||||||
yield 'invalid URL' => ['htt:foo', self::STATUS_BAD_REQUEST, 'INVALID_URL'];
|
yield 'invalid URL' => ['htt:foo', self::STATUS_BAD_REQUEST, 'INVALID_URL'];
|
||||||
@ -162,7 +167,7 @@ class EditShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals(100, $editedShortUrl['meta']['maxVisits'] ?? null);
|
self::assertEquals(100, $editedShortUrl['meta']['maxVisits'] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'domain' => [
|
yield 'domain' => [
|
||||||
'example.com',
|
'example.com',
|
||||||
|
@ -24,7 +24,7 @@ class GlobalVisitsTest extends ApiTestCase
|
|||||||
self::assertEquals(3, $payload['visits']['orphanVisitsCount']);
|
self::assertEquals(3, $payload['visits']['orphanVisitsCount']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiKeys(): iterable
|
public static function provideApiKeys(): iterable
|
||||||
{
|
{
|
||||||
yield 'admin API key' => ['valid_api_key', 7];
|
yield 'admin API key' => ['valid_api_key', 7];
|
||||||
yield 'domain API key' => ['domain_api_key', 0];
|
yield 'domain API key' => ['domain_api_key', 0];
|
||||||
|
@ -30,7 +30,7 @@ class ListDomainsTest extends ApiTestCase
|
|||||||
], $respPayload);
|
], $respPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiKeysAndDomains(): iterable
|
public static function provideApiKeysAndDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'admin API key' => ['valid_api_key', [
|
yield 'admin API key' => ['valid_api_key', [
|
||||||
[
|
[
|
||||||
|
@ -168,7 +168,7 @@ class ListShortUrlsTest extends ApiTestCase
|
|||||||
], $respPayload);
|
], $respPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFilteredLists(): iterable
|
public static function provideFilteredLists(): iterable
|
||||||
{
|
{
|
||||||
// FIXME Cannot use enums in constants in PHP 8.1. Change this once support for PHP 8.1 is dropped
|
// FIXME Cannot use enums in constants in PHP 8.1. Change this once support for PHP 8.1 is dropped
|
||||||
$withDeviceLongUrls = static fn (array $shortUrl, ?array $longUrls = null) => [
|
$withDeviceLongUrls = static fn (array $shortUrl, ?array $longUrls = null) => [
|
||||||
@ -321,7 +321,7 @@ class ListShortUrlsTest extends ApiTestCase
|
|||||||
], $respPayload);
|
], $respPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidFiltering(): iterable
|
public static function provideInvalidFiltering(): iterable
|
||||||
{
|
{
|
||||||
yield [['tagsMode' => 'invalid'], ['tagsMode']];
|
yield [['tagsMode' => 'invalid'], ['tagsMode']];
|
||||||
yield [['orderBy' => 'invalid'], ['orderBy']];
|
yield [['orderBy' => 'invalid'], ['orderBy']];
|
||||||
|
@ -21,7 +21,7 @@ class ListTagsTest extends ApiTestCase
|
|||||||
self::assertEquals(['tags' => $expectedTags], $payload);
|
self::assertEquals(['tags' => $expectedTags], $payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideQueries(): iterable
|
public static function provideQueries(): iterable
|
||||||
{
|
{
|
||||||
yield 'admin API key' => ['valid_api_key', [], [
|
yield 'admin API key' => ['valid_api_key', [], [
|
||||||
'data' => ['bar', 'baz', 'foo'],
|
'data' => ['bar', 'baz', 'foo'],
|
||||||
|
@ -24,7 +24,7 @@ class NonOrphanVisitsTest extends ApiTestCase
|
|||||||
self::assertCount($returnedItems, $payload['visits']['data'] ?? []);
|
self::assertCount($returnedItems, $payload['visits']['data'] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideQueries(): iterable
|
public static function provideQueries(): iterable
|
||||||
{
|
{
|
||||||
yield 'all data' => [[], 7, 7];
|
yield 'all data' => [[], 7, 7];
|
||||||
yield 'middle page' => [['page' => 2, 'itemsPerPage' => 3], 7, 3];
|
yield 'middle page' => [['page' => 2, 'itemsPerPage' => 3], 7, 3];
|
||||||
|
@ -57,7 +57,7 @@ class OrphanVisitsTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedVisits, $visits);
|
self::assertEquals($expectedVisits, $visits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideQueries(): iterable
|
public static function provideQueries(): iterable
|
||||||
{
|
{
|
||||||
yield 'all data' => [[], 3, 3, [self::INVALID_SHORT_URL, self::REGULAR_NOT_FOUND, self::BASE_URL]];
|
yield 'all data' => [[], 3, 3, [self::INVALID_SHORT_URL, self::REGULAR_NOT_FOUND, self::BASE_URL]];
|
||||||
yield 'limit items' => [['itemsPerPage' => 2], 3, 2, [self::INVALID_SHORT_URL, self::REGULAR_NOT_FOUND]];
|
yield 'limit items' => [['itemsPerPage' => 2], 3, 2, [self::INVALID_SHORT_URL, self::REGULAR_NOT_FOUND]];
|
||||||
|
@ -30,7 +30,7 @@ class RenameTagTest extends ApiTestCase
|
|||||||
self::assertEquals('Forbidden tag operation', $payload['title']);
|
self::assertEquals('Forbidden tag operation', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideNonAdminApiKeys(): iterable
|
public static function provideNonAdminApiKeys(): iterable
|
||||||
{
|
{
|
||||||
yield 'author' => ['author_api_key'];
|
yield 'author' => ['author_api_key'];
|
||||||
yield 'domain' => ['domain_api_key'];
|
yield 'domain' => ['domain_api_key'];
|
||||||
|
@ -34,7 +34,7 @@ class ResolveShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals(self::STATUS_OK, $fetchResp->getStatusCode());
|
self::assertEquals(self::STATUS_OK, $fetchResp->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDisabledMeta(): iterable
|
public static function provideDisabledMeta(): iterable
|
||||||
{
|
{
|
||||||
$now = Chronos::now();
|
$now = Chronos::now();
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class ShortUrlVisitsTest extends ApiTestCase
|
|||||||
self::assertCount($expectedAmountOfVisits, $payload['visits']['data'] ?? []);
|
self::assertCount($expectedAmountOfVisits, $payload['visits']['data'] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDomains(): iterable
|
public static function provideDomains(): iterable
|
||||||
{
|
{
|
||||||
yield 'domain' => ['example.com', 0];
|
yield 'domain' => ['example.com', 0];
|
||||||
yield 'no domain' => [null, 2];
|
yield 'no domain' => [null, 2];
|
||||||
@ -95,7 +95,7 @@ class ShortUrlVisitsTest extends ApiTestCase
|
|||||||
self::assertCount($expectedAmountOfVisits, $payload['visits']['data'] ?? []);
|
self::assertCount($expectedAmountOfVisits, $payload['visits']['data'] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideVisitsForBots(): iterable
|
public static function provideVisitsForBots(): iterable
|
||||||
{
|
{
|
||||||
yield 'bots excluded' => [true, 1];
|
yield 'bots excluded' => [true, 1];
|
||||||
yield 'bots not excluded' => [false, 2];
|
yield 'bots not excluded' => [false, 2];
|
||||||
|
@ -22,7 +22,7 @@ class SingleStepCreateShortUrlTest extends ApiTestCase
|
|||||||
self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type'));
|
self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideFormats(): iterable
|
public static function provideFormats(): iterable
|
||||||
{
|
{
|
||||||
yield 'txt format' => ['txt', 'text/plain'];
|
yield 'txt format' => ['txt', 'text/plain'];
|
||||||
yield 'json format' => ['json', 'application/json'];
|
yield 'json format' => ['json', 'application/json'];
|
||||||
|
@ -32,7 +32,7 @@ class TagVisitsTest extends ApiTestCase
|
|||||||
self::assertCount($expectedVisitsAmount, $payload['visits']['data']);
|
self::assertCount($expectedVisitsAmount, $payload['visits']['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTags(): iterable
|
public static function provideTags(): iterable
|
||||||
{
|
{
|
||||||
yield 'foo with admin API key' => ['valid_api_key', 'foo', false, 5];
|
yield 'foo with admin API key' => ['valid_api_key', 'foo', false, 5];
|
||||||
yield 'foo with admin API key and no bots' => ['valid_api_key', 'foo', true, 4];
|
yield 'foo with admin API key and no bots' => ['valid_api_key', 'foo', true, 4];
|
||||||
@ -62,7 +62,7 @@ class TagVisitsTest extends ApiTestCase
|
|||||||
self::assertEquals('Tag not found', $payload['title']);
|
self::assertEquals('Tag not found', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideApiKeysAndTags(): iterable
|
public static function provideApiKeysAndTags(): iterable
|
||||||
{
|
{
|
||||||
yield 'admin API key with invalid tag' => ['valid_api_key', 'invalid_tag'];
|
yield 'admin API key with invalid tag' => ['valid_api_key', 'invalid_tag'];
|
||||||
yield 'domain API key with valid tag not used' => ['domain_api_key', 'bar'];
|
yield 'domain API key with valid tag not used' => ['domain_api_key', 'bar'];
|
||||||
|
@ -45,7 +45,7 @@ class TagsStatsTest extends ApiTestCase
|
|||||||
self::assertArrayHasKey('data', $tags);
|
self::assertArrayHasKey('data', $tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideQueries(): iterable
|
public static function provideQueries(): iterable
|
||||||
{
|
{
|
||||||
yield 'admin API key' => ['valid_api_key', [], [
|
yield 'admin API key' => ['valid_api_key', [], [
|
||||||
[
|
[
|
||||||
|
@ -29,7 +29,7 @@ class UpdateTagTest extends ApiTestCase
|
|||||||
self::assertEquals('Invalid data', $payload['title']);
|
self::assertEquals('Invalid data', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideInvalidBody(): iterable
|
public static function provideInvalidBody(): iterable
|
||||||
{
|
{
|
||||||
yield [[]];
|
yield [[]];
|
||||||
yield [['oldName' => 'foo']];
|
yield [['oldName' => 'foo']];
|
||||||
@ -57,7 +57,7 @@ class UpdateTagTest extends ApiTestCase
|
|||||||
self::assertEquals('Tag not found', $payload['title']);
|
self::assertEquals('Tag not found', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTagNotFoundApiVersions(): iterable
|
public static function provideTagNotFoundApiVersions(): iterable
|
||||||
{
|
{
|
||||||
yield 'version 1' => ['1', 'TAG_NOT_FOUND'];
|
yield 'version 1' => ['1', 'TAG_NOT_FOUND'];
|
||||||
yield 'version 2' => ['2', 'TAG_NOT_FOUND'];
|
yield 'version 2' => ['2', 'TAG_NOT_FOUND'];
|
||||||
@ -85,7 +85,7 @@ class UpdateTagTest extends ApiTestCase
|
|||||||
self::assertEquals('Tag conflict', $payload['title']);
|
self::assertEquals('Tag conflict', $payload['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTagConflictsApiVersions(): iterable
|
public static function provideTagConflictsApiVersions(): iterable
|
||||||
{
|
{
|
||||||
yield 'version 1' => ['1', 'TAG_CONFLICT'];
|
yield 'version 1' => ['1', 'TAG_CONFLICT'];
|
||||||
yield 'version 2' => ['2', 'TAG_CONFLICT'];
|
yield 'version 2' => ['2', 'TAG_CONFLICT'];
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user