mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-23 07:33:58 -06:00
Merge pull request #629 from acelaya-forks/feature/reset-meta
Feature/reset meta
This commit is contained in:
commit
f71bd84a20
@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
|
||||
#### Fixed
|
||||
|
||||
* [#624](https://github.com/shlinkio/shlink/issues/624) Fixed order in which headers for remote IP detection are inspected.
|
||||
* [#623](https://github.com/shlinkio/shlink/issues/623) Fixed short URLs metadata being impossible to reset.
|
||||
|
||||
|
||||
## 2.0.2 - 2020-01-12
|
||||
|
@ -58,6 +58,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"devster/ubench": "^2.0",
|
||||
"dms/phpunit-arraysubset-asserts": "^0.1.0",
|
||||
"eaglewu/swoole-ide-helper": "dev-master",
|
||||
"infection/infection": "^0.15.0",
|
||||
"phpstan/phpstan": "^0.12.3",
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Shlink Docker image
|
||||
|
||||
[![Docker build status](https://img.shields.io/docker/cloud/build/shlinkio/shlink.svg?style=flat-square)](https://hub.docker.com/r/shlinkio/shlink/)
|
||||
[![Docker build status](https://img.shields.io/docker/build/shlinkio/shlink.svg?style=flat-square)](https://hub.docker.com/r/shlinkio/shlink/)
|
||||
[![Docker pulls](https://img.shields.io/docker/pulls/shlinkio/shlink.svg?style=flat-square)](https://hub.docker.com/r/shlinkio/shlink/)
|
||||
|
||||
This image provides an easy way to set up [shlink](https://shlink.io) on a container-based runtime.
|
||||
|
@ -10,6 +10,7 @@ use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@ -121,14 +122,14 @@ class GenerateShortUrlCommand extends Command
|
||||
$shortUrl = $this->urlShortener->urlToShortCode(
|
||||
new Uri($longUrl),
|
||||
$tags,
|
||||
ShortUrlMeta::createFromParams(
|
||||
$input->getOption('validSince'),
|
||||
$input->getOption('validUntil'),
|
||||
$customSlug,
|
||||
$maxVisits !== null ? (int) $maxVisits : null,
|
||||
$input->getOption('findIfExists'),
|
||||
$input->getOption('domain'),
|
||||
),
|
||||
ShortUrlMeta::fromRawData([
|
||||
ShortUrlMetaInputFilter::VALID_SINCE => $input->getOption('validSince'),
|
||||
ShortUrlMetaInputFilter::VALID_UNTIL => $input->getOption('validUntil'),
|
||||
ShortUrlMetaInputFilter::CUSTOM_SLUG => $customSlug,
|
||||
ShortUrlMetaInputFilter::MAX_VISITS => $maxVisits !== null ? (int) $maxVisits : null,
|
||||
ShortUrlMetaInputFilter::FIND_IF_EXISTS => $input->getOption('findIfExists'),
|
||||
ShortUrlMetaInputFilter::DOMAIN => $input->getOption('domain'),
|
||||
]),
|
||||
);
|
||||
|
||||
$io->writeln([
|
||||
|
@ -9,11 +9,16 @@ use DateTimeInterface;
|
||||
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
final class ShortUrlMeta
|
||||
{
|
||||
private bool $validSincePropWasProvided = false;
|
||||
private ?Chronos $validSince = null;
|
||||
private bool $validUntilPropWasProvided = false;
|
||||
private ?Chronos $validUntil = null;
|
||||
private ?string $customSlug = null;
|
||||
private bool $maxVisitsPropWasProvided = false;
|
||||
private ?int $maxVisits = null;
|
||||
private ?bool $findIfExists = null;
|
||||
private ?string $domain = null;
|
||||
@ -32,44 +37,13 @@ final class ShortUrlMeta
|
||||
* @param array $data
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public static function createFromRawData(array $data): self
|
||||
public static function fromRawData(array $data): self
|
||||
{
|
||||
$instance = new self();
|
||||
$instance->validate($data);
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|Chronos|null $validSince
|
||||
* @param string|Chronos|null $validUntil
|
||||
* @param string|null $customSlug
|
||||
* @param int|null $maxVisits
|
||||
* @param bool|null $findIfExists
|
||||
* @param string|null $domain
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public static function createFromParams( // phpcs:ignore
|
||||
$validSince = null,
|
||||
$validUntil = null,
|
||||
$customSlug = null,
|
||||
$maxVisits = null,
|
||||
$findIfExists = null,
|
||||
$domain = null
|
||||
): self {
|
||||
// We do not type hint the arguments because that will be done by the validation process and we would get a
|
||||
// type error if any of them do not match
|
||||
$instance = new self();
|
||||
$instance->validate([
|
||||
ShortUrlMetaInputFilter::VALID_SINCE => $validSince,
|
||||
ShortUrlMetaInputFilter::VALID_UNTIL => $validUntil,
|
||||
ShortUrlMetaInputFilter::CUSTOM_SLUG => $customSlug,
|
||||
ShortUrlMetaInputFilter::MAX_VISITS => $maxVisits,
|
||||
ShortUrlMetaInputFilter::FIND_IF_EXISTS => $findIfExists,
|
||||
ShortUrlMetaInputFilter::DOMAIN => $domain,
|
||||
]);
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws ValidationException
|
||||
@ -82,10 +56,13 @@ final class ShortUrlMeta
|
||||
}
|
||||
|
||||
$this->validSince = $this->parseDateField($inputFilter->getValue(ShortUrlMetaInputFilter::VALID_SINCE));
|
||||
$this->validSincePropWasProvided = array_key_exists(ShortUrlMetaInputFilter::VALID_SINCE, $data);
|
||||
$this->validUntil = $this->parseDateField($inputFilter->getValue(ShortUrlMetaInputFilter::VALID_UNTIL));
|
||||
$this->validUntilPropWasProvided = array_key_exists(ShortUrlMetaInputFilter::VALID_UNTIL, $data);
|
||||
$this->customSlug = $inputFilter->getValue(ShortUrlMetaInputFilter::CUSTOM_SLUG);
|
||||
$maxVisits = $inputFilter->getValue(ShortUrlMetaInputFilter::MAX_VISITS);
|
||||
$this->maxVisits = $maxVisits !== null ? (int) $maxVisits : null;
|
||||
$this->maxVisitsPropWasProvided = array_key_exists(ShortUrlMetaInputFilter::MAX_VISITS, $data);
|
||||
$this->findIfExists = $inputFilter->getValue(ShortUrlMetaInputFilter::FIND_IF_EXISTS);
|
||||
$this->domain = $inputFilter->getValue(ShortUrlMetaInputFilter::DOMAIN);
|
||||
}
|
||||
@ -113,7 +90,7 @@ final class ShortUrlMeta
|
||||
|
||||
public function hasValidSince(): bool
|
||||
{
|
||||
return $this->validSince !== null;
|
||||
return $this->validSincePropWasProvided;
|
||||
}
|
||||
|
||||
public function getValidUntil(): ?Chronos
|
||||
@ -123,7 +100,7 @@ final class ShortUrlMeta
|
||||
|
||||
public function hasValidUntil(): bool
|
||||
{
|
||||
return $this->validUntil !== null;
|
||||
return $this->validUntilPropWasProvided;
|
||||
}
|
||||
|
||||
public function getCustomSlug(): ?string
|
||||
@ -143,7 +120,7 @@ final class ShortUrlMeta
|
||||
|
||||
public function hasMaxVisits(): bool
|
||||
{
|
||||
return $this->maxVisits !== null;
|
||||
return $this->maxVisitsPropWasProvided;
|
||||
}
|
||||
|
||||
public function findIfExists(): bool
|
||||
|
@ -38,22 +38,20 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
/** @test */
|
||||
public function findOneByShortCodeReturnsProperData(): void
|
||||
{
|
||||
$regularOne = new ShortUrl('foo', ShortUrlMeta::createFromParams(null, null, 'foo'));
|
||||
$regularOne = new ShortUrl('foo', ShortUrlMeta::fromRawData(['customSlug' => 'foo']));
|
||||
$this->getEntityManager()->persist($regularOne);
|
||||
|
||||
$notYetValid = new ShortUrl(
|
||||
'bar',
|
||||
ShortUrlMeta::createFromParams(Chronos::now()->addMonth(), null, 'bar_very_long_text'),
|
||||
);
|
||||
$notYetValid = new ShortUrl('bar', ShortUrlMeta::fromRawData(
|
||||
['validSince' => Chronos::now()->addMonth(), 'customSlug' => 'bar_very_long_text'],
|
||||
));
|
||||
$this->getEntityManager()->persist($notYetValid);
|
||||
|
||||
$expired = new ShortUrl('expired', ShortUrlMeta::createFromParams(null, Chronos::now()->subMonth(), 'expired'));
|
||||
$expired = new ShortUrl('expired', ShortUrlMeta::fromRawData(
|
||||
['validUntil' => Chronos::now()->subMonth(), 'customSlug' => 'expired'],
|
||||
));
|
||||
$this->getEntityManager()->persist($expired);
|
||||
|
||||
$allVisitsComplete = new ShortUrl('baz', ShortUrlMeta::createFromRawData([
|
||||
'maxVisits' => 3,
|
||||
'customSlug' => 'baz',
|
||||
]));
|
||||
$allVisitsComplete = new ShortUrl('baz', ShortUrlMeta::fromRawData(['maxVisits' => 3, 'customSlug' => 'baz']));
|
||||
$visits = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$visit = new Visit($allVisitsComplete, Visitor::emptyInstance());
|
||||
@ -63,16 +61,14 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
$allVisitsComplete->setVisits(new ArrayCollection($visits));
|
||||
$this->getEntityManager()->persist($allVisitsComplete);
|
||||
|
||||
$withDomain = new ShortUrl('foo', ShortUrlMeta::createFromRawData([
|
||||
'domain' => 'example.com',
|
||||
'customSlug' => 'domain-short-code',
|
||||
]));
|
||||
$withDomain = new ShortUrl('foo', ShortUrlMeta::fromRawData(
|
||||
['domain' => 'example.com', 'customSlug' => 'domain-short-code'],
|
||||
));
|
||||
$this->getEntityManager()->persist($withDomain);
|
||||
|
||||
$withDomainDuplicatingRegular = new ShortUrl('foo_with_domain', ShortUrlMeta::createFromRawData([
|
||||
'domain' => 'doma.in',
|
||||
'customSlug' => 'foo',
|
||||
]));
|
||||
$withDomainDuplicatingRegular = new ShortUrl('foo_with_domain', ShortUrlMeta::fromRawData(
|
||||
['domain' => 'doma.in', 'customSlug' => 'foo'],
|
||||
));
|
||||
$this->getEntityManager()->persist($withDomainDuplicatingRegular);
|
||||
|
||||
$this->getEntityManager()->flush();
|
||||
@ -187,12 +183,12 @@ class ShortUrlRepositoryTest extends DatabaseTestCase
|
||||
/** @test */
|
||||
public function shortCodeIsInUseLooksForShortUrlInProperSetOfTables(): void
|
||||
{
|
||||
$shortUrlWithoutDomain = new ShortUrl('foo', ShortUrlMeta::createFromRawData(['customSlug' => 'my-cool-slug']));
|
||||
$shortUrlWithoutDomain = new ShortUrl('foo', ShortUrlMeta::fromRawData(['customSlug' => 'my-cool-slug']));
|
||||
$this->getEntityManager()->persist($shortUrlWithoutDomain);
|
||||
|
||||
$shortUrlWithDomain = new ShortUrl(
|
||||
'foo',
|
||||
ShortUrlMeta::createFromRawData(['domain' => 'doma.in', 'customSlug' => 'another-slug']),
|
||||
ShortUrlMeta::fromRawData(['domain' => 'doma.in', 'customSlug' => 'another-slug']),
|
||||
);
|
||||
$this->getEntityManager()->persist($shortUrlWithDomain);
|
||||
|
||||
|
@ -28,7 +28,7 @@ class ShortUrlTest extends TestCase
|
||||
public function provideInvalidShortUrls(): iterable
|
||||
{
|
||||
yield 'with custom slug' => [
|
||||
new ShortUrl('', ShortUrlMeta::createFromRawData(['customSlug' => 'custom-slug'])),
|
||||
new ShortUrl('', ShortUrlMeta::fromRawData(['customSlug' => 'custom-slug'])),
|
||||
'The short code cannot be regenerated on ShortUrls where a custom slug was provided.',
|
||||
];
|
||||
yield 'already persisted' => [
|
||||
|
@ -21,7 +21,7 @@ class ShortUrlMetaTest extends TestCase
|
||||
public function exceptionIsThrownIfProvidedDataIsInvalid(array $data): void
|
||||
{
|
||||
$this->expectException(ValidationException::class);
|
||||
ShortUrlMeta::createFromRawData($data);
|
||||
ShortUrlMeta::fromRawData($data);
|
||||
}
|
||||
|
||||
public function provideInvalidData(): iterable
|
||||
@ -49,7 +49,9 @@ class ShortUrlMetaTest extends TestCase
|
||||
/** @test */
|
||||
public function properlyCreatedInstanceReturnsValues(): void
|
||||
{
|
||||
$meta = ShortUrlMeta::createFromParams(Chronos::parse('2015-01-01')->toAtomString(), null, 'foobar');
|
||||
$meta = ShortUrlMeta::fromRawData(
|
||||
['validSince' => Chronos::parse('2015-01-01')->toAtomString(), 'customSlug' => 'foobar'],
|
||||
);
|
||||
|
||||
$this->assertTrue($meta->hasValidSince());
|
||||
$this->assertEquals(Chronos::parse('2015-01-01'), $meta->getValidSince());
|
||||
|
@ -93,12 +93,11 @@ class ShortUrlServiceTest extends TestCase
|
||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
$flush = $this->em->flush()->willReturn(null);
|
||||
|
||||
$result = $this->service->updateMetadataByShortCode('abc123', ShortUrlMeta::createFromParams(
|
||||
Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
|
||||
Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
|
||||
null,
|
||||
5,
|
||||
));
|
||||
$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,
|
||||
]));
|
||||
|
||||
$this->assertSame($shortUrl, $result);
|
||||
$this->assertEquals(Chronos::parse('2017-01-01 00:00:00'), $shortUrl->getValidSince());
|
||||
|
@ -153,7 +153,7 @@ class UrlShortenerTest extends TestCase
|
||||
$this->urlShortener->urlToShortCode(
|
||||
new Uri('http://foobar.com/12345/hello?foo=bar'),
|
||||
[],
|
||||
ShortUrlMeta::createFromRawData(['customSlug' => 'custom-slug']),
|
||||
ShortUrlMeta::fromRawData(['customSlug' => 'custom-slug']),
|
||||
);
|
||||
}
|
||||
|
||||
@ -183,49 +183,49 @@ class UrlShortenerTest extends TestCase
|
||||
{
|
||||
$url = 'http://foo.com';
|
||||
|
||||
yield [$url, [], ShortUrlMeta::createFromRawData(['findIfExists' => true]), new ShortUrl($url)];
|
||||
yield [$url, [], ShortUrlMeta::createFromRawData(
|
||||
yield [$url, [], ShortUrlMeta::fromRawData(['findIfExists' => true]), new ShortUrl($url)];
|
||||
yield [$url, [], ShortUrlMeta::fromRawData(
|
||||
['findIfExists' => true, 'customSlug' => 'foo'],
|
||||
), new ShortUrl($url)];
|
||||
yield [
|
||||
$url,
|
||||
['foo', 'bar'],
|
||||
ShortUrlMeta::createFromRawData(['findIfExists' => true]),
|
||||
ShortUrlMeta::fromRawData(['findIfExists' => true]),
|
||||
(new ShortUrl($url))->setTags(new ArrayCollection([new Tag('bar'), new Tag('foo')])),
|
||||
];
|
||||
yield [
|
||||
$url,
|
||||
[],
|
||||
ShortUrlMeta::createFromRawData(['findIfExists' => true, 'maxVisits' => 3]),
|
||||
new ShortUrl($url, ShortUrlMeta::createFromRawData(['maxVisits' => 3])),
|
||||
ShortUrlMeta::fromRawData(['findIfExists' => true, 'maxVisits' => 3]),
|
||||
new ShortUrl($url, ShortUrlMeta::fromRawData(['maxVisits' => 3])),
|
||||
];
|
||||
yield [
|
||||
$url,
|
||||
[],
|
||||
ShortUrlMeta::createFromRawData(['findIfExists' => true, 'validSince' => Chronos::parse('2017-01-01')]),
|
||||
new ShortUrl($url, ShortUrlMeta::createFromRawData(['validSince' => Chronos::parse('2017-01-01')])),
|
||||
ShortUrlMeta::fromRawData(['findIfExists' => true, 'validSince' => Chronos::parse('2017-01-01')]),
|
||||
new ShortUrl($url, ShortUrlMeta::fromRawData(['validSince' => Chronos::parse('2017-01-01')])),
|
||||
];
|
||||
yield [
|
||||
$url,
|
||||
[],
|
||||
ShortUrlMeta::createFromRawData(['findIfExists' => true, 'validUntil' => Chronos::parse('2017-01-01')]),
|
||||
new ShortUrl($url, ShortUrlMeta::createFromRawData(['validUntil' => Chronos::parse('2017-01-01')])),
|
||||
ShortUrlMeta::fromRawData(['findIfExists' => true, 'validUntil' => Chronos::parse('2017-01-01')]),
|
||||
new ShortUrl($url, ShortUrlMeta::fromRawData(['validUntil' => Chronos::parse('2017-01-01')])),
|
||||
];
|
||||
yield [
|
||||
$url,
|
||||
[],
|
||||
ShortUrlMeta::createFromRawData(['findIfExists' => true, 'domain' => 'example.com']),
|
||||
new ShortUrl($url, ShortUrlMeta::createFromRawData(['domain' => 'example.com'])),
|
||||
ShortUrlMeta::fromRawData(['findIfExists' => true, 'domain' => 'example.com']),
|
||||
new ShortUrl($url, ShortUrlMeta::fromRawData(['domain' => 'example.com'])),
|
||||
];
|
||||
yield [
|
||||
$url,
|
||||
['baz', 'foo', 'bar'],
|
||||
ShortUrlMeta::createFromRawData([
|
||||
ShortUrlMeta::fromRawData([
|
||||
'findIfExists' => true,
|
||||
'validUntil' => Chronos::parse('2017-01-01'),
|
||||
'maxVisits' => 4,
|
||||
]),
|
||||
(new ShortUrl($url, ShortUrlMeta::createFromRawData([
|
||||
(new ShortUrl($url, ShortUrlMeta::fromRawData([
|
||||
'validUntil' => Chronos::parse('2017-01-01'),
|
||||
'maxVisits' => 4,
|
||||
])))->setTags(new ArrayCollection([new Tag('foo'), new Tag('bar'), new Tag('baz')])),
|
||||
@ -237,7 +237,7 @@ class UrlShortenerTest extends TestCase
|
||||
{
|
||||
$url = 'http://foo.com';
|
||||
$tags = ['baz', 'foo', 'bar'];
|
||||
$meta = ShortUrlMeta::createFromRawData([
|
||||
$meta = ShortUrlMeta::fromRawData([
|
||||
'findIfExists' => true,
|
||||
'validUntil' => Chronos::parse('2017-01-01'),
|
||||
'maxVisits' => 4,
|
||||
|
@ -42,13 +42,13 @@ class ShortUrlDataTransformerTest extends TestCase
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
]];
|
||||
yield 'max visits only' => [new ShortUrl('', ShortUrlMeta::createFromParams(null, null, null, $maxVisits)), [
|
||||
yield 'max visits only' => [new ShortUrl('', ShortUrlMeta::fromRawData(['maxVisits' => $maxVisits])), [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => $maxVisits,
|
||||
]];
|
||||
yield 'max visits and valid since' => [
|
||||
new ShortUrl('', ShortUrlMeta::createFromParams($now, null, null, $maxVisits)),
|
||||
new ShortUrl('', ShortUrlMeta::fromRawData(['validSince' => $now, 'maxVisits' => $maxVisits])),
|
||||
[
|
||||
'validSince' => $now->toAtomString(),
|
||||
'validUntil' => null,
|
||||
@ -56,7 +56,9 @@ class ShortUrlDataTransformerTest extends TestCase
|
||||
],
|
||||
];
|
||||
yield 'both dates' => [
|
||||
new ShortUrl('', ShortUrlMeta::createFromParams($now, $now->subDays(10))),
|
||||
new ShortUrl('', ShortUrlMeta::fromRawData(
|
||||
['validSince' => $now, 'validUntil' => $now->subDays(10)],
|
||||
)),
|
||||
[
|
||||
'validSince' => $now->toAtomString(),
|
||||
'validUntil' => $now->subDays(10)->toAtomString(),
|
||||
@ -64,7 +66,9 @@ class ShortUrlDataTransformerTest extends TestCase
|
||||
],
|
||||
];
|
||||
yield 'everything' => [
|
||||
new ShortUrl('', ShortUrlMeta::createFromParams($now, $now->subDays(5), null, $maxVisits)),
|
||||
new ShortUrl('', ShortUrlMeta::fromRawData(
|
||||
['validSince' => $now, 'validUntil' => $now->subDays(5), 'maxVisits' => $maxVisits],
|
||||
)),
|
||||
[
|
||||
'validSince' => $now->toAtomString(),
|
||||
'validUntil' => $now->subDays(5)->toAtomString(),
|
||||
|
@ -27,15 +27,7 @@ class CreateShortUrlAction extends AbstractCreateShortUrlAction
|
||||
]);
|
||||
}
|
||||
|
||||
$meta = ShortUrlMeta::createFromParams(
|
||||
$postData['validSince'] ?? null,
|
||||
$postData['validUntil'] ?? null,
|
||||
$postData['customSlug'] ?? null,
|
||||
$postData['maxVisits'] ?? null,
|
||||
$postData['findIfExists'] ?? null,
|
||||
$postData['domain'] ?? null,
|
||||
);
|
||||
|
||||
$meta = ShortUrlMeta::fromRawData($postData);
|
||||
return new CreateShortUrlData(new Uri($postData['longUrl']), (array) ($postData['tags'] ?? []), $meta);
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class EditShortUrlAction extends AbstractRestAction
|
||||
$postData = (array) $request->getParsedBody();
|
||||
$shortCode = $request->getAttribute('shortCode', '');
|
||||
|
||||
$this->shortUrlService->updateMetadataByShortCode($shortCode, ShortUrlMeta::createFromRawData($postData));
|
||||
$this->shortUrlService->updateMetadataByShortCode($shortCode, ShortUrlMeta::fromRawData($postData));
|
||||
return new EmptyResponse();
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,73 @@ declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioApiTest\Shlink\Rest\Action;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
|
||||
|
||||
use function Functional\first;
|
||||
use function sprintf;
|
||||
|
||||
class EditShortUrlActionTest extends ApiTestCase
|
||||
{
|
||||
use ArraySubsetAsserts;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider provideDisablingMeta
|
||||
*/
|
||||
public function metadataCanBeReset(array $meta): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$url = sprintf('/short-urls/%s', $shortCode);
|
||||
$resetMeta = [
|
||||
'validSince' => null,
|
||||
'validUntil' => null,
|
||||
'maxVisits' => null,
|
||||
];
|
||||
|
||||
// Setting meta that disables the URL should not let it be visited
|
||||
$editWithProvidedMeta = $this->callApiWithKey(self::METHOD_PATCH, $url, [RequestOptions::JSON => $meta]);
|
||||
$metaAfterEditing = $this->findShortUrlMetaByShortCode($shortCode);
|
||||
|
||||
// Resetting all meta should allow the URL to be visitable again
|
||||
$editWithResetMeta = $this->callApiWithKey(self::METHOD_PATCH, $url, [
|
||||
RequestOptions::JSON => $resetMeta,
|
||||
]);
|
||||
$metaAfterResetting = $this->findShortUrlMetaByShortCode($shortCode);
|
||||
|
||||
$this->assertEquals(self::STATUS_NO_CONTENT, $editWithProvidedMeta->getStatusCode());
|
||||
$this->assertEquals(self::STATUS_NO_CONTENT, $editWithResetMeta->getStatusCode());
|
||||
$this->assertEquals($resetMeta, $metaAfterResetting);
|
||||
self::assertArraySubset($meta, $metaAfterEditing);
|
||||
}
|
||||
|
||||
public function provideDisablingMeta(): iterable
|
||||
{
|
||||
$now = Chronos::now();
|
||||
|
||||
yield [['validSince' => $now->addMonth()->toAtomString()]];
|
||||
yield [['validUntil' => $now->subMonth()->toAtomString()]];
|
||||
yield [['maxVisits' => 20]];
|
||||
yield [['validUntil' => $now->addYear()->toAtomString(), 'maxVisits' => 100]];
|
||||
yield [[
|
||||
'validSince' => $now->subYear()->toAtomString(),
|
||||
'validUntil' => $now->addYear()->toAtomString(),
|
||||
'maxVisits' => 100,
|
||||
]];
|
||||
}
|
||||
|
||||
private function findShortUrlMetaByShortCode(string $shortCode): ?array
|
||||
{
|
||||
// FIXME Call GET /short-urls/{shortCode} once issue https://github.com/shlinkio/shlink/issues/628 is fixed
|
||||
$allShortUrls = $this->getJsonResponsePayload($this->callApiWithKey(self::METHOD_GET, '/short-urls'));
|
||||
$list = $allShortUrls['shortUrls']['data'] ?? [];
|
||||
$matchingShortUrl = first($list, fn (array $shortUrl) => $shortUrl['shortCode'] ?? '' === $shortCode);
|
||||
|
||||
return $matchingShortUrl['meta'] ?? null;
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function tryingToEditInvalidUrlReturnsNotFoundError(): void
|
||||
{
|
||||
|
@ -20,32 +20,32 @@ 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::fromRawData(['customSlug' => 'abc123'])),
|
||||
'2018-05-01',
|
||||
);
|
||||
$manager->persist($abcShortUrl);
|
||||
|
||||
$defShortUrl = $this->setShortUrlDate(new ShortUrl(
|
||||
'https://blog.alejandrocelaya.com/2017/12/09/acmailer-7-0-the-most-important-release-in-a-long-time/',
|
||||
ShortUrlMeta::createFromParams(Chronos::parse('2020-05-01'), null, 'def456'),
|
||||
ShortUrlMeta::fromRawData(['validSince' => Chronos::parse('2020-05-01'), 'customSlug' => 'def456']),
|
||||
), '2019-01-01 00:00:10');
|
||||
$manager->persist($defShortUrl);
|
||||
|
||||
$customShortUrl = $this->setShortUrlDate(new ShortUrl(
|
||||
'https://shlink.io',
|
||||
ShortUrlMeta::createFromParams(null, null, 'custom', 2),
|
||||
ShortUrlMeta::fromRawData(['customSlug' => 'custom', 'maxVisits' => 2]),
|
||||
), '2019-01-01 00:00:20');
|
||||
$manager->persist($customShortUrl);
|
||||
|
||||
$withDomainShortUrl = $this->setShortUrlDate(new ShortUrl(
|
||||
'https://blog.alejandrocelaya.com/2019/04/27/considerations-to-properly-use-open-source-software-projects/',
|
||||
ShortUrlMeta::createFromRawData(['domain' => 'example.com', 'customSlug' => 'ghi789']),
|
||||
ShortUrlMeta::fromRawData(['domain' => 'example.com', 'customSlug' => 'ghi789']),
|
||||
), '2019-01-01 00:00:30');
|
||||
$manager->persist($withDomainShortUrl);
|
||||
|
||||
$withDomainAndSlugShortUrl = $this->setShortUrlDate(new ShortUrl(
|
||||
'https://google.com',
|
||||
ShortUrlMeta::createFromRawData(['domain' => 'some-domain.com', 'customSlug' => 'custom-with-domain']),
|
||||
ShortUrlMeta::fromRawData(['domain' => 'some-domain.com', 'customSlug' => 'custom-with-domain']),
|
||||
), '2018-10-20');
|
||||
$manager->persist($withDomainAndSlugShortUrl);
|
||||
|
||||
|
@ -76,7 +76,7 @@ class CreateShortUrlActionTest extends TestCase
|
||||
];
|
||||
|
||||
yield [['longUrl' => 'http://www.domain.com/foo/bar'], ShortUrlMeta::createEmpty()];
|
||||
yield [$fullMeta, ShortUrlMeta::createFromRawData($fullMeta)];
|
||||
yield [$fullMeta, ShortUrlMeta::fromRawData($fullMeta)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user