mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Restrict interaction with orphan visits when API key has that role
This commit is contained in:
@@ -15,18 +15,22 @@ use Shlinkio\Shlink\Core\Visit\Paginator\Adapter\OrphanVisitsPaginatorAdapter;
|
||||
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsCountFiltering;
|
||||
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsListFiltering;
|
||||
use Shlinkio\Shlink\Core\Visit\Repository\VisitRepositoryInterface;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class OrphanVisitsPaginatorAdapterTest extends TestCase
|
||||
{
|
||||
private OrphanVisitsPaginatorAdapter $adapter;
|
||||
private MockObject & VisitRepositoryInterface $repo;
|
||||
private VisitsParams $params;
|
||||
private ApiKey $apiKey;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->repo = $this->createMock(VisitRepositoryInterface::class);
|
||||
$this->params = VisitsParams::fromRawData([]);
|
||||
$this->adapter = new OrphanVisitsPaginatorAdapter($this->repo, $this->params);
|
||||
$this->apiKey = ApiKey::create();
|
||||
|
||||
$this->adapter = new OrphanVisitsPaginatorAdapter($this->repo, $this->params, $this->apiKey);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -34,7 +38,7 @@ class OrphanVisitsPaginatorAdapterTest extends TestCase
|
||||
{
|
||||
$expectedCount = 5;
|
||||
$this->repo->expects($this->once())->method('countOrphanVisits')->with(
|
||||
new VisitsCountFiltering($this->params->dateRange),
|
||||
new VisitsCountFiltering($this->params->dateRange, apiKey: $this->apiKey),
|
||||
)->willReturn($expectedCount);
|
||||
|
||||
$result = $this->adapter->getNbResults();
|
||||
@@ -51,9 +55,13 @@ class OrphanVisitsPaginatorAdapterTest extends TestCase
|
||||
{
|
||||
$visitor = Visitor::emptyInstance();
|
||||
$list = [Visit::forRegularNotFound($visitor), Visit::forInvalidShortUrl($visitor)];
|
||||
$this->repo->expects($this->once())->method('findOrphanVisits')->with(
|
||||
new VisitsListFiltering($this->params->dateRange, $this->params->excludeBots, null, $limit, $offset),
|
||||
)->willReturn($list);
|
||||
$this->repo->expects($this->once())->method('findOrphanVisits')->with(new VisitsListFiltering(
|
||||
$this->params->dateRange,
|
||||
$this->params->excludeBots,
|
||||
$this->apiKey,
|
||||
$limit,
|
||||
$offset,
|
||||
))->willReturn($list);
|
||||
|
||||
$result = $this->adapter->getSlice($offset, $limit);
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Core\Visit\Repository\VisitDeleterRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Visit\VisitsDeleter;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class VisitsDeleterTest extends TestCase
|
||||
{
|
||||
@@ -38,4 +41,16 @@ class VisitsDeleterTest extends TestCase
|
||||
yield '5000' => [5000];
|
||||
yield '0' => [0];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function returnsNoDeletedVisitsForApiKeyWithNoPermission(): void
|
||||
{
|
||||
$this->repo->expects($this->never())->method('deleteOrphanVisits');
|
||||
|
||||
$result = $this->visitsDeleter->deleteOrphanVisits(
|
||||
ApiKey::fromMeta(ApiKeyMeta::withRoles(RoleDefinition::forOrphanVisitsExcluded())),
|
||||
);
|
||||
|
||||
self::assertEquals(0, $result->affectedItems);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +50,14 @@ class VisitsStatsHelperTest extends TestCase
|
||||
}
|
||||
|
||||
#[Test, DataProvider('provideCounts')]
|
||||
public function returnsExpectedVisitsStats(int $expectedCount): void
|
||||
public function returnsExpectedVisitsStats(int $expectedCount, ?ApiKey $apiKey): void
|
||||
{
|
||||
$repo = $this->createMock(VisitRepository::class);
|
||||
$callCount = 0;
|
||||
$repo->expects($this->exactly(2))->method('countNonOrphanVisits')->willReturnCallback(
|
||||
function (VisitsCountFiltering $options) use ($expectedCount, &$callCount) {
|
||||
function (VisitsCountFiltering $options) use ($expectedCount, $apiKey, &$callCount) {
|
||||
Assert::assertEquals($callCount !== 0, $options->excludeBots);
|
||||
Assert::assertEquals($apiKey, $options->apiKey);
|
||||
$callCount++;
|
||||
|
||||
return $expectedCount * 3;
|
||||
@@ -67,14 +68,17 @@ class VisitsStatsHelperTest extends TestCase
|
||||
)->willReturn($expectedCount);
|
||||
$this->em->expects($this->once())->method('getRepository')->with(Visit::class)->willReturn($repo);
|
||||
|
||||
$stats = $this->helper->getVisitsStats();
|
||||
$stats = $this->helper->getVisitsStats($apiKey);
|
||||
|
||||
self::assertEquals(new VisitsStats($expectedCount * 3, $expectedCount), $stats);
|
||||
}
|
||||
|
||||
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, null]),
|
||||
...map(range(0, 18, 3), fn (int $value) => [$value, ApiKey::create()]),
|
||||
];
|
||||
}
|
||||
|
||||
#[Test, DataProvider('provideAdminApiKeys')]
|
||||
|
||||
Reference in New Issue
Block a user