Added tests covering count non orphan visits with different combinations of filters

This commit is contained in:
Alejandro Celaya 2022-01-16 11:44:12 +01:00
parent 61618250ec
commit 4a3e04ced9
4 changed files with 51 additions and 30 deletions

View file

@ -14,8 +14,8 @@ use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsCountFiltering;
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsListFiltering;
use Shlinkio\Shlink\Core\Visit\Spec\CountOfNonOrphanVisits;
use Shlinkio\Shlink\Core\Visit\Spec\CountOfOrphanVisits;
use Shlinkio\Shlink\Core\Visit\Spec\CountOfShortUrlVisits;
use const PHP_INT_MAX;
@ -179,10 +179,9 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo
return $this->resolveVisitsWithNativeQuery($qb, $filtering->limit(), $filtering->offset());
}
// TODO This should support counting in a date range or excluding bots
public function countNonOrphanVisits(VisitsCountFiltering $filtering): int
{
return (int) $this->matchSingleScalarResult(new CountOfShortUrlVisits($filtering->apiKey()));
return (int) $this->matchSingleScalarResult(new CountOfNonOrphanVisits($filtering));
}
private function createAllVisitsQueryBuilder(VisitsListFiltering $filtering): QueryBuilder

View file

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Visit\Spec;
use Happyr\DoctrineSpecification\Spec;
use Happyr\DoctrineSpecification\Specification\BaseSpecification;
use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Core\Spec\InDateRange;
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsCountFiltering;
use Shlinkio\Shlink\Rest\ApiKey\Spec\WithApiKeySpecsEnsuringJoin;
class CountOfNonOrphanVisits extends BaseSpecification
{
public function __construct(private VisitsCountFiltering $filtering)
{
parent::__construct();
}
protected function getSpec(): Specification
{
$conditions = [
Spec::isNotNull('shortUrl'),
new InDateRange($this->filtering->dateRange()),
];
if ($this->filtering->excludeBots()) {
$conditions[] = Spec::eq('potentialBot', false);
}
$apiKey = $this->filtering->apiKey();
if ($apiKey !== null) {
$conditions[] = new WithApiKeySpecsEnsuringJoin($apiKey, 'shortUrl');
}
return Spec::countOf(Spec::andX(...$conditions));
}
}

View file

@ -1,27 +0,0 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Visit\Spec;
use Happyr\DoctrineSpecification\Spec;
use Happyr\DoctrineSpecification\Specification\BaseSpecification;
use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Rest\ApiKey\Spec\WithApiKeySpecsEnsuringJoin;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
class CountOfShortUrlVisits extends BaseSpecification
{
public function __construct(private ?ApiKey $apiKey)
{
parent::__construct();
}
protected function getSpec(): Specification
{
return Spec::countOf(Spec::andX(
Spec::isNotNull('shortUrl'),
new WithApiKeySpecsEnsuringJoin($this->apiKey, 'shortUrl'),
));
}
}

View file

@ -301,6 +301,16 @@ class VisitRepositoryTest extends DatabaseTestCase
self::assertEquals(4, $this->repo->countNonOrphanVisits(VisitsCountFiltering::withApiKey($apiKey1)));
self::assertEquals(5 + 7, $this->repo->countNonOrphanVisits(VisitsCountFiltering::withApiKey($apiKey2)));
self::assertEquals(4 + 7, $this->repo->countNonOrphanVisits(VisitsCountFiltering::withApiKey($domainApiKey)));
self::assertEquals(4, $this->repo->countNonOrphanVisits(new VisitsCountFiltering(DateRange::withStartDate(
Chronos::parse('2016-01-05')->startOfDay(),
))));
self::assertEquals(2, $this->repo->countNonOrphanVisits(new VisitsCountFiltering(DateRange::withStartDate(
Chronos::parse('2016-01-03')->startOfDay(),
), false, $apiKey1)));
self::assertEquals(1, $this->repo->countNonOrphanVisits(new VisitsCountFiltering(DateRange::withStartDate(
Chronos::parse('2016-01-07')->startOfDay(),
), false, $apiKey2)));
self::assertEquals(3 + 5, $this->repo->countNonOrphanVisits(new VisitsCountFiltering(null, true, $apiKey2)));
self::assertEquals(4, $this->repo->countOrphanVisits(new VisitsCountFiltering()));
self::assertEquals(3, $this->repo->countOrphanVisits(new VisitsCountFiltering(null, true)));
}