mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Removed use of deprecated methods in DB tests
This commit is contained in:
parent
1cd6fdeede
commit
c58fa586e1
@ -130,7 +130,7 @@ class ShortUrl extends AbstractEntity
|
||||
|
||||
/**
|
||||
* @param Collection|Tag[] $tags
|
||||
* @deprecated
|
||||
* @deprecated Use ShortUrl::update to set the tags on this ShortUrl
|
||||
*/
|
||||
public function setTags(Collection $tags): self
|
||||
{
|
||||
|
@ -10,14 +10,12 @@ use ReflectionObject;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsOrdering;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\PersistenceShortUrlRelationResolver;
|
||||
use Shlinkio\Shlink\Core\Util\TagManagerTrait;
|
||||
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
@ -27,13 +25,13 @@ use function count;
|
||||
|
||||
class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
{
|
||||
use TagManagerTrait;
|
||||
|
||||
private ShortUrlRepository $repo;
|
||||
private PersistenceShortUrlRelationResolver $relationResolver;
|
||||
|
||||
public function beforeEach(): void
|
||||
{
|
||||
$this->repo = $this->getEntityManager()->getRepository(ShortUrl::class);
|
||||
$this->relationResolver = new PersistenceShortUrlRelationResolver($this->getEntityManager());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -90,11 +88,10 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
/** @test */
|
||||
public function findListProperlyFiltersResult(): void
|
||||
{
|
||||
$tag = new Tag('bar');
|
||||
$this->getEntityManager()->persist($tag);
|
||||
|
||||
$foo = ShortUrl::withLongUrl('foo');
|
||||
$foo->setTags(new ArrayCollection([$tag]));
|
||||
$foo = ShortUrl::fromMeta(
|
||||
ShortUrlMeta::fromRawData(['longUrl' => 'foo', 'tags' => ['bar']]),
|
||||
$this->relationResolver,
|
||||
);
|
||||
$this->getEntityManager()->persist($foo);
|
||||
|
||||
$bar = ShortUrl::withLongUrl('bar');
|
||||
@ -235,8 +232,10 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
$start = Chronos::parse('2020-03-05 20:18:30');
|
||||
$end = Chronos::parse('2021-03-05 20:18:30');
|
||||
|
||||
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData(['validSince' => $start, 'longUrl' => 'foo']));
|
||||
$shortUrl->setTags($this->tagNamesToEntities($this->getEntityManager(), ['foo', 'bar']));
|
||||
$shortUrl = ShortUrl::fromMeta(
|
||||
ShortUrlMeta::fromRawData(['validSince' => $start, 'longUrl' => 'foo', 'tags' => ['foo', 'bar']]),
|
||||
$this->relationResolver,
|
||||
);
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
|
||||
$shortUrl2 = ShortUrl::fromMeta(ShortUrlMeta::fromRawData(['validUntil' => $end, 'longUrl' => 'bar']));
|
||||
@ -300,28 +299,24 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
public function findOneMatchingReturnsOldestOneWhenThereAreMultipleMatches(): void
|
||||
{
|
||||
$start = Chronos::parse('2020-03-05 20:18:30');
|
||||
$meta = ShortUrlMeta::fromRawData(['validSince' => $start, 'maxVisits' => 50, 'longUrl' => 'foo']);
|
||||
$tags = ['foo', 'bar'];
|
||||
$tagEntities = $this->tagNamesToEntities($this->getEntityManager(), $tags);
|
||||
$metaWithTags = ShortUrlMeta::fromRawData(
|
||||
$meta = ShortUrlMeta::fromRawData(
|
||||
['validSince' => $start, 'maxVisits' => 50, 'longUrl' => 'foo', 'tags' => $tags],
|
||||
);
|
||||
|
||||
$shortUrl1 = ShortUrl::fromMeta($meta);
|
||||
$shortUrl1->setTags($tagEntities);
|
||||
$shortUrl1 = ShortUrl::fromMeta($meta, $this->relationResolver);
|
||||
$this->getEntityManager()->persist($shortUrl1);
|
||||
|
||||
$shortUrl2 = ShortUrl::fromMeta($meta);
|
||||
$shortUrl2->setTags($tagEntities);
|
||||
$this->getEntityManager()->persist($shortUrl2);
|
||||
|
||||
$shortUrl3 = ShortUrl::fromMeta($meta);
|
||||
$shortUrl3->setTags($tagEntities);
|
||||
$this->getEntityManager()->persist($shortUrl3);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$result = $this->repo->findOneMatching($metaWithTags);
|
||||
$shortUrl2 = ShortUrl::fromMeta($meta, $this->relationResolver);
|
||||
$this->getEntityManager()->persist($shortUrl2);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$shortUrl3 = ShortUrl::fromMeta($meta, $this->relationResolver);
|
||||
$this->getEntityManager()->persist($shortUrl3);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$result = $this->repo->findOneMatching($meta);
|
||||
|
||||
self::assertSame($shortUrl1, $result);
|
||||
self::assertNotSame($shortUrl2, $result);
|
||||
@ -349,10 +344,13 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
$rightDomainApiKey = ApiKey::withRoles(RoleDefinition::forDomain($rightDomain));
|
||||
$this->getEntityManager()->persist($rightDomainApiKey);
|
||||
|
||||
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData(
|
||||
['validSince' => $start, 'apiKey' => $apiKey, 'domain' => $rightDomain->getAuthority(), 'longUrl' => 'foo'],
|
||||
), new PersistenceShortUrlRelationResolver($this->getEntityManager()));
|
||||
$shortUrl->setTags($this->tagNamesToEntities($this->getEntityManager(), ['foo', 'bar']));
|
||||
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
|
||||
'validSince' => $start,
|
||||
'apiKey' => $apiKey,
|
||||
'domain' => $rightDomain->getAuthority(),
|
||||
'longUrl' => 'foo',
|
||||
'tags' => ['foo', 'bar'],
|
||||
]), $this->relationResolver);
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Core\Repository;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
@ -22,10 +21,12 @@ use function array_chunk;
|
||||
class TagRepositoryTest extends DatabaseTestCase
|
||||
{
|
||||
private TagRepository $repo;
|
||||
private PersistenceShortUrlRelationResolver $relationResolver;
|
||||
|
||||
protected function beforeEach(): void
|
||||
{
|
||||
$this->repo = $this->getEntityManager()->getRepository(Tag::class);
|
||||
$this->relationResolver = new PersistenceShortUrlRelationResolver($this->getEntityManager());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -52,49 +53,44 @@ class TagRepositoryTest extends DatabaseTestCase
|
||||
public function properTagsInfoIsReturned(): void
|
||||
{
|
||||
$names = ['foo', 'bar', 'baz', 'another'];
|
||||
$tags = [];
|
||||
foreach ($names as $name) {
|
||||
$tag = new Tag($name);
|
||||
$tags[] = $tag;
|
||||
$this->getEntityManager()->persist($tag);
|
||||
$this->getEntityManager()->persist(new Tag($name));
|
||||
}
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
[$firstUrlTags] = array_chunk($tags, 3);
|
||||
$secondUrlTags = [$tags[0]];
|
||||
[$firstUrlTags] = array_chunk($names, 3);
|
||||
$secondUrlTags = [$names[0]];
|
||||
$metaWithTags = fn (array $tags) => ShortUrlMeta::fromRawData(['longUrl' => '', 'tags' => $tags]);
|
||||
|
||||
$shortUrl = ShortUrl::createEmpty();
|
||||
$shortUrl->setTags(new ArrayCollection($firstUrlTags));
|
||||
$shortUrl = ShortUrl::fromMeta($metaWithTags($firstUrlTags), $this->relationResolver);
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
$this->getEntityManager()->persist(new Visit($shortUrl, Visitor::emptyInstance()));
|
||||
$this->getEntityManager()->persist(new Visit($shortUrl, Visitor::emptyInstance()));
|
||||
$this->getEntityManager()->persist(new Visit($shortUrl, Visitor::emptyInstance()));
|
||||
|
||||
$shortUrl2 = ShortUrl::createEmpty();
|
||||
$shortUrl2->setTags(new ArrayCollection($secondUrlTags));
|
||||
$shortUrl2 = ShortUrl::fromMeta($metaWithTags($secondUrlTags), $this->relationResolver);
|
||||
$this->getEntityManager()->persist($shortUrl2);
|
||||
$this->getEntityManager()->persist(new Visit($shortUrl2, Visitor::emptyInstance()));
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$result = $this->repo->findTagsWithInfo();
|
||||
|
||||
self::assertCount(4, $result);
|
||||
self::assertEquals(
|
||||
['tag' => $tags[3], 'shortUrlsCount' => 0, 'visitsCount' => 0],
|
||||
$result[0]->jsonSerialize(),
|
||||
);
|
||||
self::assertEquals(
|
||||
['tag' => $tags[1], 'shortUrlsCount' => 1, 'visitsCount' => 3],
|
||||
$result[1]->jsonSerialize(),
|
||||
);
|
||||
self::assertEquals(
|
||||
['tag' => $tags[2], 'shortUrlsCount' => 1, 'visitsCount' => 3],
|
||||
$result[2]->jsonSerialize(),
|
||||
);
|
||||
self::assertEquals(
|
||||
['tag' => $tags[0], 'shortUrlsCount' => 2, 'visitsCount' => 4],
|
||||
$result[3]->jsonSerialize(),
|
||||
);
|
||||
self::assertEquals(0, $result[0]->shortUrlsCount());
|
||||
self::assertEquals(0, $result[0]->visitsCount());
|
||||
self::assertEquals($names[3], $result[0]->tag()->__toString());
|
||||
|
||||
self::assertEquals(1, $result[1]->shortUrlsCount());
|
||||
self::assertEquals(3, $result[1]->visitsCount());
|
||||
self::assertEquals($names[1], $result[1]->tag()->__toString());
|
||||
|
||||
self::assertEquals(1, $result[2]->shortUrlsCount());
|
||||
self::assertEquals(3, $result[2]->visitsCount());
|
||||
self::assertEquals($names[2], $result[2]->tag()->__toString());
|
||||
|
||||
self::assertEquals(2, $result[3]->shortUrlsCount());
|
||||
self::assertEquals(4, $result[3]->visitsCount());
|
||||
self::assertEquals($names[0], $result[3]->tag()->__toString());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -110,24 +106,23 @@ class TagRepositoryTest extends DatabaseTestCase
|
||||
$this->getEntityManager()->persist($domainApiKey);
|
||||
|
||||
$names = ['foo', 'bar', 'baz', 'another'];
|
||||
$tags = [];
|
||||
foreach ($names as $name) {
|
||||
$tag = new Tag($name);
|
||||
$tags[] = $tag;
|
||||
$this->getEntityManager()->persist($tag);
|
||||
$this->getEntityManager()->persist(new Tag($name));
|
||||
}
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
[$firstUrlTags, $secondUrlTags] = array_chunk($tags, 3);
|
||||
[$firstUrlTags, $secondUrlTags] = array_chunk($names, 3);
|
||||
|
||||
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData(['apiKey' => $authorApiKey, 'longUrl' => '']));
|
||||
$shortUrl->setTags(new ArrayCollection($firstUrlTags));
|
||||
$shortUrl = ShortUrl::fromMeta(
|
||||
ShortUrlMeta::fromRawData(['apiKey' => $authorApiKey, 'longUrl' => '', 'tags' => $firstUrlTags]),
|
||||
$this->relationResolver,
|
||||
);
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
|
||||
$shortUrl2 = ShortUrl::fromMeta(
|
||||
ShortUrlMeta::fromRawData(['domain' => $domain->getAuthority(), 'longUrl' => '']),
|
||||
new PersistenceShortUrlRelationResolver($this->getEntityManager()),
|
||||
ShortUrlMeta::fromRawData(['domain' => $domain->getAuthority(), 'longUrl' => '', 'tags' => $secondUrlTags]),
|
||||
$this->relationResolver,
|
||||
);
|
||||
$shortUrl2->setTags(new ArrayCollection($secondUrlTags));
|
||||
$this->getEntityManager()->persist($shortUrl2);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
|
@ -5,11 +5,9 @@ declare(strict_types=1);
|
||||
namespace ShlinkioTest\Shlink\Core\Repository;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Entity\VisitLocation;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
@ -28,10 +26,12 @@ use function sprintf;
|
||||
class VisitRepositoryTest extends DatabaseTestCase
|
||||
{
|
||||
private VisitRepository $repo;
|
||||
private PersistenceShortUrlRelationResolver $relationResolver;
|
||||
|
||||
protected function beforeEach(): void
|
||||
{
|
||||
$this->repo = $this->getEntityManager()->getRepository(Visit::class);
|
||||
$this->relationResolver = new PersistenceShortUrlRelationResolver($this->getEntityManager());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,58 +126,45 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||
/** @test */
|
||||
public function findVisitsByTagReturnsProperData(): void
|
||||
{
|
||||
$foo = new Tag('foo');
|
||||
$this->getEntityManager()->persist($foo);
|
||||
$foo = 'foo';
|
||||
|
||||
/** @var ShortUrl $shortUrl */
|
||||
[,, $shortUrl] = $this->createShortUrlsAndVisits(false);
|
||||
/** @var ShortUrl $shortUrl2 */
|
||||
[,, $shortUrl2] = $this->createShortUrlsAndVisits(false);
|
||||
/** @var ShortUrl $shortUrl3 */
|
||||
[,, $shortUrl3] = $this->createShortUrlsAndVisits(false);
|
||||
$this->createShortUrlsAndVisits(false, [$foo]);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$shortUrl->setTags(new ArrayCollection([$foo]));
|
||||
$shortUrl2->setTags(new ArrayCollection([$foo]));
|
||||
$shortUrl3->setTags(new ArrayCollection([$foo]));
|
||||
$this->createShortUrlsAndVisits(false, [$foo]);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$this->createShortUrlsAndVisits(false, [$foo]);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
self::assertCount(0, $this->repo->findVisitsByTag('invalid'));
|
||||
self::assertCount(18, $this->repo->findVisitsByTag((string) $foo));
|
||||
self::assertCount(6, $this->repo->findVisitsByTag((string) $foo, new DateRange(
|
||||
self::assertCount(18, $this->repo->findVisitsByTag($foo));
|
||||
self::assertCount(6, $this->repo->findVisitsByTag($foo, new DateRange(
|
||||
Chronos::parse('2016-01-02'),
|
||||
Chronos::parse('2016-01-03'),
|
||||
)));
|
||||
self::assertCount(12, $this->repo->findVisitsByTag((string) $foo, new DateRange(
|
||||
Chronos::parse('2016-01-03'),
|
||||
)));
|
||||
self::assertCount(12, $this->repo->findVisitsByTag($foo, new DateRange(Chronos::parse('2016-01-03'))));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function countVisitsByTagReturnsProperData(): void
|
||||
{
|
||||
$foo = new Tag('foo');
|
||||
$this->getEntityManager()->persist($foo);
|
||||
$foo = 'foo';
|
||||
|
||||
/** @var ShortUrl $shortUrl */
|
||||
[,, $shortUrl] = $this->createShortUrlsAndVisits(false);
|
||||
/** @var ShortUrl $shortUrl2 */
|
||||
[,, $shortUrl2] = $this->createShortUrlsAndVisits(false);
|
||||
|
||||
$shortUrl->setTags(new ArrayCollection([$foo]));
|
||||
$shortUrl2->setTags(new ArrayCollection([$foo]));
|
||||
$this->createShortUrlsAndVisits(false, [$foo]);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
$this->createShortUrlsAndVisits(false, [$foo]);
|
||||
$this->getEntityManager()->flush();
|
||||
|
||||
self::assertEquals(0, $this->repo->countVisitsByTag('invalid'));
|
||||
self::assertEquals(12, $this->repo->countVisitsByTag((string) $foo));
|
||||
self::assertEquals(4, $this->repo->countVisitsByTag((string) $foo, new DateRange(
|
||||
self::assertEquals(12, $this->repo->countVisitsByTag($foo));
|
||||
self::assertEquals(4, $this->repo->countVisitsByTag($foo, new DateRange(
|
||||
Chronos::parse('2016-01-02'),
|
||||
Chronos::parse('2016-01-03'),
|
||||
)));
|
||||
self::assertEquals(8, $this->repo->countVisitsByTag((string) $foo, new DateRange(
|
||||
Chronos::parse('2016-01-03'),
|
||||
)));
|
||||
self::assertEquals(8, $this->repo->countVisitsByTag($foo, new DateRange(Chronos::parse('2016-01-03'))));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -192,7 +179,7 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||
$this->getEntityManager()->persist($apiKey1);
|
||||
$shortUrl = ShortUrl::fromMeta(
|
||||
ShortUrlMeta::fromRawData(['apiKey' => $apiKey1, 'domain' => $domain->getAuthority(), 'longUrl' => '']),
|
||||
new PersistenceShortUrlRelationResolver($this->getEntityManager()),
|
||||
$this->relationResolver,
|
||||
);
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
$this->createVisitsForShortUrl($shortUrl, 4);
|
||||
@ -205,7 +192,7 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||
|
||||
$shortUrl3 = ShortUrl::fromMeta(
|
||||
ShortUrlMeta::fromRawData(['apiKey' => $apiKey2, 'domain' => $domain->getAuthority(), 'longUrl' => '']),
|
||||
new PersistenceShortUrlRelationResolver($this->getEntityManager()),
|
||||
$this->relationResolver,
|
||||
);
|
||||
$this->getEntityManager()->persist($shortUrl3);
|
||||
$this->createVisitsForShortUrl($shortUrl3, 7);
|
||||
@ -221,9 +208,12 @@ class VisitRepositoryTest extends DatabaseTestCase
|
||||
self::assertEquals(4 + 7, $this->repo->countVisits($domainApiKey));
|
||||
}
|
||||
|
||||
private function createShortUrlsAndVisits(bool $withDomain = true): array
|
||||
private function createShortUrlsAndVisits(bool $withDomain = true, array $tags = []): array
|
||||
{
|
||||
$shortUrl = ShortUrl::createEmpty();
|
||||
$shortUrl = ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
|
||||
'longUrl' => '',
|
||||
'tags' => $tags,
|
||||
]), $this->relationResolver);
|
||||
$domain = 'example.com';
|
||||
$shortCode = $shortUrl->getShortCode();
|
||||
$this->getEntityManager()->persist($shortUrl);
|
||||
|
@ -81,11 +81,10 @@ class ShortUrlServiceTest extends TestCase
|
||||
*/
|
||||
public function providedTagsAreGetFromRepoAndSetToTheShortUrl(?ApiKey $apiKey): void
|
||||
{
|
||||
$shortUrl = $this->prophesize(ShortUrl::class);
|
||||
$shortUrl->setTags(Argument::any())->shouldBeCalledOnce();
|
||||
$shortUrl = ShortUrl::createEmpty();
|
||||
$shortCode = 'abc123';
|
||||
$this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode), $apiKey)
|
||||
->willReturn($shortUrl->reveal())
|
||||
->willReturn($shortUrl)
|
||||
->shouldBeCalledOnce();
|
||||
|
||||
$tagRepo = $this->prophesize(EntityRepository::class);
|
||||
|
@ -5,14 +5,12 @@ declare(strict_types=1);
|
||||
namespace ShlinkioTest\Shlink\Core\Service;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
|
Loading…
Reference in New Issue
Block a user