Created middleware which injects default short code length from config when a value was not explicitly provided

This commit is contained in:
Alejandro Celaya 2020-02-18 19:21:34 +01:00
parent 9372d1739a
commit 343ee04acb
5 changed files with 98 additions and 1 deletions

View file

@ -243,6 +243,10 @@
"domain": {
"description": "The domain to which the short URL will be attached",
"type": "string"
},
"shortCodeLength": {
"description": "The length for generated short code. It has to be at least 4 and defaults to 5. It will be ignored when customSlug is provided",
"type": "number"
}
}
}

View file

@ -38,6 +38,7 @@ return [
Middleware\CrossDomainMiddleware::class => InvokableFactory::class,
Middleware\ShortUrl\CreateShortUrlContentNegotiationMiddleware::class => InvokableFactory::class,
Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class => ConfigAbstractFactory::class,
Middleware\ShortUrl\DefaultShortCodesLengthMiddleware::class => ConfigAbstractFactory::class,
],
],
@ -75,6 +76,9 @@ return [
Action\Tag\UpdateTagAction::class => [Service\Tag\TagService::class, LoggerInterface::class],
Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class => ['config.url_shortener.domain.hostname'],
Middleware\ShortUrl\DefaultShortCodesLengthMiddleware::class => [
'config.url_shortener.default_short_codes_length',
],
],
];

View file

@ -13,7 +13,11 @@ return [
Action\HealthAction::getRouteDef(),
// Short codes
Action\ShortUrl\CreateShortUrlAction::getRouteDef([$contentNegotiationMiddleware, $dropDomainMiddleware]),
Action\ShortUrl\CreateShortUrlAction::getRouteDef([
$contentNegotiationMiddleware,
$dropDomainMiddleware,
Middleware\ShortUrl\DefaultShortCodesLengthMiddleware::class,
]),
Action\ShortUrl\SingleStepCreateShortUrlAction::getRouteDef([$contentNegotiationMiddleware]),
Action\ShortUrl\EditShortUrlAction::getRouteDef([$dropDomainMiddleware]),
Action\ShortUrl\DeleteShortUrlAction::getRouteDef([$dropDomainMiddleware]),

View file

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Rest\Middleware\ShortUrl;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
class DefaultShortCodesLengthMiddleware implements MiddlewareInterface
{
private int $defaultShortCodesLength;
public function __construct(int $defaultShortCodesLength)
{
$this->defaultShortCodesLength = $defaultShortCodesLength;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$body = $request->getParsedBody();
if (! isset($body[ShortUrlMetaInputFilter::SHORT_CODE_LENGTH])) {
$body[ShortUrlMetaInputFilter::SHORT_CODE_LENGTH] = $this->defaultShortCodesLength;
}
return $handler->handle($request->withParsedBody($body));
}
}

View file

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace ShlinkioApiTest\Shlink\Rest\Middleware\ShortUrl;
use Laminas\Diactoros\Response;
use Laminas\Diactoros\ServerRequestFactory;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
use Shlinkio\Shlink\Rest\Middleware\ShortUrl\DefaultShortCodesLengthMiddleware;
class DefaultShortCodesLengthMiddlewareTest extends TestCase
{
private DefaultShortCodesLengthMiddleware $middleware;
private ObjectProphecy $handler;
public function setUp(): void
{
$this->handler = $this->prophesize(RequestHandlerInterface::class);
$this->middleware = new DefaultShortCodesLengthMiddleware(8);
}
/**
* @test
* @dataProvider provideBodies
*/
public function defaultValueIsInjectedInBodyWhenNotProvided(array $body, int $expectedLength): void
{
$request = ServerRequestFactory::fromGlobals()->withParsedBody($body);
$handle = $this->handler->handle(Argument::that(function (ServerRequestInterface $req) use ($expectedLength) {
$parsedBody = $req->getParsedBody();
Assert::assertArrayHasKey(ShortUrlMetaInputFilter::SHORT_CODE_LENGTH, $parsedBody);
Assert::assertEquals($expectedLength, $parsedBody[ShortUrlMetaInputFilter::SHORT_CODE_LENGTH]);
return $req;
}))->willReturn(new Response());
$this->middleware->process($request, $this->handler->reveal());
$handle->shouldHaveBeenCalledOnce();
}
public function provideBodies(): iterable
{
yield 'value provided' => [[ShortUrlMetaInputFilter::SHORT_CODE_LENGTH => 6], 6];
yield 'value not provided' => [[], 8];
}
}