mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-24 05:38:06 +03:00
Updated ListShortUrlsAction api test so that it covers filtering use cases
This commit is contained in:
parent
35eeaf4282
commit
8142801f1f
3 changed files with 158 additions and 103 deletions
|
@ -54,15 +54,9 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
|
|||
|
||||
private function processOrderByForList(QueryBuilder $qb, $orderBy): array
|
||||
{
|
||||
// Map public field names to column names
|
||||
$fieldNameMap = [
|
||||
'originalUrl' => 'longUrl',
|
||||
'longUrl' => 'longUrl',
|
||||
'shortCode' => 'shortCode',
|
||||
'dateCreated' => 'dateCreated',
|
||||
];
|
||||
$fieldName = is_array($orderBy) ? key($orderBy) : $orderBy;
|
||||
$order = is_array($orderBy) ? $orderBy[$fieldName] : 'ASC';
|
||||
$isArray = is_array($orderBy);
|
||||
$fieldName = $isArray ? key($orderBy) : $orderBy;
|
||||
$order = $isArray ? $orderBy[$fieldName] : 'ASC';
|
||||
|
||||
if (contains(['visits', 'visitsCount', 'visitCount'], $fieldName)) {
|
||||
$qb->addSelect('COUNT(DISTINCT v) AS totalVisits')
|
||||
|
@ -73,6 +67,13 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
|
|||
return array_column($qb->getQuery()->getResult(), 0);
|
||||
}
|
||||
|
||||
// Map public field names to column names
|
||||
$fieldNameMap = [
|
||||
'originalUrl' => 'longUrl',
|
||||
'longUrl' => 'longUrl',
|
||||
'shortCode' => 'shortCode',
|
||||
'dateCreated' => 'dateCreated',
|
||||
];
|
||||
if (array_key_exists($fieldName, $fieldNameMap)) {
|
||||
$qb->orderBy('s.' . $fieldNameMap[$fieldName], $order);
|
||||
}
|
||||
|
|
|
@ -4,107 +4,160 @@ declare(strict_types=1);
|
|||
|
||||
namespace ShlinkioApiTest\Shlink\Rest\Action;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
|
||||
|
||||
use function count;
|
||||
|
||||
class ListShortUrlsTest extends ApiTestCase
|
||||
{
|
||||
/** @test */
|
||||
public function shortUrlsAreProperlyListed(): void
|
||||
private const SHORT_URL_SHLINK = [
|
||||
'shortCode' => 'abc123',
|
||||
'shortUrl' => 'http://doma.in/abc123',
|
||||
'longUrl' => 'https://shlink.io',
|
||||
'dateCreated' => '2018-05-01T00:00:00+00:00',
|
||||
'visitsCount' => 3,
|
||||
'tags' => ['foo'],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' => 'https://shlink.io',
|
||||
];
|
||||
private const SHORT_URL_CUSTOM_SLUG_AND_DOMAIN = [
|
||||
'shortCode' => 'custom-with-domain',
|
||||
'shortUrl' => 'http://some-domain.com/custom-with-domain',
|
||||
'longUrl' => 'https://google.com',
|
||||
'dateCreated' => '2018-10-20T00:00:00+00:00',
|
||||
'visitsCount' => 0,
|
||||
'tags' => [],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' => 'https://google.com',
|
||||
];
|
||||
private const SHORT_URL_META = [
|
||||
'shortCode' => 'def456',
|
||||
'shortUrl' => 'http://doma.in/def456',
|
||||
'longUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2017/12/09'
|
||||
. '/acmailer-7-0-the-most-important-release-in-a-long-time/',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 2,
|
||||
'tags' => ['bar', 'foo'],
|
||||
'meta' => [
|
||||
'validSince' => '2020-05-01T00:00:00+00:00',
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2017/12/09'
|
||||
. '/acmailer-7-0-the-most-important-release-in-a-long-time/',
|
||||
];
|
||||
private const SHORT_URL_CUSTOM_SLUG = [
|
||||
'shortCode' => 'custom',
|
||||
'shortUrl' => 'http://doma.in/custom',
|
||||
'longUrl' => 'https://shlink.io',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 0,
|
||||
'tags' => [],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => 2,
|
||||
],
|
||||
'originalUrl' => 'https://shlink.io',
|
||||
];
|
||||
private const SHORT_URL_CUSTOM_DOMAIN = [
|
||||
'shortCode' => 'ghi789',
|
||||
'shortUrl' => 'http://example.com/ghi789',
|
||||
'longUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2019/04/27'
|
||||
. '/considerations-to-properly-use-open-source-software-projects/',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 0,
|
||||
'tags' => [],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2019/04/27'
|
||||
. '/considerations-to-properly-use-open-source-software-projects/',
|
||||
];
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider provideFilteredLists
|
||||
*/
|
||||
public function shortUrlsAreProperlyListed(array $query, array $expectedShortUrls): void
|
||||
{
|
||||
$resp = $this->callApiWithKey(self::METHOD_GET, '/short-urls');
|
||||
$resp = $this->callApiWithKey(self::METHOD_GET, '/short-urls', [RequestOptions::QUERY => $query]);
|
||||
$respPayload = $this->getJsonResponsePayload($resp);
|
||||
|
||||
$this->assertEquals(self::STATUS_OK, $resp->getStatusCode());
|
||||
$this->assertEquals([
|
||||
'shortUrls' => [
|
||||
'data' => [
|
||||
[
|
||||
'shortCode' => 'abc123',
|
||||
'shortUrl' => 'http://doma.in/abc123',
|
||||
'longUrl' => 'https://shlink.io',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 3,
|
||||
'tags' => ['foo'],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' => 'https://shlink.io',
|
||||
],
|
||||
[
|
||||
'shortCode' => 'def456',
|
||||
'shortUrl' => 'http://doma.in/def456',
|
||||
'longUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2017/12/09'
|
||||
. '/acmailer-7-0-the-most-important-release-in-a-long-time/',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 2,
|
||||
'tags' => ['bar', 'foo'],
|
||||
'meta' => [
|
||||
'validSince' => '2020-05-01T00:00:00+00:00',
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2017/12/09'
|
||||
. '/acmailer-7-0-the-most-important-release-in-a-long-time/',
|
||||
],
|
||||
[
|
||||
'shortCode' => 'custom',
|
||||
'shortUrl' => 'http://doma.in/custom',
|
||||
'longUrl' => 'https://shlink.io',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 0,
|
||||
'tags' => [],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => 2,
|
||||
],
|
||||
'originalUrl' => 'https://shlink.io',
|
||||
],
|
||||
[
|
||||
'shortCode' => 'ghi789',
|
||||
'shortUrl' => 'http://example.com/ghi789',
|
||||
'longUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2019/04/27'
|
||||
. '/considerations-to-properly-use-open-source-software-projects/',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 0,
|
||||
'tags' => [],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' =>
|
||||
'https://blog.alejandrocelaya.com/2019/04/27'
|
||||
. '/considerations-to-properly-use-open-source-software-projects/',
|
||||
],
|
||||
[
|
||||
'shortCode' => 'custom-with-domain',
|
||||
'shortUrl' => 'http://some-domain.com/custom-with-domain',
|
||||
'longUrl' => 'https://google.com',
|
||||
'dateCreated' => '2019-01-01T00:00:00+00:00',
|
||||
'visitsCount' => 0,
|
||||
'tags' => [],
|
||||
'meta' => [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
],
|
||||
'originalUrl' => 'https://google.com',
|
||||
],
|
||||
],
|
||||
'pagination' => [
|
||||
'currentPage' => 1,
|
||||
'pagesCount' => 1,
|
||||
'itemsPerPage' => 10,
|
||||
'itemsInCurrentPage' => 5,
|
||||
'totalItems' => 5,
|
||||
],
|
||||
'data' => $expectedShortUrls,
|
||||
'pagination' => $this->buildPagination(count($expectedShortUrls)),
|
||||
],
|
||||
], $respPayload);
|
||||
}
|
||||
|
||||
public function provideFilteredLists(): iterable
|
||||
{
|
||||
yield [[], [
|
||||
self::SHORT_URL_SHLINK,
|
||||
self::SHORT_URL_CUSTOM_SLUG_AND_DOMAIN,
|
||||
self::SHORT_URL_META,
|
||||
self::SHORT_URL_CUSTOM_SLUG,
|
||||
self::SHORT_URL_CUSTOM_DOMAIN,
|
||||
]];
|
||||
yield [['orderBy' => 'shortCode'], [
|
||||
self::SHORT_URL_SHLINK,
|
||||
self::SHORT_URL_CUSTOM_SLUG,
|
||||
self::SHORT_URL_CUSTOM_SLUG_AND_DOMAIN,
|
||||
self::SHORT_URL_META,
|
||||
self::SHORT_URL_CUSTOM_DOMAIN,
|
||||
]];
|
||||
yield [['startDate' => Chronos::parse('2018-12-01')->toAtomString()], [
|
||||
self::SHORT_URL_META,
|
||||
self::SHORT_URL_CUSTOM_SLUG,
|
||||
self::SHORT_URL_CUSTOM_DOMAIN,
|
||||
]];
|
||||
yield [['endDate' => Chronos::parse('2018-12-01')->toAtomString()], [
|
||||
self::SHORT_URL_SHLINK,
|
||||
self::SHORT_URL_CUSTOM_SLUG_AND_DOMAIN,
|
||||
]];
|
||||
yield [['tags' => ['foo']], [
|
||||
self::SHORT_URL_SHLINK,
|
||||
self::SHORT_URL_META,
|
||||
]];
|
||||
yield [['tags' => ['bar']], [
|
||||
self::SHORT_URL_META,
|
||||
]];
|
||||
yield [['tags' => ['foo'], 'endDate' => Chronos::parse('2018-12-01')->toAtomString()], [
|
||||
self::SHORT_URL_SHLINK,
|
||||
]];
|
||||
yield [['searchTerm' => 'alejandro'], [
|
||||
self::SHORT_URL_META,
|
||||
self::SHORT_URL_CUSTOM_DOMAIN,
|
||||
]];
|
||||
}
|
||||
|
||||
private function buildPagination(int $itemsCount): array
|
||||
{
|
||||
return [
|
||||
'currentPage' => 1,
|
||||
'pagesCount' => 1,
|
||||
'itemsPerPage' => 10,
|
||||
'itemsInCurrentPage' => $itemsCount,
|
||||
'totalItems' => $itemsCount,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ class ShortUrlsFixture extends AbstractFixture
|
|||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$abcShortUrl = $this->setShortUrlDate(
|
||||
new ShortUrl('https://shlink.io', ShortUrlMeta::createFromRawData(['customSlug' => 'abc123']))
|
||||
new ShortUrl('https://shlink.io', ShortUrlMeta::createFromRawData(['customSlug' => 'abc123'])),
|
||||
Chronos::parse('2018-05-01')
|
||||
);
|
||||
$manager->persist($abcShortUrl);
|
||||
|
||||
|
@ -46,7 +47,7 @@ class ShortUrlsFixture extends AbstractFixture
|
|||
$withDomainAndSlugShortUrl = $this->setShortUrlDate(new ShortUrl(
|
||||
'https://google.com',
|
||||
ShortUrlMeta::createFromRawData(['domain' => 'some-domain.com', 'customSlug' => 'custom-with-domain'])
|
||||
));
|
||||
), Chronos::parse('2018-10-20'));
|
||||
$manager->persist($withDomainAndSlugShortUrl);
|
||||
|
||||
$manager->flush();
|
||||
|
@ -55,12 +56,12 @@ class ShortUrlsFixture extends AbstractFixture
|
|||
$this->addReference('def456_short_url', $defShortUrl);
|
||||
}
|
||||
|
||||
private function setShortUrlDate(ShortUrl $shortUrl): ShortUrl
|
||||
private function setShortUrlDate(ShortUrl $shortUrl, ?Chronos $date = null): ShortUrl
|
||||
{
|
||||
$ref = new ReflectionObject($shortUrl);
|
||||
$dateProp = $ref->getProperty('dateCreated');
|
||||
$dateProp->setAccessible(true);
|
||||
$dateProp->setValue($shortUrl, Chronos::create(2019, 1, 1, 0, 0, 0));
|
||||
$dateProp->setValue($shortUrl, $date ?? Chronos::parse('2019-01-01'));
|
||||
|
||||
return $shortUrl;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue