mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Merge pull request #387 from acelaya/feature/fix-check-exists
Feature/fix check exists
This commit is contained in:
commit
20c3bde036
11
CHANGELOG.md
11
CHANGELOG.md
@ -4,16 +4,17 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
|
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
## [Unreleased]
|
## 1.16.3 - 2019-03-30
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
|
||||||
* [#153](https://github.com/shlinkio/shlink/issues/153) Updated to [doctrine/migrations](https://github.com/doctrine/migrations) version 2.0.0
|
* *Nothing*
|
||||||
* [#376](https://github.com/shlinkio/shlink/issues/376) Allowed `visit:update-db` command to not return an error exit code even if download fails, by passing the `-i` flag.
|
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
|
||||||
* *Nothing*
|
* [#153](https://github.com/shlinkio/shlink/issues/153) Updated to [doctrine/migrations](https://github.com/doctrine/migrations) version 2.0.0
|
||||||
|
* [#376](https://github.com/shlinkio/shlink/issues/376) Allowed `visit:update-db` command to not return an error exit code even if download fails, by passing the `-i` flag.
|
||||||
|
* [#341](https://github.com/shlinkio/shlink/issues/341) Improved database tests so that they are executed against all supported database engines.
|
||||||
|
|
||||||
#### Deprecated
|
#### Deprecated
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
|
|||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
|
||||||
* *Nothing*
|
* [#382](https://github.com/shlinkio/shlink/issues/382) Fixed existing short URLs not properly checked when providing the `findIfExists` flag.
|
||||||
|
|
||||||
|
|
||||||
## 1.16.2 - 2019-03-05
|
## 1.16.2 - 2019-03-05
|
||||||
|
@ -112,32 +112,39 @@ class UrlShortener implements UrlShortenerInterface
|
|||||||
if ($meta->hasCustomSlug()) {
|
if ($meta->hasCustomSlug()) {
|
||||||
$criteria['shortCode'] = $meta->getCustomSlug();
|
$criteria['shortCode'] = $meta->getCustomSlug();
|
||||||
}
|
}
|
||||||
/** @var ShortUrl|null $shortUrl */
|
/** @var ShortUrl[] $shortUrls */
|
||||||
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy($criteria);
|
$shortUrls = $this->em->getRepository(ShortUrl::class)->findBy($criteria);
|
||||||
if ($shortUrl === null) {
|
if (empty($shortUrls)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($meta->hasMaxVisits() && $meta->getMaxVisits() !== $shortUrl->getMaxVisits()) {
|
// Iterate short URLs until one that matches is found, or return null otherwise
|
||||||
return null;
|
return array_reduce($shortUrls, function (?ShortUrl $found, ShortUrl $shortUrl) use ($tags, $meta) {
|
||||||
}
|
if ($found) {
|
||||||
if ($meta->hasValidSince() && ! $meta->getValidSince()->eq($shortUrl->getValidSince())) {
|
return $found;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
if ($meta->hasValidUntil() && ! $meta->getValidUntil()->eq($shortUrl->getValidUntil())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$shortUrlTags = invoke($shortUrl->getTags(), '__toString');
|
if ($meta->hasMaxVisits() && $meta->getMaxVisits() !== $shortUrl->getMaxVisits()) {
|
||||||
$hasAllTags = count($shortUrlTags) === count($tags) && array_reduce(
|
return null;
|
||||||
$tags,
|
}
|
||||||
function (bool $hasAllTags, string $tag) use ($shortUrlTags) {
|
if ($meta->hasValidSince() && ! $meta->getValidSince()->eq($shortUrl->getValidSince())) {
|
||||||
return $hasAllTags && contains($shortUrlTags, $tag);
|
return null;
|
||||||
},
|
}
|
||||||
true
|
if ($meta->hasValidUntil() && ! $meta->getValidUntil()->eq($shortUrl->getValidUntil())) {
|
||||||
);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $hasAllTags ? $shortUrl : null;
|
$shortUrlTags = invoke($shortUrl->getTags(), '__toString');
|
||||||
|
$hasAllTags = count($shortUrlTags) === count($tags) && array_reduce(
|
||||||
|
$tags,
|
||||||
|
function (bool $hasAllTags, string $tag) use ($shortUrlTags) {
|
||||||
|
return $hasAllTags && contains($shortUrlTags, $tag);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
return $hasAllTags ? $shortUrl : null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkUrlExists(string $url): void
|
private function checkUrlExists(string $url): void
|
||||||
|
@ -27,6 +27,8 @@ use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
|||||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||||
use Zend\Diactoros\Uri;
|
use Zend\Diactoros\Uri;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
|
|
||||||
class UrlShortenerTest extends TestCase
|
class UrlShortenerTest extends TestCase
|
||||||
{
|
{
|
||||||
/** @var UrlShortener */
|
/** @var UrlShortener */
|
||||||
@ -121,7 +123,7 @@ class UrlShortenerTest extends TestCase
|
|||||||
{
|
{
|
||||||
$repo = $this->prophesize(ShortUrlRepository::class);
|
$repo = $this->prophesize(ShortUrlRepository::class);
|
||||||
$countBySlug = $repo->count(['shortCode' => 'custom-slug'])->willReturn(1);
|
$countBySlug = $repo->count(['shortCode' => 'custom-slug'])->willReturn(1);
|
||||||
$repo->findOneBy(Argument::cetera())->willReturn(null);
|
$repo->findBy(Argument::cetera())->willReturn([]);
|
||||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||||
|
|
||||||
$countBySlug->shouldBeCalledOnce();
|
$countBySlug->shouldBeCalledOnce();
|
||||||
@ -146,20 +148,23 @@ class UrlShortenerTest extends TestCase
|
|||||||
?ShortUrl $expected
|
?ShortUrl $expected
|
||||||
): void {
|
): void {
|
||||||
$repo = $this->prophesize(ShortUrlRepository::class);
|
$repo = $this->prophesize(ShortUrlRepository::class);
|
||||||
$findExisting = $repo->findOneBy(Argument::any())->willReturn($expected);
|
$findExisting = $repo->findBy(Argument::any())->willReturn($expected !== null ? [$expected] : []);
|
||||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||||
|
|
||||||
$result = $this->urlShortener->urlToShortCode(new Uri($url), $tags, $meta);
|
$result = $this->urlShortener->urlToShortCode(new Uri($url), $tags, $meta);
|
||||||
|
|
||||||
$this->assertSame($expected, $result);
|
|
||||||
$findExisting->shouldHaveBeenCalledOnce();
|
$findExisting->shouldHaveBeenCalledOnce();
|
||||||
$getRepo->shouldHaveBeenCalledOnce();
|
$getRepo->shouldHaveBeenCalledOnce();
|
||||||
|
if ($expected) {
|
||||||
|
$this->assertSame($expected, $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideExistingShortUrls(): iterable
|
public function provideExistingShortUrls(): iterable
|
||||||
{
|
{
|
||||||
$url = 'http://foo.com';
|
$url = 'http://foo.com';
|
||||||
|
|
||||||
|
yield [$url, [], ShortUrlMeta::createFromRawData(['findIfExists' => true]), null];
|
||||||
yield [$url, [], ShortUrlMeta::createFromRawData(['findIfExists' => true]), new ShortUrl($url)];
|
yield [$url, [], ShortUrlMeta::createFromRawData(['findIfExists' => true]), new ShortUrl($url)];
|
||||||
yield [$url, [], ShortUrlMeta::createFromRawData(
|
yield [$url, [], ShortUrlMeta::createFromRawData(
|
||||||
['findIfExists' => true, 'customSlug' => 'foo']
|
['findIfExists' => true, 'customSlug' => 'foo']
|
||||||
@ -203,6 +208,37 @@ class UrlShortenerTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function properExistingShortUrlIsReturnedWhenMultipleMatch(): void
|
||||||
|
{
|
||||||
|
$url = 'http://foo.com';
|
||||||
|
$tags = ['baz', 'foo', 'bar'];
|
||||||
|
$meta = ShortUrlMeta::createFromRawData([
|
||||||
|
'findIfExists' => true,
|
||||||
|
'validUntil' => Chronos::parse('2017-01-01'),
|
||||||
|
'maxVisits' => 4,
|
||||||
|
]);
|
||||||
|
$tagsCollection = new ArrayCollection(array_map(function (string $tag) {
|
||||||
|
return new Tag($tag);
|
||||||
|
}, $tags));
|
||||||
|
$expected = (new ShortUrl($url, $meta))->setTags($tagsCollection);
|
||||||
|
|
||||||
|
$repo = $this->prophesize(ShortUrlRepository::class);
|
||||||
|
$findExisting = $repo->findBy(Argument::any())->willReturn([
|
||||||
|
new ShortUrl($url),
|
||||||
|
new ShortUrl($url, $meta),
|
||||||
|
$expected,
|
||||||
|
(new ShortUrl($url))->setTags($tagsCollection),
|
||||||
|
]);
|
||||||
|
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||||
|
|
||||||
|
$result = $this->urlShortener->urlToShortCode(new Uri($url), $tags, $meta);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $result);
|
||||||
|
$findExisting->shouldHaveBeenCalledOnce();
|
||||||
|
$getRepo->shouldHaveBeenCalledOnce();
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function shortCodeIsProperlyParsed(): void
|
public function shortCodeIsProperlyParsed(): void
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user