Add Twig AsyncUploadExtension and its associated test

Created AsyncUploadExtension under Chill\DocStoreBundle\AsyncUpload\Templating to provide Twig filter functions for generating URLs for asynchronous file uploads. To ensure correctness, AsyncUploadExtensionTest was implemented in Bundle\ChillDocStoreBundle\Tests\AsyncUpload\Templating. Service definitions were also updated in services.yaml.
This commit is contained in:
Julien Fastré 2023-12-11 16:53:38 +01:00
parent 4fd5a37df3
commit 1195767eb3
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
3 changed files with 149 additions and 2 deletions

View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\DocStoreBundle\AsyncUpload\Templating;
use Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface;
use Chill\DocStoreBundle\Entity\StoredObject;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
/**
* This class extends the AbstractExtension class and provides Twig filter functions for generating URLs for asynchronous
* file uploads.
*/
class AsyncUploadExtension extends AbstractExtension
{
public function __construct(
private readonly TempUrlGeneratorInterface $tempUrlGenerator,
private readonly UrlGeneratorInterface $routingUrlGenerator
) {}
public function getFilters()
{
return [
new TwigFilter('file_url', $this->computeSignedUrl(...)),
new TwigFilter('generate_url', $this->computeGenerateUrl(...)),
];
}
public function computeSignedUrl(StoredObject|string $file, string $method = 'GET', int $expiresDelay = null): string
{
if ($file instanceof StoredObject) {
$object_name = $file->getFilename();
} else {
$object_name = $file;
}
return $this->tempUrlGenerator->generate($method, $object_name, $expiresDelay)->url;
}
public function computeGenerateUrl(StoredObject|string $file, string $method = 'GET', int $expiresDelay = null): string
{
if ($file instanceof StoredObject) {
$object_name = $file->getFilename();
} else {
$object_name = $file;
}
$args = [
'method' => $method,
'object_name' => $object_name,
];
if (null !== $expiresDelay) {
$args['expires_delay'] = $expiresDelay;
}
return $this->routingUrlGenerator->generate('async_upload.generate_url', $args);
}
}

View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace AsyncUpload\Templating;
use Chill\DocStoreBundle\AsyncUpload\SignedUrl;
use Chill\DocStoreBundle\AsyncUpload\Templating\AsyncUploadExtension;
use Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface;
use Chill\DocStoreBundle\Entity\StoredObject;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* @internal
*
* @coversNothing
*/
class AsyncUploadExtensionTest extends KernelTestCase
{
use ProphecyTrait;
private AsyncUploadExtension $asyncUploadExtension;
public function setUp(): void
{
$generator = $this->prophesize(TempUrlGeneratorInterface::class);
$generator->generate(Argument::in(['GET', 'POST']), Argument::type('string'), Argument::any())
->will(fn (array $args): SignedUrl => new SignedUrl($args[0], 'https://object.store.example/container/'.$args[1], new \DateTimeImmutable('1 hours')));
$urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
$urlGenerator->generate('async_upload.generate_url', Argument::type('array'))
->willReturn('url');
$this->asyncUploadExtension = new AsyncUploadExtension(
$generator->reveal(),
$urlGenerator->reveal()
);
}
/**
* @dataProvider dataProviderStoredObject
*/
public function testComputeSignedUrl(StoredObject|string $storedObject): void
{
$actual = $this->asyncUploadExtension->computeSignedUrl($storedObject);
self::assertStringContainsString('https://object.store.example/container', $actual);
self::assertStringContainsString(is_string($storedObject) ? $storedObject : $storedObject->getFilename(), $actual);
}
/**
* @dataProvider dataProviderStoredObject
*/
public function testComputeGenerateUrl(StoredObject|string $storedObject): void
{
$actual = $this->asyncUploadExtension->computeGenerateUrl($storedObject);
self::assertEquals('url', $actual);
}
public function dataProviderStoredObject(): iterable
{
yield [(new StoredObject())->setFilename('blabla')];
yield ['blabla'];
}
}

View File

@ -55,9 +55,10 @@ services:
resource: '../GenericDoc/Renderer/'
Chill\DocStoreBundle\AsyncUpload\Driver\:
autowire: true
autoconfigure: true
resource: '../AsyncUpload/Driver/'
Chill\DocStoreBundle\AsyncUpload\Templating\:
resource: '../AsyncUpload/Templating/'
Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface:
alias: Chill\DocStoreBundle\AsyncUpload\Driver\OpenstackObjectStore\TempUrlOpenstackGenerator