mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-25 18:30:23 -06:00
Replaced the use of EntityDoesNotExistException by ShorturlNotFoundException where applicable
This commit is contained in:
parent
310032e303
commit
0c5eec7e95
@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
|
||||
|
||||
use Shlinkio\Shlink\CLI\Util\ExitCodes;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
@ -66,9 +65,6 @@ class ResolveUrlCommand extends Command
|
||||
$output->writeln(sprintf('Long URL: <info>%s</info>', $url->getLongUrl()));
|
||||
return ExitCodes::EXIT_SUCCESS;
|
||||
} catch (ShortUrlNotFoundException $e) {
|
||||
$io->error(sprintf('Provided short code "%s" has an invalid format.', $shortCode));
|
||||
return ExitCodes::EXIT_FAILURE;
|
||||
} catch (EntityDoesNotExistException $e) {
|
||||
$io->error(sprintf('Provided short code "%s" could not be found.', $shortCode));
|
||||
return ExitCodes::EXIT_FAILURE;
|
||||
}
|
||||
|
@ -8,12 +8,13 @@ use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\CLI\Command\ShortUrl\ResolveUrlCommand;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
use const PHP_EOL;
|
||||
|
||||
class ResolveUrlCommandTest extends TestCase
|
||||
@ -51,23 +52,11 @@ class ResolveUrlCommandTest extends TestCase
|
||||
public function incorrectShortCodeOutputsErrorMessage(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, null)->willThrow(EntityDoesNotExistException::class)
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, null)->willThrow(ShortUrlNotFoundException::class)
|
||||
->shouldBeCalledOnce();
|
||||
|
||||
$this->commandTester->execute(['shortCode' => $shortCode]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Provided short code "' . $shortCode . '" could not be found.', $output);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function wrongShortCodeFormatOutputsErrorMessage(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, null)->willThrow(new ShortUrlNotFoundException())
|
||||
->shouldBeCalledOnce();
|
||||
|
||||
$this->commandTester->execute(['shortCode' => $shortCode]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
$this->assertStringContainsString('Provided short code "' . $shortCode . '" has an invalid format.', $output);
|
||||
$this->assertStringContainsString(sprintf('Provided short code "%s" could not be found', $shortCode), $output);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
use Shlinkio\Shlink\Core\Options\AppOptions;
|
||||
@ -72,7 +71,7 @@ abstract class AbstractTrackingAction implements MiddlewareInterface
|
||||
}
|
||||
|
||||
return $this->createSuccessResp($this->buildUrlToRedirectTo($url, $query, $disableTrackParam));
|
||||
} catch (ShortUrlNotFoundException | EntityDoesNotExistException $e) {
|
||||
} catch (ShortUrlNotFoundException $e) {
|
||||
$this->logger->warning('An error occurred while tracking short code. {e}', ['e' => $e]);
|
||||
return $this->createErrorResp($request, $handler);
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Shlinkio\Shlink\Common\Response\ResponseUtilsTrait;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Shlinkio\Shlink\PreviewGenerator\Exception\PreviewGenerationException;
|
||||
@ -56,7 +55,7 @@ class PreviewAction implements MiddlewareInterface
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
$imagePath = $this->previewGenerator->generatePreview($url->getLongUrl());
|
||||
return $this->generateImageResponse($imagePath);
|
||||
} catch (ShortUrlNotFoundException | EntityDoesNotExistException | PreviewGenerationException $e) {
|
||||
} catch (ShortUrlNotFoundException | PreviewGenerationException $e) {
|
||||
$this->logger->warning('An error occurred while generating preview image. {e}', ['e' => $e]);
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Zend\Expressive\Router\Exception\RuntimeException;
|
||||
@ -60,7 +59,7 @@ class QrCodeAction implements MiddlewareInterface
|
||||
|
||||
try {
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, $domain);
|
||||
} catch (ShortUrlNotFoundException | EntityDoesNotExistException $e) {
|
||||
} catch (ShortUrlNotFoundException $e) {
|
||||
$this->logger->warning('An error occurred while creating QR code. {e}', ['e' => $e]);
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
@ -19,11 +19,7 @@ class NonUniqueSlugException extends InvalidArgumentException implements Problem
|
||||
|
||||
public static function fromSlug(string $slug, ?string $domain): self
|
||||
{
|
||||
$suffix = '';
|
||||
if ($domain !== null) {
|
||||
$suffix = sprintf(' for domain "%s"', $domain);
|
||||
}
|
||||
|
||||
$suffix = $domain === null ? '' : sprintf(' for domain "%s"', $domain);
|
||||
$e = new self(sprintf('Provided slug "%s" is already in use%s.', $slug, $suffix));
|
||||
|
||||
$e->detail = $e->getMessage();
|
||||
|
@ -17,9 +17,10 @@ class ShortUrlNotFoundException extends DomainException implements ProblemDetail
|
||||
private const TITLE = 'Short URL not found';
|
||||
public const TYPE = 'INVALID_SHORTCODE';
|
||||
|
||||
public static function fromNotFoundShortCode(string $shortCode): self
|
||||
public static function fromNotFoundShortCode(string $shortCode, ?string $domain = null): self
|
||||
{
|
||||
$e = new self(sprintf('No URL found for short code "%s"', $shortCode));
|
||||
$suffix = $domain === null ? '' : sprintf(' for domain "%s"', $domain);
|
||||
$e = new self(sprintf('No URL found with short code "%s"%s', $shortCode, $suffix));
|
||||
|
||||
$e->detail = $e->getMessage();
|
||||
$e->title = self::TITLE;
|
||||
|
@ -8,9 +8,9 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\PersistenceDomainResolver;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
@ -129,7 +129,7 @@ class UrlShortener implements UrlShortenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws EntityDoesNotExistException
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
public function shortCodeToUrl(string $shortCode, ?string $domain = null): ShortUrl
|
||||
{
|
||||
@ -137,10 +137,7 @@ class UrlShortener implements UrlShortenerInterface
|
||||
$shortUrlRepo = $this->em->getRepository(ShortUrl::class);
|
||||
$shortUrl = $shortUrlRepo->findOneByShortCode($shortCode, $domain);
|
||||
if ($shortUrl === null) {
|
||||
throw EntityDoesNotExistException::createFromEntityAndConditions(ShortUrl::class, [
|
||||
'shortCode' => $shortCode,
|
||||
'domain' => $domain,
|
||||
]);
|
||||
throw ShortUrlNotFoundException::fromNotFoundShortCode($shortCode, $domain);
|
||||
}
|
||||
|
||||
return $shortUrl;
|
||||
|
@ -6,10 +6,9 @@ namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Exception\RuntimeException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
|
||||
interface UrlShortenerInterface
|
||||
@ -18,12 +17,11 @@ interface UrlShortenerInterface
|
||||
* @param string[] $tags
|
||||
* @throws NonUniqueSlugException
|
||||
* @throws InvalidUrlException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function urlToShortCode(UriInterface $url, array $tags, ShortUrlMeta $meta): ShortUrl;
|
||||
|
||||
/**
|
||||
* @throws EntityDoesNotExistException
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
public function shortCodeToUrl(string $shortCode, ?string $domain = null): ShortUrl;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Shlinkio\Shlink\Core\Action\PreviewAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Shlinkio\Shlink\PreviewGenerator\Service\PreviewGenerator;
|
||||
@ -38,19 +37,6 @@ class PreviewActionTest extends TestCase
|
||||
$this->action = new PreviewAction($this->previewGenerator->reveal(), $this->urlShortener->reveal());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function invalidShortCodeFallsBackToNextMiddleware(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willThrow(EntityDoesNotExistException::class)
|
||||
->shouldBeCalledOnce();
|
||||
$delegate = $this->prophesize(RequestHandlerInterface::class);
|
||||
$delegate->handle(Argument::cetera())->shouldBeCalledOnce()
|
||||
->willReturn(new Response());
|
||||
|
||||
$this->action->process((new ServerRequest())->withAttribute('shortCode', $shortCode), $delegate->reveal());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function correctShortCodeReturnsImageResponse(): void
|
||||
{
|
||||
|
@ -11,7 +11,6 @@ use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
|
||||
use Shlinkio\Shlink\Core\Action\QrCodeAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Zend\Diactoros\Response;
|
||||
@ -39,7 +38,7 @@ class QrCodeActionTest extends TestCase
|
||||
public function aNotFoundShortCodeWillDelegateIntoNextMiddleware(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, '')->willThrow(EntityDoesNotExistException::class)
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, '')->willThrow(ShortUrlNotFoundException::class)
|
||||
->shouldBeCalledOnce();
|
||||
$delegate = $this->prophesize(RequestHandlerInterface::class);
|
||||
$process = $delegate->handle(Argument::any())->willReturn(new Response());
|
||||
|
@ -10,7 +10,7 @@ use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Options;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Shlinkio\Shlink\Core\Service\VisitsTracker;
|
||||
@ -76,7 +76,7 @@ class RedirectActionTest extends TestCase
|
||||
public function nextMiddlewareIsInvokedIfLongUrlIsNotFound(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, '')->willThrow(EntityDoesNotExistException::class)
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, '')->willThrow(ShortUrlNotFoundException::class)
|
||||
->shouldBeCalledOnce();
|
||||
$this->visitTracker->track(Argument::cetera())->shouldNotBeCalled();
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Core\Exception;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
|
||||
class InvalidShortCodeExceptionTest extends TestCase
|
||||
{
|
||||
/** @test */
|
||||
public function properlyCreatesExceptionFromNotFoundShortCode(): void
|
||||
{
|
||||
$e = ShortUrlNotFoundException::fromNotFoundShortCode('abc123');
|
||||
|
||||
$this->assertEquals('No URL found for short code "abc123"', $e->getMessage());
|
||||
}
|
||||
}
|
38
module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php
Normal file
38
module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Core\Exception;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
|
||||
class ShortUrlNotFoundExceptionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider provideMessages
|
||||
*/
|
||||
public function properlyCreatesExceptionFromNotFoundShortCode(
|
||||
string $expectedMessage,
|
||||
string $shortCode,
|
||||
?string $domain
|
||||
): void {
|
||||
$e = ShortUrlNotFoundException::fromNotFoundShortCode($shortCode, $domain);
|
||||
$this->assertEquals($expectedMessage, $e->getMessage());
|
||||
}
|
||||
|
||||
public function provideMessages(): iterable
|
||||
{
|
||||
yield 'without domain' => [
|
||||
'No URL found with short code "abc123"',
|
||||
'abc123',
|
||||
null,
|
||||
];
|
||||
yield 'with domain' => [
|
||||
'No URL found with short code "bar" for domain "foo"',
|
||||
'bar',
|
||||
'foo',
|
||||
];
|
||||
}
|
||||
}
|
@ -8,15 +8,11 @@ use InvalidArgumentException;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
|
||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
class ResolveShortUrlAction extends AbstractRestAction
|
||||
{
|
||||
protected const ROUTE_PATH = '/short-urls/{shortCode}';
|
||||
@ -48,15 +44,7 @@ class ResolveShortUrlAction extends AbstractRestAction
|
||||
$domain = $request->getQueryParams()['domain'] ?? null;
|
||||
$transformer = new ShortUrlDataTransformer($this->domainConfig);
|
||||
|
||||
try {
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode, $domain);
|
||||
return new JsonResponse($transformer->transform($url));
|
||||
} catch (EntityDoesNotExistException $e) {
|
||||
$this->logger->warning('Provided short code couldn\'t be found. {e}', ['e' => $e]);
|
||||
return new JsonResponse([
|
||||
'error' => RestUtils::INVALID_ARGUMENT_ERROR, // FIXME Not correct. Use correct value on "type"
|
||||
'message' => sprintf('No URL found for short code "%s"', $shortCode),
|
||||
], self::STATUS_NOT_FOUND);
|
||||
}
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode, $domain);
|
||||
return new JsonResponse($transformer->transform($url));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ class ResolveShortUrlActionTest extends ApiTestCase
|
||||
['error' => $error] = $this->getJsonResponsePayload($resp);
|
||||
|
||||
$this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode());
|
||||
$this->assertEquals(RestUtils::INVALID_ARGUMENT_ERROR, $error);
|
||||
$this->assertEquals(RestUtils::INVALID_SHORTCODE_ERROR, $error);
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,8 @@ namespace ShlinkioTest\Shlink\Rest\Action\ShortUrl;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Shlinkio\Shlink\Rest\Action\ShortUrl\ResolveShortUrlAction;
|
||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||
use Zend\Diactoros\ServerRequest;
|
||||
|
||||
use function strpos;
|
||||
@ -28,19 +26,6 @@ class ResolveShortUrlActionTest extends TestCase
|
||||
$this->action = new ResolveShortUrlAction($this->urlShortener->reveal(), []);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function incorrectShortCodeReturnsError(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode, null)->willThrow(EntityDoesNotExistException::class)
|
||||
->shouldBeCalledOnce();
|
||||
|
||||
$request = (new ServerRequest())->withAttribute('shortCode', $shortCode);
|
||||
$response = $this->action->handle($request);
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_ARGUMENT_ERROR) > 0);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function correctShortCodeReturnsSuccess(): void
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user