mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-22 15:13:59 -06:00
Converted NonUniqueSlugException into a problem details exception
This commit is contained in:
parent
0d7d53ab5b
commit
c1eee2246b
@ -4,10 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Exception;
|
||||
|
||||
use Fig\Http\Message\StatusCodeInterface;
|
||||
use Zend\ProblemDetails\Exception\CommonProblemDetailsExceptionTrait;
|
||||
use Zend\ProblemDetails\Exception\ProblemDetailsExceptionInterface;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
class NonUniqueSlugException extends InvalidArgumentException
|
||||
class NonUniqueSlugException extends InvalidArgumentException implements ProblemDetailsExceptionInterface
|
||||
{
|
||||
use CommonProblemDetailsExceptionTrait;
|
||||
|
||||
private const TITLE = 'Invalid custom slug';
|
||||
public const TYPE = 'INVALID_SLUG';
|
||||
|
||||
public static function fromSlug(string $slug, ?string $domain): self
|
||||
{
|
||||
$suffix = '';
|
||||
@ -15,6 +24,13 @@ class NonUniqueSlugException extends InvalidArgumentException
|
||||
$suffix = sprintf(' for domain "%s"', $domain);
|
||||
}
|
||||
|
||||
return new self(sprintf('Provided slug "%s" is not unique%s.', $slug, $suffix));
|
||||
$e = new self(sprintf('Provided slug "%s" is already in use%s.', $slug, $suffix));
|
||||
|
||||
$e->detail = $e->getMessage();
|
||||
$e->title = self::TITLE;
|
||||
$e->type = self::TYPE;
|
||||
$e->status = StatusCodeInterface::STATUS_BAD_REQUEST;
|
||||
|
||||
return $e;
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,12 @@ class NonUniqueSlugExceptionTest extends TestCase
|
||||
public function provideMessages(): iterable
|
||||
{
|
||||
yield 'without domain' => [
|
||||
'Provided slug "foo" is not unique.',
|
||||
'Provided slug "foo" is already in use.',
|
||||
'foo',
|
||||
null,
|
||||
];
|
||||
yield 'with domain' => [
|
||||
'Provided slug "baz" is not unique for domain "bar".',
|
||||
'Provided slug "baz" is already in use for domain "bar".',
|
||||
'baz',
|
||||
'bar',
|
||||
];
|
||||
|
@ -7,7 +7,6 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||
use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
@ -16,8 +15,6 @@ use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
abstract class AbstractCreateShortUrlAction extends AbstractRestAction
|
||||
{
|
||||
/** @var UrlShortenerInterface */
|
||||
@ -52,21 +49,13 @@ abstract class AbstractCreateShortUrlAction extends AbstractRestAction
|
||||
}
|
||||
|
||||
$longUrl = $shortUrlData->getLongUrl();
|
||||
$tags = $shortUrlData->getTags();
|
||||
$shortUrlMeta = $shortUrlData->getMeta();
|
||||
|
||||
try {
|
||||
$shortUrl = $this->urlShortener->urlToShortCode($longUrl, $shortUrlData->getTags(), $shortUrlMeta);
|
||||
$transformer = new ShortUrlDataTransformer($this->domainConfig);
|
||||
$shortUrl = $this->urlShortener->urlToShortCode($longUrl, $tags, $shortUrlMeta);
|
||||
$transformer = new ShortUrlDataTransformer($this->domainConfig);
|
||||
|
||||
return new JsonResponse($transformer->transform($shortUrl));
|
||||
} catch (NonUniqueSlugException $e) {
|
||||
$customSlug = $shortUrlMeta->getCustomSlug();
|
||||
$this->logger->warning('Provided non-unique slug. {e}', ['e' => $e]);
|
||||
return new JsonResponse([
|
||||
'error' => RestUtils::getRestErrorCodeFromException($e),
|
||||
'message' => sprintf('Provided slug %s is already in use. Try with a different one.', $customSlug),
|
||||
], self::STATUS_BAD_REQUEST);
|
||||
}
|
||||
return new JsonResponse($transformer->transform($shortUrl));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,8 @@ class RestUtils
|
||||
/** @deprecated */
|
||||
public const INVALID_URL_ERROR = Core\InvalidUrlException::TYPE;
|
||||
public const INVALID_ARGUMENT_ERROR = 'INVALID_ARGUMENT';
|
||||
public const INVALID_SLUG_ERROR = 'INVALID_SLUG';
|
||||
/** @deprecated */
|
||||
public const INVALID_SLUG_ERROR = Core\NonUniqueSlugException::TYPE;
|
||||
public const INVALID_CREDENTIALS_ERROR = 'INVALID_CREDENTIALS';
|
||||
public const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN';
|
||||
public const INVALID_AUTHORIZATION_ERROR = 'INVALID_AUTHORIZATION';
|
||||
|
@ -8,8 +8,6 @@ use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction;
|
||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||
@ -88,23 +86,4 @@ class CreateShortUrlActionTest extends TestCase
|
||||
yield ['127.0.0.1'];
|
||||
yield ['???/&%$&'];
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function nonUniqueSlugReturnsError(): void
|
||||
{
|
||||
$this->urlShortener->urlToShortCode(
|
||||
Argument::type(Uri::class),
|
||||
Argument::type('array'),
|
||||
ShortUrlMeta::createFromRawData(['customSlug' => 'foo']),
|
||||
Argument::cetera()
|
||||
)->willThrow(NonUniqueSlugException::class)->shouldBeCalledOnce();
|
||||
|
||||
$request = (new ServerRequest())->withParsedBody([
|
||||
'longUrl' => 'http://www.domain.com/foo/bar',
|
||||
'customSlug' => 'foo',
|
||||
]);
|
||||
$response = $this->action->handle($request);
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
$this->assertStringContainsString(RestUtils::INVALID_SLUG_ERROR, (string) $response->getBody());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user