mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-02 13:03:50 +00:00
234 lines
8.4 KiB
PHP
234 lines
8.4 KiB
PHP
<?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\Tests\Controller;
|
|
|
|
use Chill\DocStoreBundle\AsyncUpload\SignedUrl;
|
|
use Chill\DocStoreBundle\AsyncUpload\SignedUrlPost;
|
|
use Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface;
|
|
use Chill\DocStoreBundle\Controller\AsyncUploadController;
|
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
|
use Chill\MainBundle\Entity\User;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Prophecy\Argument;
|
|
use Prophecy\PhpUnit\ProphecyTrait;
|
|
use Psr\Log\NullLogger;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
use Symfony\Component\Security\Core\Security;
|
|
use Symfony\Component\Serializer\SerializerInterface;
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* @coversNothing
|
|
*/
|
|
class AsyncUploadControllerTest extends TestCase
|
|
{
|
|
use ProphecyTrait;
|
|
|
|
public function testGetSignedUrlPost(): void
|
|
{
|
|
$storedObject = new StoredObject();
|
|
$security = $this->prophesize(Security::class);
|
|
$security->isGranted('SEE_AND_EDIT', $storedObject)->willReturn(true)->shouldBeCalled();
|
|
|
|
$controller = new AsyncUploadController(
|
|
$this->buildTempUrlGenerator(),
|
|
$this->buildSerializer(),
|
|
$security->reveal(),
|
|
new NullLogger(),
|
|
);
|
|
|
|
$actual = $controller->getSignedUrlPost(new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800]), $storedObject);
|
|
|
|
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
|
|
|
self::assertArrayHasKey('method', $decodedActual);
|
|
self::assertEquals('POST', $decodedActual['method']);
|
|
}
|
|
|
|
public function testGetSignedUrlGetSimpleScenarioHappy(): void
|
|
{
|
|
$storedObject = new StoredObject();
|
|
$storedObject->registerVersion();
|
|
$security = $this->prophesize(Security::class);
|
|
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
|
$security->getUser()->willReturn(new User());
|
|
|
|
$controller = new AsyncUploadController(
|
|
$this->buildTempUrlGenerator(),
|
|
$this->buildSerializer(),
|
|
$security->reveal(),
|
|
new NullLogger(),
|
|
);
|
|
|
|
$actual = $controller->getSignedUrlGet(new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800]), $storedObject, 'get');
|
|
|
|
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
|
|
|
self::assertArrayHasKey('method', $decodedActual);
|
|
self::assertEquals('GET', $decodedActual['method']);
|
|
}
|
|
|
|
public function testGetSignedUrlGetSimpleScenarioNotAuthorized(): void
|
|
{
|
|
$this->expectException(AccessDeniedHttpException::class);
|
|
|
|
$storedObject = new StoredObject();
|
|
$storedObject->registerVersion();
|
|
$security = $this->prophesize(Security::class);
|
|
$security->isGranted('SEE', $storedObject)->willReturn(false)->shouldBeCalled();
|
|
|
|
$controller = new AsyncUploadController(
|
|
$this->buildTempUrlGenerator(),
|
|
$this->buildSerializer(),
|
|
$security->reveal(),
|
|
new NullLogger(),
|
|
);
|
|
|
|
$controller->getSignedUrlGet(new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800]), $storedObject, 'get');
|
|
}
|
|
|
|
public function testGetSignedUrlGetForSpecificVersionOfTheStoredObjectStoredInDatabase(): void
|
|
{
|
|
$storedObject = new StoredObject();
|
|
$version = $storedObject->registerVersion();
|
|
// we add a version to be sure that the we do not get the last one
|
|
$storedObject->registerVersion();
|
|
|
|
$security = $this->prophesize(Security::class);
|
|
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
|
$security->getUser()->willReturn(new User());
|
|
|
|
$controller = new AsyncUploadController(
|
|
$this->buildTempUrlGenerator(),
|
|
$this->buildSerializer(),
|
|
$security->reveal(),
|
|
new NullLogger(),
|
|
);
|
|
|
|
$actual = $controller->getSignedUrlGet(
|
|
new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800, 'version' => $version->getFilename()]),
|
|
$storedObject,
|
|
'get'
|
|
);
|
|
|
|
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
|
|
|
self::assertArrayHasKey('method', $decodedActual);
|
|
self::assertEquals('GET', $decodedActual['method']);
|
|
self::assertArrayHasKey('object_name', $decodedActual);
|
|
self::assertEquals($version->getFilename(), $decodedActual['object_name']);
|
|
}
|
|
|
|
public function testGetSignedUrlGetForSpecificVersionOfTheStoredObjectNotYetStoredInDatabase(): void
|
|
{
|
|
$storedObject = new StoredObject();
|
|
$storedObject->registerVersion();
|
|
// we generate a valid name
|
|
$version = $storedObject->getPrefix().'/some-version';
|
|
|
|
$security = $this->prophesize(Security::class);
|
|
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
|
$security->getUser()->willReturn(new User());
|
|
|
|
$controller = new AsyncUploadController(
|
|
$this->buildTempUrlGenerator(),
|
|
$this->buildSerializer(),
|
|
$security->reveal(),
|
|
new NullLogger(),
|
|
);
|
|
|
|
$actual = $controller->getSignedUrlGet(
|
|
new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800, 'version' => $version]),
|
|
$storedObject,
|
|
'get'
|
|
);
|
|
|
|
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
|
|
|
self::assertArrayHasKey('method', $decodedActual);
|
|
self::assertEquals('GET', $decodedActual['method']);
|
|
self::assertArrayHasKey('object_name', $decodedActual);
|
|
self::assertEquals($version, $decodedActual['object_name']);
|
|
}
|
|
|
|
public function testGetSignedUrlGetForSpecificVersionNotBelongingToTheStoreObject(): void
|
|
{
|
|
$this->expectException(AccessDeniedHttpException::class);
|
|
|
|
$storedObject = new StoredObject();
|
|
$storedObject->registerVersion();
|
|
// we generate a random version
|
|
$version = 'something/else';
|
|
|
|
$security = $this->prophesize(Security::class);
|
|
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
|
|
|
$controller = new AsyncUploadController(
|
|
$this->buildTempUrlGenerator(),
|
|
$this->buildSerializer(),
|
|
$security->reveal(),
|
|
new NullLogger(),
|
|
);
|
|
|
|
$controller->getSignedUrlGet(
|
|
new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800, 'version' => $version]),
|
|
$storedObject,
|
|
'get'
|
|
);
|
|
}
|
|
|
|
public function buildTempUrlGenerator(): TempUrlGeneratorInterface
|
|
{
|
|
return new class () implements TempUrlGeneratorInterface {
|
|
public function generatePost(?int $expire_delay = null, ?int $submit_delay = null, int $max_file_count = 1, ?string $object_name = null): SignedUrlPost
|
|
{
|
|
return new SignedUrlPost(
|
|
'https://object.store.example',
|
|
new \DateTimeImmutable('1 hour'),
|
|
$object_name ?? 'abc',
|
|
150,
|
|
1,
|
|
1800,
|
|
'',
|
|
'abc',
|
|
'abc'
|
|
);
|
|
}
|
|
|
|
public function generate(string $method, string $object_name, ?int $expire_delay = null): SignedUrl
|
|
{
|
|
return new SignedUrl(
|
|
strtoupper($method),
|
|
'https://object.store.example',
|
|
new \DateTimeImmutable('1 hour'),
|
|
$object_name
|
|
);
|
|
}
|
|
};
|
|
}
|
|
|
|
private function buildSerializer(): SerializerInterface
|
|
{
|
|
$serializer = $this->prophesize(SerializerInterface::class);
|
|
$serializer->serialize(Argument::type(SignedUrl::class), 'json', Argument::type('array'))
|
|
->will(fn (array $args): string => json_encode(
|
|
['method' => $args[0]->method, 'object_name' => $args[0]->object_name],
|
|
JSON_THROW_ON_ERROR,
|
|
3
|
|
));
|
|
|
|
return $serializer->reveal();
|
|
}
|
|
}
|