mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-18 21:23:37 -06:00
Merge pull request #1337 from acelaya-forks/feature/short-urls-filtering
Feature/short urls filtering
This commit is contained in:
commit
223339cd61
@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
|
||||
* [#1300](https://github.com/shlinkio/shlink/issues/1300) Changed default ordering for short URLs list, returning always from newest to oldest.
|
||||
* [#1299](https://github.com/shlinkio/shlink/issues/1299) Updated to the latest base docker images, based in PHP 8.1.1, and bumped openswoole to v4.9.1.
|
||||
* [#1282](https://github.com/shlinkio/shlink/issues/1282) Env vars now have precedence over installer options.
|
||||
* [#1328](https://github.com/shlinkio/shlink/issues/1328) Refactored ShortUrlsRepository to use DTOs in methods with too many arguments.
|
||||
|
||||
### Deprecated
|
||||
* [#1315](https://github.com/shlinkio/shlink/issues/1315) Deprecated `GET /tags?withStats=true` endpoint. Use `GET /tags/stats` instead.
|
||||
|
@ -18,6 +18,11 @@ final class Ordering
|
||||
return new self($field, $dir ?? self::DEFAULT_DIR);
|
||||
}
|
||||
|
||||
public static function emptyInstance(): self
|
||||
{
|
||||
return self::fromTuple([null, null]);
|
||||
}
|
||||
|
||||
public function orderField(): ?string
|
||||
{
|
||||
return $this->field;
|
||||
|
@ -11,12 +11,13 @@ use Doctrine\ORM\QueryBuilder;
|
||||
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
|
||||
use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Model\Ordering;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
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 function array_column;
|
||||
@ -26,27 +27,18 @@ use function Functional\contains;
|
||||
class ShortUrlRepository extends EntitySpecificationRepository implements ShortUrlRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string[] $tags
|
||||
* @return ShortUrl[]
|
||||
*/
|
||||
public function findList(
|
||||
?int $limit = null,
|
||||
?int $offset = null,
|
||||
?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);
|
||||
public function findList(ShortUrlsListFiltering $filtering): array
|
||||
{
|
||||
$qb = $this->createListQueryBuilder($filtering);
|
||||
$qb->select('DISTINCT s')
|
||||
->setMaxResults($limit)
|
||||
->setFirstResult($offset);
|
||||
->setMaxResults($filtering->limit())
|
||||
->setFirstResult($filtering->offset());
|
||||
|
||||
// In case the ordering has been specified, the query could be more complex. Process it
|
||||
if ($orderBy?->hasOrderField()) {
|
||||
return $this->processOrderByForList($qb, $orderBy);
|
||||
if ($filtering->orderBy()->hasOrderField()) {
|
||||
return $this->processOrderByForList($qb, $filtering->orderBy());
|
||||
}
|
||||
|
||||
// With no explicit order by, fallback to dateCreated-DESC
|
||||
@ -77,30 +69,21 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function countList(
|
||||
?string $searchTerm = null,
|
||||
array $tags = [],
|
||||
?string $tagsMode = null,
|
||||
?DateRange $dateRange = null,
|
||||
?Specification $spec = null,
|
||||
): int {
|
||||
$qb = $this->createListQueryBuilder($searchTerm, $tags, $tagsMode, $dateRange, $spec);
|
||||
public function countList(ShortUrlsCountFiltering $filtering): int
|
||||
{
|
||||
$qb = $this->createListQueryBuilder($filtering);
|
||||
$qb->select('COUNT(DISTINCT s)');
|
||||
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
private function createListQueryBuilder(
|
||||
?string $searchTerm,
|
||||
array $tags,
|
||||
?string $tagsMode,
|
||||
?DateRange $dateRange,
|
||||
?Specification $spec,
|
||||
): QueryBuilder {
|
||||
private function createListQueryBuilder(ShortUrlsCountFiltering $filtering): QueryBuilder
|
||||
{
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(ShortUrl::class, 's')
|
||||
->where('1=1');
|
||||
|
||||
$dateRange = $filtering->dateRange();
|
||||
if ($dateRange?->startDate() !== null) {
|
||||
$qb->andWhere($qb->expr()->gte('s.dateCreated', ':startDate'));
|
||||
$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);
|
||||
}
|
||||
|
||||
$searchTerm = $filtering->searchTerm();
|
||||
$tags = $filtering->tags();
|
||||
// Apply search term to every searchable field if not empty
|
||||
if (! empty($searchTerm)) {
|
||||
// Left join with tags only if no tags were provided. In case of tags, an inner join will be done later
|
||||
@ -131,18 +116,18 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
|
||||
// Filter by tags if provided
|
||||
if (! empty($tags)) {
|
||||
$tagsMode = $tagsMode ?? ShortUrlsParams::TAGS_MODE_ANY;
|
||||
$tagsMode = $filtering->tagsMode() ?? ShortUrlsParams::TAGS_MODE_ANY;
|
||||
$tagsMode === ShortUrlsParams::TAGS_MODE_ANY
|
||||
? $qb->join('s.tags', 't')->andWhere($qb->expr()->in('t.name', $tags))
|
||||
: $this->joinAllTags($qb, $tags);
|
||||
}
|
||||
|
||||
$this->applySpecification($qb, $spec, 's');
|
||||
$this->applySpecification($qb, $filtering->apiKey()?->spec(), 's');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function findOneWithDomainFallback(string $shortCode, ?string $domain = null): ?ShortUrl
|
||||
public function findOneWithDomainFallback(ShortUrlIdentifier $identifier): ?ShortUrl
|
||||
{
|
||||
// When ordering DESC, Postgres puts nulls at the beginning while the rest of supported DB engines put them at
|
||||
// the bottom
|
||||
@ -161,8 +146,8 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
$query = $this->getEntityManager()->createQuery($dql);
|
||||
$query->setMaxResults(1)
|
||||
->setParameters([
|
||||
'shortCode' => $shortCode,
|
||||
'domain' => $domain,
|
||||
'shortCode' => $identifier->shortCode(),
|
||||
'domain' => $identifier->domain(),
|
||||
]);
|
||||
|
||||
// Since we ordered by domain, we will have first the URL matching provided domain, followed by the one
|
||||
|
@ -7,35 +7,20 @@ namespace Shlinkio\Shlink\Core\Repository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface;
|
||||
use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Model\Ordering;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
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;
|
||||
|
||||
interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface
|
||||
{
|
||||
public function findList(
|
||||
?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 findList(ShortUrlsListFiltering $filtering): array;
|
||||
|
||||
public function countList(
|
||||
?string $searchTerm = null,
|
||||
array $tags = [],
|
||||
?string $tagsMode = null,
|
||||
?DateRange $dateRange = null,
|
||||
?Specification $spec = null,
|
||||
): int;
|
||||
public function countList(ShortUrlsCountFiltering $filtering): int;
|
||||
|
||||
public function findOneWithDomainFallback(string $shortCode, ?string $domain = null): ?ShortUrl;
|
||||
public function findOneWithDomainFallback(ShortUrlIdentifier $identifier): ?ShortUrl;
|
||||
|
||||
public function findOne(ShortUrlIdentifier $identifier, ?Specification $spec = null): ?ShortUrl;
|
||||
|
||||
|
@ -39,7 +39,7 @@ class ShortUrlResolver implements ShortUrlResolverInterface
|
||||
{
|
||||
/** @var ShortUrlRepository $shortUrlRepo */
|
||||
$shortUrlRepo = $this->em->getRepository(ShortUrl::class);
|
||||
$shortUrl = $shortUrlRepo->findOneWithDomainFallback($identifier->shortCode(), $identifier->domain());
|
||||
$shortUrl = $shortUrlRepo->findOneWithDomainFallback($identifier);
|
||||
if (! $shortUrl?->isEnabled()) {
|
||||
throw ShortUrlNotFoundException::fromNotFound($identifier);
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlEdit;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
||||
use Shlinkio\Shlink\Core\Paginator\Adapter\ShortUrlRepositoryAdapter;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
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\Rest\Entity\ApiKey;
|
||||
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Paginator\Adapter;
|
||||
namespace Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter;
|
||||
|
||||
use Pagerfanta\Adapter\AdapterInterface;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
||||
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;
|
||||
|
||||
class ShortUrlRepositoryAdapter implements AdapterInterface
|
||||
@ -21,25 +23,12 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
|
||||
public function getSlice(int $offset, int $length): iterable
|
||||
{
|
||||
return $this->repository->findList(
|
||||
$length,
|
||||
$offset,
|
||||
$this->params->searchTerm(),
|
||||
$this->params->tags(),
|
||||
$this->params->tagsMode(),
|
||||
$this->params->orderBy(),
|
||||
$this->params->dateRange(),
|
||||
$this->apiKey?->spec(),
|
||||
ShortUrlsListFiltering::fromLimitsAndParams($length, $offset, $this->params, $this->apiKey),
|
||||
);
|
||||
}
|
||||
|
||||
public function getNbResults(): int
|
||||
{
|
||||
return $this->repository->countList(
|
||||
$this->params->searchTerm(),
|
||||
$this->params->tags(),
|
||||
$this->params->tagsMode(),
|
||||
$this->params->dateRange(),
|
||||
$this->apiKey?->spec(),
|
||||
);
|
||||
return $this->repository->countList(ShortUrlsCountFiltering::fromParams($this->params, $this->apiKey));
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -17,6 +17,8 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
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\Importer\Model\ImportedShlinkUrl;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
|
||||
@ -55,25 +57,32 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
self::assertSame($regularOne, $this->repo->findOneWithDomainFallback($regularOne->getShortCode()));
|
||||
self::assertSame($regularOne, $this->repo->findOneWithDomainFallback(
|
||||
$withDomainDuplicatingRegular->getShortCode(),
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($regularOne->getShortCode()),
|
||||
));
|
||||
self::assertSame($regularOne, $this->repo->findOneWithDomainFallback(
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($withDomainDuplicatingRegular->getShortCode()),
|
||||
));
|
||||
self::assertSame($withDomain, $this->repo->findOneWithDomainFallback(
|
||||
$withDomain->getShortCode(),
|
||||
'example.com',
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($withDomain->getShortCode(), 'example.com'),
|
||||
));
|
||||
self::assertSame(
|
||||
$withDomainDuplicatingRegular,
|
||||
$this->repo->findOneWithDomainFallback($withDomainDuplicatingRegular->getShortCode(), 'doma.in'),
|
||||
$this->repo->findOneWithDomainFallback(
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($withDomainDuplicatingRegular->getShortCode(), 'doma.in'),
|
||||
),
|
||||
);
|
||||
self::assertSame(
|
||||
$regularOne,
|
||||
$this->repo->findOneWithDomainFallback($withDomainDuplicatingRegular->getShortCode(), 'other-domain.com'),
|
||||
);
|
||||
self::assertNull($this->repo->findOneWithDomainFallback('invalid'));
|
||||
self::assertNull($this->repo->findOneWithDomainFallback($withDomain->getShortCode()));
|
||||
self::assertNull($this->repo->findOneWithDomainFallback($withDomain->getShortCode(), 'other-domain.com'));
|
||||
self::assertSame($regularOne, $this->repo->findOneWithDomainFallback(ShortUrlIdentifier::fromShortCodeAndDomain(
|
||||
$withDomainDuplicatingRegular->getShortCode(),
|
||||
'other-domain.com',
|
||||
)));
|
||||
self::assertNull($this->repo->findOneWithDomainFallback(ShortUrlIdentifier::fromShortCodeAndDomain('invalid')));
|
||||
self::assertNull($this->repo->findOneWithDomainFallback(
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($withDomain->getShortCode()),
|
||||
));
|
||||
self::assertNull($this->repo->findOneWithDomainFallback(
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($withDomain->getShortCode(), 'other-domain.com'),
|
||||
));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -85,7 +94,7 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
}
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
self::assertEquals($count, $this->repo->countList());
|
||||
self::assertEquals($count, $this->repo->countList(new ShortUrlsCountFiltering()));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -112,44 +121,49 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
|
||||
$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::assertEquals(1, $this->repo->countList('foo', ['bar']));
|
||||
self::assertEquals(1, $this->repo->countList(new ShortUrlsCountFiltering('foo', ['bar'])));
|
||||
self::assertSame($foo, $result[0]);
|
||||
|
||||
$result = $this->repo->findList();
|
||||
$result = $this->repo->findList(new ShortUrlsListFiltering(null, null, Ordering::emptyInstance()));
|
||||
self::assertCount(3, $result);
|
||||
|
||||
$result = $this->repo->findList(2);
|
||||
$result = $this->repo->findList(new ShortUrlsListFiltering(2, null, Ordering::emptyInstance()));
|
||||
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(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::assertSame($bar, $result[0]);
|
||||
|
||||
$result = $this->repo->findList(null, null, null, [], null, null, DateRange::withEndDate(
|
||||
Chronos::now()->subDays(2),
|
||||
));
|
||||
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(
|
||||
$result = $this->repo->findList(
|
||||
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, [], null, DateRange::withEndDate(
|
||||
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),
|
||||
)));
|
||||
))));
|
||||
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 */
|
||||
@ -162,7 +176,9 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
|
||||
$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::assertEquals('a', $result[0]->getLongUrl());
|
||||
@ -202,38 +218,86 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
|
||||
$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(
|
||||
new ShortUrlsListFiltering(null, null, Ordering::emptyInstance(), null, ['foo', 'bar']),
|
||||
));
|
||||
self::assertCount(5, $this->repo->findList(new ShortUrlsListFiltering(
|
||||
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,
|
||||
['foo', 'bar', 'baz'],
|
||||
ShortUrlsParams::TAGS_MODE_ANY,
|
||||
));
|
||||
self::assertCount(0, $this->repo->findList(
|
||||
)));
|
||||
self::assertCount(0, $this->repo->findList(new ShortUrlsListFiltering(
|
||||
null,
|
||||
null,
|
||||
Ordering::emptyInstance(),
|
||||
null,
|
||||
['foo', 'bar', 'baz'],
|
||||
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 */
|
||||
|
@ -86,7 +86,9 @@ class ShortUrlResolverTest extends TestCase
|
||||
$shortCode = $shortUrl->getShortCode();
|
||||
|
||||
$repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
$findOneByShortCode = $repo->findOneWithDomainFallback($shortCode, null)->willReturn($shortUrl);
|
||||
$findOneByShortCode = $repo->findOneWithDomainFallback(
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($shortCode),
|
||||
)->willReturn($shortUrl);
|
||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$result = $this->urlResolver->resolveEnabledShortUrl(new ShortUrlIdentifier($shortCode));
|
||||
@ -105,7 +107,9 @@ class ShortUrlResolverTest extends TestCase
|
||||
$shortCode = $shortUrl->getShortCode();
|
||||
|
||||
$repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
$findOneByShortCode = $repo->findOneWithDomainFallback($shortCode, null)->willReturn($shortUrl);
|
||||
$findOneByShortCode = $repo->findOneWithDomainFallback(
|
||||
ShortUrlIdentifier::fromShortCodeAndDomain($shortCode),
|
||||
)->willReturn($shortUrl);
|
||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$this->expectException(ShortUrlNotFoundException::class);
|
||||
|
@ -2,15 +2,17 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Core\Paginator\Adapter;
|
||||
namespace ShlinkioTest\Shlink\Core\ShortUrl\Paginator\Adapter;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
||||
use Shlinkio\Shlink\Core\Paginator\Adapter\ShortUrlRepositoryAdapter;
|
||||
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;
|
||||
|
||||
class ShortUrlRepositoryAdapterTest extends TestCase
|
||||
@ -46,8 +48,9 @@ class ShortUrlRepositoryAdapterTest extends TestCase
|
||||
$orderBy = $params->orderBy();
|
||||
$dateRange = $params->dateRange();
|
||||
|
||||
$this->repo->findList(10, 5, $searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $orderBy, $dateRange, null)
|
||||
->shouldBeCalledOnce();
|
||||
$this->repo->findList(
|
||||
new ShortUrlsListFiltering(10, 5, $orderBy, $searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $dateRange),
|
||||
)->shouldBeCalledOnce();
|
||||
$adapter->getSlice(5, 10);
|
||||
}
|
||||
|
||||
@ -71,8 +74,9 @@ class ShortUrlRepositoryAdapterTest extends TestCase
|
||||
$adapter = new ShortUrlRepositoryAdapter($this->repo->reveal(), $params, $apiKey);
|
||||
$dateRange = $params->dateRange();
|
||||
|
||||
$this->repo->countList($searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $dateRange, $apiKey->spec())
|
||||
->shouldBeCalledOnce();
|
||||
$this->repo->countList(
|
||||
new ShortUrlsCountFiltering($searchTerm, $tags, ShortUrlsParams::TAGS_MODE_ANY, $dateRange, $apiKey),
|
||||
)->shouldBeCalledOnce();
|
||||
$adapter->getNbResults();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user