Refactored ShortUrlRepository to wrap args into DTOs

This commit is contained in:
Alejandro Celaya 2022-01-17 20:10:41 +01:00
parent 0727c7bdfb
commit 661b07e12f
9 changed files with 251 additions and 119 deletions

View file

@ -18,6 +18,11 @@ final class Ordering
return new self($field, $dir ?? self::DEFAULT_DIR); return new self($field, $dir ?? self::DEFAULT_DIR);
} }
public static function emptyInstance(): self
{
return self::fromTuple([null, null]);
}
public function orderField(): ?string public function orderField(): ?string
{ {
return $this->field; return $this->field;

View file

@ -11,12 +11,13 @@ use Doctrine\ORM\QueryBuilder;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
use Happyr\DoctrineSpecification\Specification\Specification; use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType; use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\Ordering; use Shlinkio\Shlink\Core\Model\Ordering;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl; use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
use function array_column; use function array_column;
@ -26,27 +27,18 @@ use function Functional\contains;
class ShortUrlRepository extends EntitySpecificationRepository implements ShortUrlRepositoryInterface class ShortUrlRepository extends EntitySpecificationRepository implements ShortUrlRepositoryInterface
{ {
/** /**
* @param string[] $tags
* @return ShortUrl[] * @return ShortUrl[]
*/ */
public function findList( public function findList(ShortUrlsListFiltering $filtering): array
?int $limit = null, {
?int $offset = null, $qb = $this->createListQueryBuilder($filtering);
?string $searchTerm = null,
array $tags = [],
?string $tagsMode = null,
?Ordering $orderBy = null,
?DateRange $dateRange = null,
?Specification $spec = null,
): array {
$qb = $this->createListQueryBuilder($searchTerm, $tags, $tagsMode, $dateRange, $spec);
$qb->select('DISTINCT s') $qb->select('DISTINCT s')
->setMaxResults($limit) ->setMaxResults($filtering->limit())
->setFirstResult($offset); ->setFirstResult($filtering->offset());
// In case the ordering has been specified, the query could be more complex. Process it // In case the ordering has been specified, the query could be more complex. Process it
if ($orderBy?->hasOrderField()) { if ($filtering->orderBy()->hasOrderField()) {
return $this->processOrderByForList($qb, $orderBy); return $this->processOrderByForList($qb, $filtering->orderBy());
} }
// With no explicit order by, fallback to dateCreated-DESC // With no explicit order by, fallback to dateCreated-DESC
@ -77,30 +69,21 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
public function countList( public function countList(ShortUrlsCountFiltering $filtering): int
?string $searchTerm = null, {
array $tags = [], $qb = $this->createListQueryBuilder($filtering);
?string $tagsMode = null,
?DateRange $dateRange = null,
?Specification $spec = null,
): int {
$qb = $this->createListQueryBuilder($searchTerm, $tags, $tagsMode, $dateRange, $spec);
$qb->select('COUNT(DISTINCT s)'); $qb->select('COUNT(DISTINCT s)');
return (int) $qb->getQuery()->getSingleScalarResult(); return (int) $qb->getQuery()->getSingleScalarResult();
} }
private function createListQueryBuilder( private function createListQueryBuilder(ShortUrlsCountFiltering $filtering): QueryBuilder
?string $searchTerm, {
array $tags,
?string $tagsMode,
?DateRange $dateRange,
?Specification $spec,
): QueryBuilder {
$qb = $this->getEntityManager()->createQueryBuilder(); $qb = $this->getEntityManager()->createQueryBuilder();
$qb->from(ShortUrl::class, 's') $qb->from(ShortUrl::class, 's')
->where('1=1'); ->where('1=1');
$dateRange = $filtering->dateRange();
if ($dateRange?->startDate() !== null) { if ($dateRange?->startDate() !== null) {
$qb->andWhere($qb->expr()->gte('s.dateCreated', ':startDate')); $qb->andWhere($qb->expr()->gte('s.dateCreated', ':startDate'));
$qb->setParameter('startDate', $dateRange->startDate(), ChronosDateTimeType::CHRONOS_DATETIME); $qb->setParameter('startDate', $dateRange->startDate(), ChronosDateTimeType::CHRONOS_DATETIME);
@ -110,6 +93,8 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
$qb->setParameter('endDate', $dateRange->endDate(), ChronosDateTimeType::CHRONOS_DATETIME); $qb->setParameter('endDate', $dateRange->endDate(), ChronosDateTimeType::CHRONOS_DATETIME);
} }
$searchTerm = $filtering->searchTerm();
$tags = $filtering->tags();
// Apply search term to every searchable field if not empty // Apply search term to every searchable field if not empty
if (! empty($searchTerm)) { if (! empty($searchTerm)) {
// Left join with tags only if no tags were provided. In case of tags, an inner join will be done later // Left join with tags only if no tags were provided. In case of tags, an inner join will be done later
@ -131,13 +116,13 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
// Filter by tags if provided // Filter by tags if provided
if (! empty($tags)) { if (! empty($tags)) {
$tagsMode = $tagsMode ?? ShortUrlsParams::TAGS_MODE_ANY; $tagsMode = $filtering->tagsMode() ?? ShortUrlsParams::TAGS_MODE_ANY;
$tagsMode === ShortUrlsParams::TAGS_MODE_ANY $tagsMode === ShortUrlsParams::TAGS_MODE_ANY
? $qb->join('s.tags', 't')->andWhere($qb->expr()->in('t.name', $tags)) ? $qb->join('s.tags', 't')->andWhere($qb->expr()->in('t.name', $tags))
: $this->joinAllTags($qb, $tags); : $this->joinAllTags($qb, $tags);
} }
$this->applySpecification($qb, $spec, 's'); $this->applySpecification($qb, $filtering->apiKey()?->spec(), 's');
return $qb; return $qb;
} }

View file

@ -7,34 +7,20 @@ namespace Shlinkio\Shlink\Core\Repository;
use Doctrine\Persistence\ObjectRepository; use Doctrine\Persistence\ObjectRepository;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface;
use Happyr\DoctrineSpecification\Specification\Specification; use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\Ordering;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl; use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface
{ {
public function findList( public function findList(ShortUrlsListFiltering $filtering): array;
?int $limit = null,
?int $offset = null,
?string $searchTerm = null,
array $tags = [],
?string $tagsMode = null,
?Ordering $orderBy = null,
?DateRange $dateRange = null,
?Specification $spec = null,
): array;
public function countList( public function countList(ShortUrlsCountFiltering $filtering): int;
?string $searchTerm = null,
array $tags = [],
?string $tagsMode = null,
?DateRange $dateRange = null,
?Specification $spec = null,
): int;
// TODO Use ShortUrlIdentifier here
public function findOneWithDomainFallback(string $shortCode, ?string $domain = null): ?ShortUrl; public function findOneWithDomainFallback(string $shortCode, ?string $domain = null): ?ShortUrl;
public function findOne(ShortUrlIdentifier $identifier, ?Specification $spec = null): ?ShortUrl; public function findOne(ShortUrlIdentifier $identifier, ?Specification $spec = null): ?ShortUrl;

View file

@ -12,10 +12,10 @@ use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlEdit; use Shlinkio\Shlink\Core\Model\ShortUrlEdit;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Paginator\Adapter\ShortUrlRepositoryAdapter;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository; use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlTitleResolutionHelperInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlTitleResolutionHelperInterface;
use Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter\ShortUrlRepositoryAdapter;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;

View file

@ -2,11 +2,13 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Paginator\Adapter; namespace Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter;
use Pagerfanta\Adapter\AdapterInterface; use Pagerfanta\Adapter\AdapterInterface;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface; use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
class ShortUrlRepositoryAdapter implements AdapterInterface class ShortUrlRepositoryAdapter implements AdapterInterface
@ -21,25 +23,12 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
public function getSlice(int $offset, int $length): iterable public function getSlice(int $offset, int $length): iterable
{ {
return $this->repository->findList( return $this->repository->findList(
$length, ShortUrlsListFiltering::fromLimitsAndParams($length, $offset, $this->params, $this->apiKey),
$offset,
$this->params->searchTerm(),
$this->params->tags(),
$this->params->tagsMode(),
$this->params->orderBy(),
$this->params->dateRange(),
$this->apiKey?->spec(),
); );
} }
public function getNbResults(): int public function getNbResults(): int
{ {
return $this->repository->countList( return $this->repository->countList(ShortUrlsCountFiltering::fromParams($this->params, $this->apiKey));
$this->params->searchTerm(),
$this->params->tags(),
$this->params->tagsMode(),
$this->params->dateRange(),
$this->apiKey?->spec(),
);
} }
} }

View file

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Persistence;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
class ShortUrlsCountFiltering
{
public function __construct(
private ?string $searchTerm = null,
private array $tags = [],
private ?string $tagsMode = null,
private ?DateRange $dateRange = null,
private ?ApiKey $apiKey = null,
) {
}
public static function fromParams(ShortUrlsParams $params, ?ApiKey $apiKey): self
{
return new self($params->searchTerm(), $params->tags(), $params->tagsMode(), $params->dateRange(), $apiKey);
}
public function searchTerm(): ?string
{
return $this->searchTerm;
}
public function tags(): array
{
return $this->tags;
}
public function tagsMode(): ?string
{
return $this->tagsMode;
}
public function dateRange(): ?DateRange
{
return $this->dateRange;
}
public function apiKey(): ?ApiKey
{
return $this->apiKey;
}
}

View file

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Persistence;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Model\Ordering;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
class ShortUrlsListFiltering extends ShortUrlsCountFiltering
{
public function __construct(
private ?int $limit,
private ?int $offset,
private Ordering $orderBy,
?string $searchTerm = null,
array $tags = [],
?string $tagsMode = null,
?DateRange $dateRange = null,
?ApiKey $apiKey = null,
) {
parent::__construct($searchTerm, $tags, $tagsMode, $dateRange, $apiKey);
}
public static function fromLimitsAndParams(int $limit, int $offset, ShortUrlsParams $params, ?ApiKey $apiKey): self
{
return new self(
$limit,
$offset,
$params->orderBy(),
$params->searchTerm(),
$params->tags(),
$params->tagsMode(),
$params->dateRange(),
$apiKey,
);
}
public function offset(): ?int
{
return $this->offset;
}
public function limit(): ?int
{
return $this->limit;
}
public function orderBy(): Ordering
{
return $this->orderBy;
}
}

View file

@ -17,6 +17,8 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository; use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\PersistenceShortUrlRelationResolver; use Shlinkio\Shlink\Core\ShortUrl\Resolver\PersistenceShortUrlRelationResolver;
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl; use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta; use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
@ -85,7 +87,7 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
} }
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
self::assertEquals($count, $this->repo->countList()); self::assertEquals($count, $this->repo->countList(new ShortUrlsCountFiltering()));
} }
/** @test */ /** @test */
@ -112,44 +114,49 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
$result = $this->repo->findList(null, null, 'foo', ['bar']); $result = $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), 'foo', ['bar']),
);
self::assertCount(1, $result); self::assertCount(1, $result);
self::assertEquals(1, $this->repo->countList('foo', ['bar'])); self::assertEquals(1, $this->repo->countList(new ShortUrlsCountFiltering('foo', ['bar'])));
self::assertSame($foo, $result[0]); self::assertSame($foo, $result[0]);
$result = $this->repo->findList(); $result = $this->repo->findList(new ShortUrlsListFiltering(null, null, Ordering::emptyInstance()));
self::assertCount(3, $result); self::assertCount(3, $result);
$result = $this->repo->findList(2); $result = $this->repo->findList(new ShortUrlsListFiltering(2, null, Ordering::emptyInstance()));
self::assertCount(2, $result); self::assertCount(2, $result);
$result = $this->repo->findList(2, 1); $result = $this->repo->findList(new ShortUrlsListFiltering(2, 1, Ordering::emptyInstance()));
self::assertCount(2, $result); self::assertCount(2, $result);
self::assertCount(1, $this->repo->findList(2, 2)); self::assertCount(1, $this->repo->findList(new ShortUrlsListFiltering(2, 2, Ordering::emptyInstance())));
$result = $this->repo->findList(null, null, null, [], null, Ordering::fromTuple(['visits', 'DESC'])); $result = $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::fromTuple(['visits', 'DESC'])),
);
self::assertCount(3, $result); self::assertCount(3, $result);
self::assertSame($bar, $result[0]); self::assertSame($bar, $result[0]);
$result = $this->repo->findList(null, null, null, [], null, null, DateRange::withEndDate( $result = $this->repo->findList(
Chronos::now()->subDays(2), new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, [], null, DateRange::withEndDate(
));
self::assertCount(1, $result);
self::assertEquals(1, $this->repo->countList(null, [], null, DateRange::withEndDate(
Chronos::now()->subDays(2),
)));
self::assertSame($foo2, $result[0]);
self::assertCount(
2,
$this->repo->findList(null, null, null, [], null, null, DateRange::withStartDate(
Chronos::now()->subDays(2), Chronos::now()->subDays(2),
)), )),
); );
self::assertEquals(2, $this->repo->countList(null, [], null, DateRange::withStartDate( self::assertCount(1, $result);
self::assertEquals(1, $this->repo->countList(new ShortUrlsCountFiltering(null, [], null, DateRange::withEndDate(
Chronos::now()->subDays(2), Chronos::now()->subDays(2),
))); ))));
self::assertSame($foo2, $result[0]);
self::assertCount(2, $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, [], null, DateRange::withStartDate(
Chronos::now()->subDays(2),
)),
));
self::assertEquals(2, $this->repo->countList(
new ShortUrlsCountFiltering(null, [], null, DateRange::withStartDate(Chronos::now()->subDays(2))),
));
} }
/** @test */ /** @test */
@ -162,7 +169,9 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
$result = $this->repo->findList(null, null, null, [], null, Ordering::fromTuple(['longUrl', 'ASC'])); $result = $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::fromTuple(['longUrl', 'ASC'])),
);
self::assertCount(count($urls), $result); self::assertCount(count($urls), $result);
self::assertEquals('a', $result[0]->getLongUrl()); self::assertEquals('a', $result[0]->getLongUrl());
@ -202,38 +211,86 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
$this->getEntityManager()->flush(); $this->getEntityManager()->flush();
self::assertCount(5, $this->repo->findList(null, null, null, ['foo', 'bar']));
self::assertCount(5, $this->repo->findList(null, null, null, ['foo', 'bar'], ShortUrlsParams::TAGS_MODE_ANY));
self::assertCount(1, $this->repo->findList(null, null, null, ['foo', 'bar'], ShortUrlsParams::TAGS_MODE_ALL));
self::assertEquals(5, $this->repo->countList(null, ['foo', 'bar']));
self::assertEquals(5, $this->repo->countList(null, ['foo', 'bar'], ShortUrlsParams::TAGS_MODE_ANY));
self::assertEquals(1, $this->repo->countList(null, ['foo', 'bar'], ShortUrlsParams::TAGS_MODE_ALL));
self::assertCount(4, $this->repo->findList(null, null, null, ['bar', 'baz']));
self::assertCount(4, $this->repo->findList(null, null, null, ['bar', 'baz'], ShortUrlsParams::TAGS_MODE_ANY));
self::assertCount(2, $this->repo->findList(null, null, null, ['bar', 'baz'], ShortUrlsParams::TAGS_MODE_ALL));
self::assertEquals(4, $this->repo->countList(null, ['bar', 'baz']));
self::assertEquals(4, $this->repo->countList(null, ['bar', 'baz'], ShortUrlsParams::TAGS_MODE_ANY));
self::assertEquals(2, $this->repo->countList(null, ['bar', 'baz'], ShortUrlsParams::TAGS_MODE_ALL));
self::assertCount(5, $this->repo->findList(null, null, null, ['foo', 'bar', 'baz']));
self::assertCount(5, $this->repo->findList( self::assertCount(5, $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, ['foo', 'bar']),
));
self::assertCount(5, $this->repo->findList(new ShortUrlsListFiltering(
null, null,
null, null,
Ordering::emptyInstance(),
null,
['foo', 'bar'],
ShortUrlsParams::TAGS_MODE_ANY,
)));
self::assertCount(1, $this->repo->findList(new ShortUrlsListFiltering(
null,
null,
Ordering::emptyInstance(),
null,
['foo', 'bar'],
ShortUrlsParams::TAGS_MODE_ALL,
)));
self::assertEquals(5, $this->repo->countList(new ShortUrlsCountFiltering(null, ['foo', 'bar'])));
self::assertEquals(5, $this->repo->countList(
new ShortUrlsCountFiltering(null, ['foo', 'bar'], ShortUrlsParams::TAGS_MODE_ANY),
));
self::assertEquals(1, $this->repo->countList(
new ShortUrlsCountFiltering(null, ['foo', 'bar'], ShortUrlsParams::TAGS_MODE_ALL),
));
self::assertCount(4, $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, ['bar', 'baz']),
));
self::assertCount(4, $this->repo->findList(new ShortUrlsListFiltering(
null,
null,
Ordering::emptyInstance(),
null,
['bar', 'baz'],
ShortUrlsParams::TAGS_MODE_ANY,
)));
self::assertCount(2, $this->repo->findList(new ShortUrlsListFiltering(
null,
null,
Ordering::emptyInstance(),
null,
['bar', 'baz'],
ShortUrlsParams::TAGS_MODE_ALL,
)));
self::assertEquals(4, $this->repo->countList(new ShortUrlsCountFiltering(null, ['bar', 'baz'])));
self::assertEquals(4, $this->repo->countList(
new ShortUrlsCountFiltering(null, ['bar', 'baz'], ShortUrlsParams::TAGS_MODE_ANY),
));
self::assertEquals(2, $this->repo->countList(
new ShortUrlsCountFiltering(null, ['bar', 'baz'], ShortUrlsParams::TAGS_MODE_ALL),
));
self::assertCount(5, $this->repo->findList(
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, ['foo', 'bar', 'baz']),
));
self::assertCount(5, $this->repo->findList(new ShortUrlsListFiltering(
null,
null,
Ordering::emptyInstance(),
null, null,
['foo', 'bar', 'baz'], ['foo', 'bar', 'baz'],
ShortUrlsParams::TAGS_MODE_ANY, ShortUrlsParams::TAGS_MODE_ANY,
)); )));
self::assertCount(0, $this->repo->findList( self::assertCount(0, $this->repo->findList(new ShortUrlsListFiltering(
null, null,
null, null,
Ordering::emptyInstance(),
null, null,
['foo', 'bar', 'baz'], ['foo', 'bar', 'baz'],
ShortUrlsParams::TAGS_MODE_ALL, ShortUrlsParams::TAGS_MODE_ALL,
)));
self::assertEquals(5, $this->repo->countList(new ShortUrlsCountFiltering(null, ['foo', 'bar', 'baz'])));
self::assertEquals(5, $this->repo->countList(
new ShortUrlsCountFiltering(null, ['foo', 'bar', 'baz'], ShortUrlsParams::TAGS_MODE_ANY),
));
self::assertEquals(0, $this->repo->countList(
new ShortUrlsCountFiltering(null, ['foo', 'bar', 'baz'], ShortUrlsParams::TAGS_MODE_ALL),
)); ));
self::assertEquals(5, $this->repo->countList(null, ['foo', 'bar', 'baz']));
self::assertEquals(5, $this->repo->countList(null, ['foo', 'bar', 'baz'], ShortUrlsParams::TAGS_MODE_ANY));
self::assertEquals(0, $this->repo->countList(null, ['foo', 'bar', 'baz'], ShortUrlsParams::TAGS_MODE_ALL));
} }
/** @test */ /** @test */

View file

@ -2,15 +2,17 @@
declare(strict_types=1); declare(strict_types=1);
namespace ShlinkioTest\Shlink\Core\Paginator\Adapter; namespace ShlinkioTest\Shlink\Core\ShortUrl\Paginator\Adapter;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Paginator\Adapter\ShortUrlRepositoryAdapter;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface; use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
use Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter\ShortUrlRepositoryAdapter;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
class ShortUrlRepositoryAdapterTest extends TestCase class ShortUrlRepositoryAdapterTest extends TestCase
@ -46,8 +48,9 @@ class ShortUrlRepositoryAdapterTest extends TestCase
$orderBy = $params->orderBy(); $orderBy = $params->orderBy();
$dateRange = $params->dateRange(); $dateRange = $params->dateRange();
$this->repo->findList(10, 5, $searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $orderBy, $dateRange, null) $this->repo->findList(
->shouldBeCalledOnce(); new ShortUrlsListFiltering(10, 5, $orderBy, $searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $dateRange),
)->shouldBeCalledOnce();
$adapter->getSlice(5, 10); $adapter->getSlice(5, 10);
} }
@ -71,8 +74,9 @@ class ShortUrlRepositoryAdapterTest extends TestCase
$adapter = new ShortUrlRepositoryAdapter($this->repo->reveal(), $params, $apiKey); $adapter = new ShortUrlRepositoryAdapter($this->repo->reveal(), $params, $apiKey);
$dateRange = $params->dateRange(); $dateRange = $params->dateRange();
$this->repo->countList($searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $dateRange, $apiKey->spec()) $this->repo->countList(
->shouldBeCalledOnce(); new ShortUrlsCountFiltering($searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $dateRange, $apiKey),
)->shouldBeCalledOnce();
$adapter->getNbResults(); $adapter->getNbResults();
} }