Updated short URL edition so that it supports editing tags

This commit is contained in:
Alejandro Celaya 2021-01-31 12:12:21 +01:00
parent c58fa586e1
commit 977058d219
5 changed files with 41 additions and 5 deletions

View File

@ -77,7 +77,12 @@ return [
EventDispatcherInterface::class, EventDispatcherInterface::class,
'config.url_shortener.anonymize_remote_addr', 'config.url_shortener.anonymize_remote_addr',
], ],
Service\ShortUrlService::class => ['em', Service\ShortUrl\ShortUrlResolver::class, Util\UrlValidator::class], Service\ShortUrlService::class => [
'em',
Service\ShortUrl\ShortUrlResolver::class,
Util\UrlValidator::class,
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class,
],
Visit\VisitLocator::class => ['em'], Visit\VisitLocator::class => ['em'],
Visit\VisitsStatsHelper::class => ['em'], Visit\VisitsStatsHelper::class => ['em'],
Tag\TagService::class => ['em'], Tag\TagService::class => ['em'],

View File

@ -138,8 +138,10 @@ class ShortUrl extends AbstractEntity
return $this; return $this;
} }
public function update(ShortUrlEdit $shortUrlEdit): void public function update(
{ ShortUrlEdit $shortUrlEdit,
?ShortUrlRelationResolverInterface $relationResolver = null
): void {
if ($shortUrlEdit->hasValidSince()) { if ($shortUrlEdit->hasValidSince()) {
$this->validSince = $shortUrlEdit->validSince(); $this->validSince = $shortUrlEdit->validSince();
} }
@ -152,6 +154,10 @@ class ShortUrl extends AbstractEntity
if ($shortUrlEdit->hasLongUrl()) { if ($shortUrlEdit->hasLongUrl()) {
$this->longUrl = $shortUrlEdit->longUrl(); $this->longUrl = $shortUrlEdit->longUrl();
} }
if ($shortUrlEdit->hasTags()) {
$relationResolver = $relationResolver ?? new SimpleShortUrlRelationResolver();
$this->tags = $relationResolver->resolveTags($shortUrlEdit->tags());
}
} }
/** /**

View File

@ -15,6 +15,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Paginator\Adapter\ShortUrlRepositoryAdapter; 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\Resolver\ShortUrlRelationResolverInterface;
use Shlinkio\Shlink\Core\Util\TagManagerTrait; use Shlinkio\Shlink\Core\Util\TagManagerTrait;
use Shlinkio\Shlink\Core\Util\UrlValidatorInterface; use Shlinkio\Shlink\Core\Util\UrlValidatorInterface;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@ -26,15 +27,18 @@ class ShortUrlService implements ShortUrlServiceInterface
private ORM\EntityManagerInterface $em; private ORM\EntityManagerInterface $em;
private ShortUrlResolverInterface $urlResolver; private ShortUrlResolverInterface $urlResolver;
private UrlValidatorInterface $urlValidator; private UrlValidatorInterface $urlValidator;
private ShortUrlRelationResolverInterface $relationResolver;
public function __construct( public function __construct(
ORM\EntityManagerInterface $em, ORM\EntityManagerInterface $em,
ShortUrlResolverInterface $urlResolver, ShortUrlResolverInterface $urlResolver,
UrlValidatorInterface $urlValidator UrlValidatorInterface $urlValidator,
ShortUrlRelationResolverInterface $relationResolver
) { ) {
$this->em = $em; $this->em = $em;
$this->urlResolver = $urlResolver; $this->urlResolver = $urlResolver;
$this->urlValidator = $urlValidator; $this->urlValidator = $urlValidator;
$this->relationResolver = $relationResolver;
} }
/** /**
@ -80,7 +84,7 @@ class ShortUrlService implements ShortUrlServiceInterface
} }
$shortUrl = $this->urlResolver->resolveShortUrl($identifier, $apiKey); $shortUrl = $this->urlResolver->resolveShortUrl($identifier, $apiKey);
$shortUrl->update($shortUrlEdit); $shortUrl->update($shortUrlEdit, $this->relationResolver);
$this->em->flush(); $this->em->flush();

View File

@ -19,6 +19,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
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\Service\ShortUrlService; use Shlinkio\Shlink\Core\Service\ShortUrlService;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver;
use Shlinkio\Shlink\Core\Util\UrlValidatorInterface; use Shlinkio\Shlink\Core\Util\UrlValidatorInterface;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
use ShlinkioTest\Shlink\Core\Util\ApiKeyHelpersTrait; use ShlinkioTest\Shlink\Core\Util\ApiKeyHelpersTrait;
@ -48,6 +49,7 @@ class ShortUrlServiceTest extends TestCase
$this->em->reveal(), $this->em->reveal(),
$this->urlResolver->reveal(), $this->urlResolver->reveal(),
$this->urlValidator->reveal(), $this->urlValidator->reveal(),
new SimpleShortUrlRelationResolver(),
); );
} }

View File

@ -52,6 +52,25 @@ class EditShortUrlTagsTest extends ApiTestCase
self::assertEquals($domain, $payload['domain'] ?? null); self::assertEquals($domain, $payload['domain'] ?? null);
} }
/** @test */
public function allowsEditingTagsWithTwoEndpoints(): void
{
$getUrlTagsFromApi = fn () => $this->getJsonResponsePayload(
$this->callApiWithKey(self::METHOD_GET, '/short-urls/abc123'),
)['tags'] ?? null;
self::assertEquals(['foo'], $getUrlTagsFromApi());
$this->callApiWithKey(self::METHOD_PUT, '/short-urls/abc123/tags', [RequestOptions::JSON => [
'tags' => ['a', 'e'],
]]);
self::assertEquals(['a', 'e'], $getUrlTagsFromApi());
$this->callApiWithKey(self::METHOD_PATCH, '/short-urls/abc123', [RequestOptions::JSON => [
'tags' => ['i', 'o', 'u'],
]]);
self::assertEquals(['i', 'o', 'u'], $getUrlTagsFromApi());
}
/** @test */ /** @test */
public function tagsAreSetOnProperShortUrlBasedOnProvidedDomain(): void public function tagsAreSetOnProperShortUrlBasedOnProvidedDomain(): void
{ {