Merge pull request #1193 from acelaya-forks/feature/api-key-visits

Added extra DB tests ensuring proper short URL visits are resolved fr…
This commit is contained in:
Alejandro Celaya 2021-10-01 19:59:30 +02:00 committed by GitHub
commit 60c8f23a63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 6 deletions

View file

@ -355,6 +355,8 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$this->getEntityManager()->persist($wrongDomainApiKey);
$rightDomainApiKey = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forDomain($rightDomain)));
$this->getEntityManager()->persist($rightDomainApiKey);
$adminApiKey = ApiKey::create();
$this->getEntityManager()->persist($adminApiKey);
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
'validSince' => $start,
@ -365,6 +367,12 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
]), $this->relationResolver);
$this->getEntityManager()->persist($shortUrl);
$nonDomainShortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
'apiKey' => $apiKey,
'longUrl' => 'non-domain',
]), $this->relationResolver);
$this->getEntityManager()->persist($nonDomainShortUrl);
$this->getEntityManager()->flush();
self::assertSame(
@ -379,6 +387,12 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
'longUrl' => 'foo',
'tags' => ['foo', 'bar'],
])));
self::assertSame($shortUrl, $this->repo->findOneMatching(ShortUrlMeta::fromRawData([
'validSince' => $start,
'apiKey' => $adminApiKey,
'longUrl' => 'foo',
'tags' => ['foo', 'bar'],
])));
self::assertNull($this->repo->findOneMatching(ShortUrlMeta::fromRawData([
'validSince' => $start,
'apiKey' => $otherApiKey,
@ -424,6 +438,27 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
'tags' => ['foo', 'bar'],
])),
);
self::assertSame(
$nonDomainShortUrl,
$this->repo->findOneMatching(ShortUrlMeta::fromRawData([
'apiKey' => $apiKey,
'longUrl' => 'non-domain',
])),
);
self::assertSame(
$nonDomainShortUrl,
$this->repo->findOneMatching(ShortUrlMeta::fromRawData([
'apiKey' => $adminApiKey,
'longUrl' => 'non-domain',
])),
);
self::assertNull(
$this->repo->findOneMatching(ShortUrlMeta::fromRawData([
'apiKey' => $otherApiKey,
'longUrl' => 'non-domain',
])),
);
}
/** @test */

View file

@ -16,6 +16,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\Repository\VisitRepository;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\PersistenceShortUrlRelationResolver;
use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter;
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsCountFiltering;
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsListFiltering;
use Shlinkio\Shlink\IpGeolocation\Model\Location;
@ -25,6 +26,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
use Shlinkio\Shlink\TestUtils\DbTest\DatabaseTestCase;
use function Functional\map;
use function is_string;
use function range;
use function sprintf;
@ -171,6 +173,38 @@ class VisitRepositoryTest extends DatabaseTestCase
));
}
/** @test */
public function findVisitsByShortCodeReturnsProperDataWhenUsingAPiKeys(): void
{
$adminApiKey = ApiKey::create();
$this->getEntityManager()->persist($adminApiKey);
$restrictedApiKey = ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forAuthoredShortUrls()));
$this->getEntityManager()->persist($restrictedApiKey);
$this->getEntityManager()->flush();
[$shortCode1] = $this->createShortUrlsAndVisits(true, [], $adminApiKey);
[$shortCode2] = $this->createShortUrlsAndVisits('bar.com', [], $restrictedApiKey);
self::assertNotEmpty($this->repo->findVisitsByShortCode(
ShortUrlIdentifier::fromShortCodeAndDomain($shortCode1),
new VisitsListFiltering(null, false, $adminApiKey->spec()),
));
self::assertNotEmpty($this->repo->findVisitsByShortCode(
ShortUrlIdentifier::fromShortCodeAndDomain($shortCode2),
new VisitsListFiltering(null, false, $adminApiKey->spec()),
));
self::assertEmpty($this->repo->findVisitsByShortCode(
ShortUrlIdentifier::fromShortCodeAndDomain($shortCode1),
new VisitsListFiltering(null, false, $restrictedApiKey->spec()),
));
self::assertNotEmpty($this->repo->findVisitsByShortCode(
ShortUrlIdentifier::fromShortCodeAndDomain($shortCode2),
new VisitsListFiltering(null, false, $restrictedApiKey->spec()),
));
}
/** @test */
public function findVisitsByTagReturnsProperData(): void
{
@ -354,19 +388,26 @@ class VisitRepositoryTest extends DatabaseTestCase
));
}
private function createShortUrlsAndVisits(bool $withDomain = true, array $tags = []): array
{
/**
* @return array{string, string, ShortUrl}
*/
private function createShortUrlsAndVisits(
bool|string $withDomain = true,
array $tags = [],
?ApiKey $apiKey = null,
): array {
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
'longUrl' => '',
'tags' => $tags,
ShortUrlInputFilter::LONG_URL => '',
ShortUrlInputFilter::TAGS => $tags,
ShortUrlInputFilter::API_KEY => $apiKey,
]), $this->relationResolver);
$domain = 'example.com';
$domain = is_string($withDomain) ? $withDomain : 'example.com';
$shortCode = $shortUrl->getShortCode();
$this->getEntityManager()->persist($shortUrl);
$this->createVisitsForShortUrl($shortUrl);
if ($withDomain) {
if ($withDomain !== false) {
$shortUrlWithDomain = ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
'customSlug' => $shortCode,
'domain' => $domain,