diff --git a/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php b/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php index 76414481..6a036c62 100644 --- a/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/DeleteShortUrlCommandTest.php @@ -83,7 +83,7 @@ class DeleteShortUrlCommandTest extends TestCase $ignoreThreshold = array_pop($args); if (!$ignoreThreshold) { - throw new Exception\DeleteShortUrlException(10); + throw Exception\DeleteShortUrlException::fromVisitsThreshold(10, ''); } } ); @@ -112,7 +112,7 @@ class DeleteShortUrlCommandTest extends TestCase { $shortCode = 'abc123'; $deleteByShortCode = $this->service->deleteByShortCode($shortCode, false)->willThrow( - new Exception\DeleteShortUrlException(10) + Exception\DeleteShortUrlException::fromVisitsThreshold(10, '') ); $this->commandTester->setInputs(['no']); diff --git a/module/Core/src/Exception/DeleteShortUrlException.php b/module/Core/src/Exception/DeleteShortUrlException.php index 984c2cbc..ddd77418 100644 --- a/module/Core/src/Exception/DeleteShortUrlException.php +++ b/module/Core/src/Exception/DeleteShortUrlException.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Exception; use Fig\Http\Message\StatusCodeInterface; -use Throwable; use Zend\ProblemDetails\Exception\CommonProblemDetailsExceptionTrait; use Zend\ProblemDetails\Exception\ProblemDetailsExceptionInterface; @@ -18,18 +17,9 @@ class DeleteShortUrlException extends DomainException implements ProblemDetailsE private const TITLE = 'Cannot delete short URL'; private const TYPE = 'INVALID_SHORTCODE_DELETION'; // FIXME Should be INVALID_SHORT_URL_DELETION - /** @var int */ - private $visitsThreshold; - - public function __construct(int $visitsThreshold, string $message = '', int $code = 0, ?Throwable $previous = null) - { - $this->visitsThreshold = $visitsThreshold; - parent::__construct($message, $code, $previous); - } - public static function fromVisitsThreshold(int $threshold, string $shortCode): self { - $e = new self($threshold, sprintf( + $e = new self(sprintf( 'Impossible to delete short URL with short code "%s" since it has more than "%s" visits.', $shortCode, $threshold @@ -39,13 +29,16 @@ class DeleteShortUrlException extends DomainException implements ProblemDetailsE $e->title = self::TITLE; $e->type = self::TYPE; $e->status = StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY; - $e->additional = ['threshold' => $threshold]; + $e->additional = [ + 'shortCode' => $shortCode, + 'threshold' => $threshold, + ]; return $e; } public function getVisitsThreshold(): int { - return $this->visitsThreshold; + return $this->additional['threshold']; } } diff --git a/module/Core/src/Exception/InvalidUrlException.php b/module/Core/src/Exception/InvalidUrlException.php index 0b741910..ffec94df 100644 --- a/module/Core/src/Exception/InvalidUrlException.php +++ b/module/Core/src/Exception/InvalidUrlException.php @@ -27,6 +27,7 @@ class InvalidUrlException extends DomainException implements ProblemDetailsExcep $e->title = self::TITLE; $e->type = self::TYPE; $e->status = $status; + $e->additional = ['url' => $url]; return $e; } diff --git a/module/Core/src/Exception/NonUniqueSlugException.php b/module/Core/src/Exception/NonUniqueSlugException.php index 9ef7365d..bcd40268 100644 --- a/module/Core/src/Exception/NonUniqueSlugException.php +++ b/module/Core/src/Exception/NonUniqueSlugException.php @@ -26,6 +26,11 @@ class NonUniqueSlugException extends InvalidArgumentException implements Problem $e->title = self::TITLE; $e->type = self::TYPE; $e->status = StatusCodeInterface::STATUS_BAD_REQUEST; + $e->additional = ['customSlug' => $slug]; + + if ($domain !== null) { + $e->additional['domain'] = $domain; + } return $e; } diff --git a/module/Core/src/Exception/ShortUrlNotFoundException.php b/module/Core/src/Exception/ShortUrlNotFoundException.php index 9617a486..aca1bce9 100644 --- a/module/Core/src/Exception/ShortUrlNotFoundException.php +++ b/module/Core/src/Exception/ShortUrlNotFoundException.php @@ -26,6 +26,11 @@ class ShortUrlNotFoundException extends DomainException implements ProblemDetail $e->title = self::TITLE; $e->type = self::TYPE; $e->status = StatusCodeInterface::STATUS_NOT_FOUND; + $e->additional = ['shortCode' => $shortCode]; + + if ($domain !== null) { + $e->additional['domain'] = $domain; + } return $e; } diff --git a/module/Core/src/Exception/TagNotFoundException.php b/module/Core/src/Exception/TagNotFoundException.php index 33cf1345..1924e89a 100644 --- a/module/Core/src/Exception/TagNotFoundException.php +++ b/module/Core/src/Exception/TagNotFoundException.php @@ -25,6 +25,7 @@ class TagNotFoundException extends DomainException implements ProblemDetailsExce $e->title = self::TITLE; $e->type = self::TYPE; $e->status = StatusCodeInterface::STATUS_NOT_FOUND; + $e->additional = ['tag' => $tag]; return $e; } diff --git a/module/Core/src/Exception/ValidationException.php b/module/Core/src/Exception/ValidationException.php index c4ff2354..f3a5c515 100644 --- a/module/Core/src/Exception/ValidationException.php +++ b/module/Core/src/Exception/ValidationException.php @@ -24,19 +24,6 @@ class ValidationException extends InvalidArgumentException implements ProblemDet private const TITLE = 'Invalid data'; private const TYPE = 'INVALID_ARGUMENT'; - /** @var array */ - private $invalidElements; - - public function __construct( - string $message = '', - array $invalidElements = [], - int $code = 0, - ?Throwable $previous = null - ) { - $this->invalidElements = $invalidElements; - parent::__construct($message, $code, $previous); - } - public static function fromInputFilter(InputFilterInterface $inputFilter, ?Throwable $prev = null): self { return static::fromArray($inputFilter->getMessages(), $prev); @@ -45,22 +32,20 @@ class ValidationException extends InvalidArgumentException implements ProblemDet public static function fromArray(array $invalidData, ?Throwable $prev = null): self { $status = StatusCodeInterface::STATUS_BAD_REQUEST; - $e = new self('Provided data is not valid', $invalidData, $status, $prev); + $e = new self('Provided data is not valid', $status, $prev); $e->detail = $e->getMessage(); $e->title = self::TITLE; $e->type = self::TYPE; $e->status = StatusCodeInterface::STATUS_BAD_REQUEST; - $e->additional = [ - 'invalidElements' => $invalidData, - ]; + $e->additional = ['invalidElements' => $invalidData]; return $e; } public function getInvalidElements(): array { - return $this->invalidElements; + return $this->additional['invalidElements']; } public function __toString(): string @@ -80,7 +65,7 @@ class ValidationException extends InvalidArgumentException implements ProblemDet private function invalidElementsToString(): string { - return reduce_left($this->invalidElements, function ($messageSet, string $name, $_, string $acc) { + return reduce_left($this->getInvalidElements(), function ($messageSet, string $name, $_, string $acc) { return $acc . sprintf( "\n '%s' => %s", $name, diff --git a/module/Core/test/Exception/DeleteShortUrlExceptionTest.php b/module/Core/test/Exception/DeleteShortUrlExceptionTest.php index 4b132eea..0e2012a2 100644 --- a/module/Core/test/Exception/DeleteShortUrlExceptionTest.php +++ b/module/Core/test/Exception/DeleteShortUrlExceptionTest.php @@ -5,17 +5,15 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\Exception; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Common\Util\StringUtilsTrait; use Shlinkio\Shlink\Core\Exception\DeleteShortUrlException; use function Functional\map; use function range; +use function Shlinkio\Shlink\Core\generateRandomShortCode; use function sprintf; class DeleteShortUrlExceptionTest extends TestCase { - use StringUtilsTrait; - /** * @test * @dataProvider provideThresholds @@ -29,29 +27,12 @@ class DeleteShortUrlExceptionTest extends TestCase $this->assertEquals($threshold, $e->getVisitsThreshold()); $this->assertEquals($expectedMessage, $e->getMessage()); - $this->assertEquals(0, $e->getCode()); - $this->assertNull($e->getPrevious()); - } - - /** - * @test - * @dataProvider provideThresholds - */ - public function visitsThresholdIsProperlyReturned(int $threshold): void - { - $e = new DeleteShortUrlException($threshold); - - $this->assertEquals($threshold, $e->getVisitsThreshold()); - $this->assertEquals('', $e->getMessage()); - $this->assertEquals(0, $e->getCode()); - $this->assertNull($e->getPrevious()); } public function provideThresholds(): array { return map(range(5, 50, 5), function (int $number) { - $shortCode = $this->generateRandomString(6); - return [$number, $shortCode, sprintf( + return [$number, $shortCode = generateRandomShortCode(6), sprintf( 'Impossible to delete short URL with short code "%s" since it has more than "%s" visits.', $shortCode, $number diff --git a/module/Core/test/Exception/ValidationExceptionTest.php b/module/Core/test/Exception/ValidationExceptionTest.php index eb47caed..069506b5 100644 --- a/module/Core/test/Exception/ValidationExceptionTest.php +++ b/module/Core/test/Exception/ValidationExceptionTest.php @@ -13,38 +13,9 @@ use Throwable; use Zend\InputFilter\InputFilterInterface; use function print_r; -use function random_int; class ValidationExceptionTest extends TestCase { - /** - * @test - * @dataProvider provideExceptionData - */ - public function createsExceptionWrappingExpectedData( - array $args, - string $expectedMessage, - array $expectedInvalidElements, - int $expectedCode, - ?Throwable $expectedPrev - ): void { - $e = new ValidationException(...$args); - - $this->assertEquals($expectedMessage, $e->getMessage()); - $this->assertEquals($expectedInvalidElements, $e->getInvalidElements()); - $this->assertEquals($expectedCode, $e->getCode()); - $this->assertEquals($expectedPrev, $e->getPrevious()); - } - - public function provideExceptionData(): iterable - { - yield 'empty args' => [[], '', [], 0, null]; - yield 'with message' => [['something'], 'something', [], 0, null]; - yield 'with elements' => [['something_else', [1, 2, 3]], 'something_else', [1, 2, 3], 0, null]; - yield 'with code' => [['foo', [], $foo = random_int(-100, 100)], 'foo', [], $foo, null]; - yield 'with prev' => [['bar', [], 8, $e = new RuntimeException()], 'bar', [], 8, $e]; - } - /** * @test * @dataProvider provideExceptions