Add StoredObjectToPdfConverter service and unit tests

Introduced the StoredObjectToPdfConverter service to handle conversion of stored objects to PDF format. Added unit tests to ensure proper functionality, including versioning and exception handling.
This commit is contained in:
Julien Fastré 2024-09-10 14:28:47 +02:00
parent 1ddd283f26
commit a60ea0e066
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
2 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,75 @@
<?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\Service;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Entity\StoredObjectPointInTime;
use Chill\DocStoreBundle\Entity\StoredObjectPointInTimeReasonEnum;
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
use Chill\WopiBundle\Service\WopiConverter;
use Symfony\Component\Mime\MimeTypesInterface;
/**
* Class StoredObjectToPdfConverter.
*
* Converts stored objects to PDF or other specified formats using WopiConverter.
*/
class StoredObjectToPdfConverter
{
public function __construct(
private readonly StoredObjectManagerInterface $storedObjectManager,
private readonly WopiConverter $wopiConverter,
private readonly MimeTypesInterface $mimeTypes,
) {}
/**
* Converts the given stored object to a specified format and stores the new version.
*
* @param StoredObject $storedObject the stored object to be converted
* @param string $lang the language for the conversion context
* @param string $convertTo The target format for the conversion. Default is 'pdf'.
*
* @return array{0: StoredObjectPointInTime, 1: StoredObjectVersion} contains the point in time before conversion and the new version of the stored object
*
* @throws \UnexpectedValueException if the preferred mime type for the conversion is not found
* @throws \RuntimeException if the conversion or storage of the new version fails
* @throws StoredObjectManagerException
*/
public function addConvertedVersion(StoredObject $storedObject, string $lang, $convertTo = 'pdf'): array
{
$newMimeType = $this->mimeTypes->getMimeTypes($convertTo)[0] ?? null;
if (null === $newMimeType) {
throw new \UnexpectedValueException(sprintf('could not find a preferred mime type for conversion to %s', $convertTo));
}
$currentVersion = $storedObject->getCurrentVersion();
if ($currentVersion->getType() === $newMimeType) {
throw new \UnexpectedValueException('Already at the same mime type');
}
$content = $this->storedObjectManager->read($currentVersion);
try {
$converted = $this->wopiConverter->convert($lang, $content, $newMimeType, $convertTo);
} catch (\RuntimeException $e) {
throw new \RuntimeException('could not store a new version for document', previous: $e);
}
$pointInTime = new StoredObjectPointInTime($currentVersion, StoredObjectPointInTimeReasonEnum::KEEP_BEFORE_CONVERSION);
$version = $this->storedObjectManager->write($storedObject, $converted, $newMimeType);
return [$pointInTime, $version];
}
}

View File

@ -0,0 +1,61 @@
<?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\Service;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Entity\StoredObjectPointInTime;
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\DocStoreBundle\Service\StoredObjectToPdfConverter;
use Chill\WopiBundle\Service\WopiConverter;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\Mime\MimeTypes;
/**
* @internal
*
* @coversNothing
*/
class StoredObjectToPdfConverterTest extends TestCase
{
use ProphecyTrait;
public function testAddConvertedVersion(): void
{
$storedObject = new StoredObject();
$currentVersion = $storedObject->registerVersion(type: 'text/html');
$storedObjectManager = $this->prophesize(StoredObjectManagerInterface::class);
$storedObjectManager->read($currentVersion)->willReturn('1234');
$storedObjectManager->write($storedObject, '5678', 'application/pdf')->shouldBeCalled()
->will(function ($args) {
/** @var StoredObject $storedObject */
$storedObject = $args[0];
return $storedObject->registerVersion(type: $args[2]);
});
$converter = $this->prophesize(WopiConverter::class);
$converter->convert('fr', '1234', 'application/pdf', 'pdf')->shouldBeCalled()
->willReturn('5678');
$converter = new StoredObjectToPdfConverter($storedObjectManager->reveal(), $converter->reveal(), MimeTypes::getDefault());
$actual = $converter->addConvertedVersion($storedObject, 'fr');
self::assertIsArray($actual);
self::assertInstanceOf(StoredObjectPointInTime::class, $actual[0]);
self::assertSame($currentVersion, $actual[0]->getObjectVersion());
self::assertInstanceOf(StoredObjectVersion::class, $actual[1]);
}
}