mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-22 08:56:42 -06:00
Add API tests to cover usage of orphan visits restricted keys
This commit is contained in:
parent
eaba5edf7f
commit
be26dd58c3
@ -32,7 +32,7 @@ class RoleResolver implements RoleResolverInterface
|
||||
$roleDefinitions[] = $this->resolveRoleForAuthority($domainAuthority);
|
||||
}
|
||||
if ($noOrphanVisits) {
|
||||
$roleDefinitions[] = RoleDefinition::forOrphanVisitsExcluded();
|
||||
$roleDefinitions[] = RoleDefinition::forNoOrphanVisits();
|
||||
}
|
||||
|
||||
return $roleDefinitions;
|
||||
|
@ -262,7 +262,7 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$noOrphanVisitsApiKey = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forOrphanVisitsExcluded()));
|
||||
$noOrphanVisitsApiKey = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forNoOrphanVisits()));
|
||||
$this->getEntityManager()->persist($noOrphanVisitsApiKey);
|
||||
|
||||
$apiKey1 = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forAuthoredShortUrls()));
|
||||
@ -330,7 +330,7 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
$this->createVisitsForShortUrl($shortUrl, 7);
|
||||
|
||||
$noOrphanVisitsApiKey = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forOrphanVisitsExcluded()));
|
||||
$noOrphanVisitsApiKey = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forNoOrphanVisits()));
|
||||
$this->getEntityManager()->persist($noOrphanVisitsApiKey);
|
||||
|
||||
$botsCount = 3;
|
||||
|
@ -48,7 +48,7 @@ class VisitsDeleterTest extends TestCase
|
||||
$this->repo->expects($this->never())->method('deleteOrphanVisits');
|
||||
|
||||
$result = $this->visitsDeleter->deleteOrphanVisits(
|
||||
ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forOrphanVisitsExcluded())),
|
||||
ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forNoOrphanVisits())),
|
||||
);
|
||||
|
||||
self::assertEquals(0, $result->affectedItems);
|
||||
|
@ -26,7 +26,7 @@ final class RoleDefinition
|
||||
);
|
||||
}
|
||||
|
||||
public static function forOrphanVisitsExcluded(): self
|
||||
public static function forNoOrphanVisits(): self
|
||||
{
|
||||
return new self(Role::NO_ORPHAN_VISITS, []);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
|
||||
class DeleteOrphanVisitsTest extends ApiTestCase
|
||||
{
|
||||
#[Test]
|
||||
public function deletesVisitsForShortUrlWithoutAffectingTheRest(): void
|
||||
public function deletesOrphanVisitsWithoutAffectingTheRest(): void
|
||||
{
|
||||
self::assertEquals(7, $this->getTotalVisits());
|
||||
self::assertEquals(3, $this->getOrphanVisits());
|
||||
@ -24,6 +24,21 @@ class DeleteOrphanVisitsTest extends ApiTestCase
|
||||
self::assertEquals(0, $this->getOrphanVisits());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function doesNotDeleteOrphanVisitsForRestrictedApiKey(): void
|
||||
{
|
||||
self::assertEquals(7, $this->getTotalVisits());
|
||||
self::assertEquals(3, $this->getOrphanVisits());
|
||||
|
||||
$resp = $this->callApiWithKey(self::METHOD_DELETE, '/visits/orphan', apiKey: 'no_orphans_api_key');
|
||||
$payload = $this->getJsonResponsePayload($resp);
|
||||
|
||||
self::assertEquals(200, $resp->getStatusCode());
|
||||
self::assertEquals(0, $payload['deletedVisits']);
|
||||
self::assertEquals(7, $this->getTotalVisits()); // This verifies that regular visits have not been affected
|
||||
self::assertEquals(3, $this->getOrphanVisits()); // This verifies that all orphan visits still exist
|
||||
}
|
||||
|
||||
private function getTotalVisits(): int
|
||||
{
|
||||
$resp = $this->callApiWithKey(self::METHOD_GET, '/visits/non-orphan');
|
||||
|
@ -11,7 +11,7 @@ use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
|
||||
class GlobalVisitsTest extends ApiTestCase
|
||||
{
|
||||
#[Test, DataProvider('provideApiKeys')]
|
||||
public function returnsExpectedVisitsStats(string $apiKey, int $expectedVisits): void
|
||||
public function returnsExpectedVisitsStats(string $apiKey, int $expectedVisits, int $expectedOrphanVisits): void
|
||||
{
|
||||
$resp = $this->callApiWithKey(self::METHOD_GET, '/visits', [], $apiKey);
|
||||
$payload = $this->getJsonResponsePayload($resp);
|
||||
@ -20,13 +20,14 @@ class GlobalVisitsTest extends ApiTestCase
|
||||
self::assertArrayHasKey('visitsCount', $payload['visits']);
|
||||
self::assertArrayHasKey('orphanVisitsCount', $payload['visits']);
|
||||
self::assertEquals($expectedVisits, $payload['visits']['visitsCount']);
|
||||
self::assertEquals(3, $payload['visits']['orphanVisitsCount']);
|
||||
self::assertEquals($expectedOrphanVisits, $payload['visits']['orphanVisitsCount']);
|
||||
}
|
||||
|
||||
public static function provideApiKeys(): iterable
|
||||
{
|
||||
yield 'admin API key' => ['valid_api_key', 7];
|
||||
yield 'domain API key' => ['domain_api_key', 0];
|
||||
yield 'author API key' => ['author_api_key', 5];
|
||||
yield 'admin API key' => ['valid_api_key', 7, 3];
|
||||
yield 'domain API key' => ['domain_api_key', 0, 3];
|
||||
yield 'author API key' => ['author_api_key', 5, 3];
|
||||
yield 'no orphans API key' => ['no_orphans_api_key', 7, 0];
|
||||
}
|
||||
}
|
||||
|
@ -69,4 +69,16 @@ class OrphanVisitsTest extends ApiTestCase
|
||||
[self::REGULAR_NOT_FOUND],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function noVisitsAreReturnedForRestrictedApiKey(): void
|
||||
{
|
||||
$resp = $this->callApiWithKey(self::METHOD_GET, '/visits/orphan', apiKey: 'no_orphans_api_key');
|
||||
$payload = $this->getJsonResponsePayload($resp);
|
||||
$visits = $payload['visits']['data'] ?? null;
|
||||
|
||||
self::assertIsArray($visits);
|
||||
self::assertEmpty($visits);
|
||||
self::assertEquals(0, $payload['visits']['pagination']['totalItems'] ?? Paginator::ALL_ITEMS);
|
||||
}
|
||||
}
|
||||
|
@ -23,21 +23,29 @@ class ApiKeyFixture extends AbstractFixture implements DependentFixtureInterface
|
||||
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$manager->persist($this->buildApiKey('valid_api_key', true));
|
||||
$manager->persist($this->buildApiKey('disabled_api_key', false));
|
||||
$manager->persist($this->buildApiKey('expired_api_key', true, Chronos::now()->subDay()->startOfDay()));
|
||||
$manager->persist($this->buildApiKey('valid_api_key', enabled: true));
|
||||
$manager->persist($this->buildApiKey('disabled_api_key', enabled: false));
|
||||
$manager->persist($this->buildApiKey(
|
||||
'expired_api_key',
|
||||
enabled: true,
|
||||
expiresAt: Chronos::now()->subDay()->startOfDay(),
|
||||
));
|
||||
|
||||
$authorApiKey = $this->buildApiKey('author_api_key', true);
|
||||
$authorApiKey = $this->buildApiKey('author_api_key', enabled: true);
|
||||
$authorApiKey->registerRole(RoleDefinition::forAuthoredShortUrls());
|
||||
$manager->persist($authorApiKey);
|
||||
$this->addReference('author_api_key', $authorApiKey);
|
||||
|
||||
/** @var Domain $exampleDomain */
|
||||
$exampleDomain = $this->getReference('example_domain');
|
||||
$domainApiKey = $this->buildApiKey('domain_api_key', true);
|
||||
$domainApiKey = $this->buildApiKey('domain_api_key', enabled: true);
|
||||
$domainApiKey->registerRole(RoleDefinition::forDomain($exampleDomain));
|
||||
$manager->persist($domainApiKey);
|
||||
|
||||
$authorApiKey = $this->buildApiKey('no_orphans_api_key', enabled: true);
|
||||
$authorApiKey->registerRole(RoleDefinition::forNoOrphanVisits());
|
||||
$manager->persist($authorApiKey);
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user