mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-17 15:59:56 +03:00
Allowed domain to be provided when editing short URL meta
This commit is contained in:
parent
732bb06c62
commit
5d1d9dcac3
8 changed files with 49 additions and 78 deletions
|
@ -53,10 +53,14 @@ return [
|
|||
|
||||
Service\UrlShortener::class => [Util\UrlValidator::class, 'em', Options\UrlShortenerOptions::class],
|
||||
Service\VisitsTracker::class => ['em', EventDispatcherInterface::class],
|
||||
Service\ShortUrlService::class => ['em'],
|
||||
Service\ShortUrlService::class => ['em', Service\ShortUrl\ShortUrlResolver::class],
|
||||
Service\VisitService::class => ['em'],
|
||||
Service\Tag\TagService::class => ['em'],
|
||||
Service\ShortUrl\DeleteShortUrlService::class => ['em', Options\DeleteShortUrlsOptions::class],
|
||||
Service\ShortUrl\DeleteShortUrlService::class => [
|
||||
'em',
|
||||
Options\DeleteShortUrlsOptions::class,
|
||||
Service\ShortUrl\ShortUrlResolver::class,
|
||||
],
|
||||
Service\ShortUrl\ShortUrlResolver::class => ['em'],
|
||||
|
||||
Util\UrlValidator::class => ['httpClient'],
|
||||
|
|
|
@ -12,15 +12,18 @@ use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions;
|
|||
|
||||
class DeleteShortUrlService implements DeleteShortUrlServiceInterface
|
||||
{
|
||||
use FindShortCodeTrait;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
private DeleteShortUrlsOptions $deleteShortUrlsOptions;
|
||||
private ShortUrlResolverInterface $urlResolver;
|
||||
|
||||
public function __construct(EntityManagerInterface $em, DeleteShortUrlsOptions $deleteShortUrlsOptions)
|
||||
{
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
DeleteShortUrlsOptions $deleteShortUrlsOptions,
|
||||
ShortUrlResolverInterface $urlResolver
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->deleteShortUrlsOptions = $deleteShortUrlsOptions;
|
||||
$this->urlResolver = $urlResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,7 +32,7 @@ class DeleteShortUrlService implements DeleteShortUrlServiceInterface
|
|||
*/
|
||||
public function deleteByShortCode(ShortUrlIdentifier $identifier, bool $ignoreThreshold = false): void
|
||||
{
|
||||
$shortUrl = $this->findByShortCode($this->em, $identifier);
|
||||
$shortUrl = $this->urlResolver->resolveShortUrl($identifier);
|
||||
if (! $ignoreThreshold && $this->isThresholdReached($shortUrl)) {
|
||||
throw Exception\DeleteShortUrlException::fromVisitsThreshold(
|
||||
$this->deleteShortUrlsOptions->getVisitsThreshold(),
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Service\ShortUrl;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
|
||||
trait FindShortCodeTrait
|
||||
{
|
||||
/**
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
private function findByShortCode(EntityManagerInterface $em, ShortUrlIdentifier $identifier): ShortUrl
|
||||
{
|
||||
/** @var ShortUrlRepositoryInterface $repo */
|
||||
$repo = $em->getRepository(ShortUrl::class);
|
||||
$shortUrl = $repo->findOneByShortCode($identifier->shortCode(), $identifier->domain());
|
||||
if ($shortUrl === null) {
|
||||
throw ShortUrlNotFoundException::fromNotFound($identifier);
|
||||
}
|
||||
|
||||
return $shortUrl;
|
||||
}
|
||||
}
|
|
@ -13,19 +13,20 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
|||
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\FindShortCodeTrait;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Util\TagManagerTrait;
|
||||
|
||||
class ShortUrlService implements ShortUrlServiceInterface
|
||||
{
|
||||
use FindShortCodeTrait;
|
||||
use TagManagerTrait;
|
||||
|
||||
private ORM\EntityManagerInterface $em;
|
||||
private ShortUrlResolverInterface $urlResolver;
|
||||
|
||||
public function __construct(ORM\EntityManagerInterface $em)
|
||||
public function __construct(ORM\EntityManagerInterface $em, ShortUrlResolverInterface $urlResolver)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->urlResolver = $urlResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,8 +49,9 @@ class ShortUrlService implements ShortUrlServiceInterface
|
|||
*/
|
||||
public function setTagsByShortCode(string $shortCode, array $tags = []): ShortUrl
|
||||
{
|
||||
$shortUrl = $this->findByShortCode($this->em, new ShortUrlIdentifier($shortCode));
|
||||
$shortUrl = $this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode));
|
||||
$shortUrl->setTags($this->tagNamesToEntities($this->em, $tags));
|
||||
|
||||
$this->em->flush();
|
||||
|
||||
return $shortUrl;
|
||||
|
@ -58,9 +60,9 @@ class ShortUrlService implements ShortUrlServiceInterface
|
|||
/**
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
public function updateMetadataByShortCode(string $shortCode, ShortUrlMeta $shortUrlMeta): ShortUrl
|
||||
public function updateMetadataByShortCode(ShortUrlIdentifier $identifier, ShortUrlMeta $shortUrlMeta): ShortUrl
|
||||
{
|
||||
$shortUrl = $this->findByShortCode($this->em, new ShortUrlIdentifier($shortCode));
|
||||
$shortUrl = $this->urlResolver->resolveShortUrl($identifier);
|
||||
$shortUrl->updateMeta($shortUrlMeta);
|
||||
|
||||
$this->em->flush();
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Core\Service;
|
|||
use Laminas\Paginator\Paginator;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
||||
|
||||
|
@ -26,5 +27,5 @@ interface ShortUrlServiceInterface
|
|||
/**
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
public function updateMetadataByShortCode(string $shortCode, ShortUrlMeta $shortUrlMeta): ShortUrl;
|
||||
public function updateMetadataByShortCode(ShortUrlIdentifier $identifier, ShortUrlMeta $shortUrlMeta): ShortUrl;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ use Shlinkio\Shlink\Core\Exception\DeleteShortUrlException;
|
|||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlService;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
|
||||
use function Functional\map;
|
||||
use function range;
|
||||
|
@ -25,6 +25,7 @@ use function sprintf;
|
|||
class DeleteShortUrlServiceTest extends TestCase
|
||||
{
|
||||
private ObjectProphecy $em;
|
||||
private ObjectProphecy $urlResolver;
|
||||
private string $shortCode;
|
||||
|
||||
public function setUp(): void
|
||||
|
@ -36,9 +37,8 @@ class DeleteShortUrlServiceTest extends TestCase
|
|||
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
|
||||
$repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
$repo->findOneByShortCode(Argument::cetera())->willReturn($shortUrl);
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
$this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
|
||||
$this->urlResolver->resolveShortUrl(Argument::cetera())->willReturn($shortUrl);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
@ -102,6 +102,6 @@ class DeleteShortUrlServiceTest extends TestCase
|
|||
return new DeleteShortUrlService($this->em->reveal(), new DeleteShortUrlsOptions([
|
||||
'visitsThreshold' => $visitsThreshold,
|
||||
'checkVisitsThreshold' => $checkVisitsThreshold,
|
||||
]));
|
||||
]), $this->urlResolver->reveal());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,11 @@ use Prophecy\Argument;
|
|||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrlService;
|
||||
|
||||
use function count;
|
||||
|
@ -24,13 +25,17 @@ class ShortUrlServiceTest extends TestCase
|
|||
{
|
||||
private ShortUrlService $service;
|
||||
private ObjectProphecy $em;
|
||||
private ObjectProphecy $urlResolver;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->em = $this->prophesize(EntityManagerInterface::class);
|
||||
$this->em->persist(Argument::any())->willReturn(null);
|
||||
$this->em->flush()->willReturn(null);
|
||||
$this->service = new ShortUrlService($this->em->reveal());
|
||||
|
||||
$this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
|
||||
|
||||
$this->service = new ShortUrlService($this->em->reveal(), $this->urlResolver->reveal());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
@ -52,29 +57,14 @@ class ShortUrlServiceTest extends TestCase
|
|||
$this->assertEquals(4, $list->getCurrentItemCount());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function exceptionIsThrownWhenSettingTagsOnInvalidShortcode(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$repo = $this->prophesize(ShortUrlRepository::class);
|
||||
$repo->findOneByShortCode($shortCode, null)->willReturn(null)
|
||||
->shouldBeCalledOnce();
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$this->expectException(ShortUrlNotFoundException::class);
|
||||
$this->service->setTagsByShortCode($shortCode);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function providedTagsAreGetFromRepoAndSetToTheShortUrl(): void
|
||||
{
|
||||
$shortUrl = $this->prophesize(ShortUrl::class);
|
||||
$shortUrl->setTags(Argument::any())->shouldBeCalledOnce();
|
||||
$shortCode = 'abc123';
|
||||
$repo = $this->prophesize(ShortUrlRepository::class);
|
||||
$repo->findOneByShortCode($shortCode, null)->willReturn($shortUrl->reveal())
|
||||
->shouldBeCalledOnce();
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
$this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode))->willReturn($shortUrl->reveal())
|
||||
->shouldBeCalledOnce();
|
||||
|
||||
$tagRepo = $this->prophesize(EntityRepository::class);
|
||||
$tagRepo->findOneBy(['name' => 'foo'])->willReturn(new Tag('foo'))->shouldBeCalledOnce();
|
||||
|
@ -89,23 +79,22 @@ class ShortUrlServiceTest extends TestCase
|
|||
{
|
||||
$shortUrl = new ShortUrl('');
|
||||
|
||||
$repo = $this->prophesize(ShortUrlRepository::class);
|
||||
$findShortUrl = $repo->findOneByShortCode('abc123', null)->willReturn($shortUrl);
|
||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
$findShortUrl = $this->urlResolver->resolveShortUrl(new ShortUrlIdentifier('abc123'))->willReturn($shortUrl);
|
||||
$flush = $this->em->flush()->willReturn(null);
|
||||
|
||||
$result = $this->service->updateMetadataByShortCode('abc123', ShortUrlMeta::fromRawData([
|
||||
'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
||||
'validUntil' => Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
|
||||
'maxVisits' => 5,
|
||||
]));
|
||||
$result = $this->service->updateMetadataByShortCode(new ShortUrlIdentifier('abc123'), ShortUrlMeta::fromRawData(
|
||||
[
|
||||
'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
||||
'validUntil' => Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
|
||||
'maxVisits' => 5,
|
||||
],
|
||||
));
|
||||
|
||||
$this->assertSame($shortUrl, $result);
|
||||
$this->assertEquals(Chronos::parse('2017-01-01 00:00:00'), $shortUrl->getValidSince());
|
||||
$this->assertEquals(Chronos::parse('2017-01-05 00:00:00'), $shortUrl->getValidUntil());
|
||||
$this->assertEquals(5, $shortUrl->getMaxVisits());
|
||||
$findShortUrl->shouldHaveBeenCalled();
|
||||
$getRepo->shouldHaveBeenCalled();
|
||||
$flush->shouldHaveBeenCalled();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
|||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
|
||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
|
@ -28,9 +29,9 @@ class EditShortUrlAction extends AbstractRestAction
|
|||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$postData = (array) $request->getParsedBody();
|
||||
$shortCode = $request->getAttribute('shortCode', '');
|
||||
$identifier = ShortUrlIdentifier::fromApiRequest($request);
|
||||
|
||||
$this->shortUrlService->updateMetadataByShortCode($shortCode, ShortUrlMeta::fromRawData($postData));
|
||||
$this->shortUrlService->updateMetadataByShortCode($identifier, ShortUrlMeta::fromRawData($postData));
|
||||
return new EmptyResponse();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue