mirror of
https://github.com/danog/Valinor.git
synced 2024-12-12 09:09:38 +01:00
6ce1a439ad
/!\ This change fixes a security issue. Userland exception thrown in a constructor will not be automatically caught by the mapper anymore. This prevents messages with sensible information from reaching the final user — for instance an SQL exception showing a part of a query. To allow exceptions to be considered as safe, the new method `MapperBuilder::filterExceptions()` must be used, with caution. ```php final class SomeClass { public function __construct(private string $value) { \Webmozart\Assert\Assert::startsWith($value, 'foo_'); } } try { (new \CuyZ\Valinor\MapperBuilder()) ->filterExceptions(function (Throwable $exception) { if ($exception instanceof \Webmozart\Assert\InvalidArgumentException) { return \CuyZ\Valinor\Mapper\Tree\Message\ThrowableMessage::from($exception); } // If the exception should not be caught by this library, it // must be thrown again. throw $exception; }) ->mapper() ->map(SomeClass::class, 'bar_baz'); } catch (\CuyZ\Valinor\Mapper\MappingError $exception) { // Should print something similar to: // > Expected a value to start with "foo_". Got: "bar_baz" echo $exception->node()->messages()[0]; } ```
54 lines
1.8 KiB
PHP
54 lines
1.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace CuyZ\Valinor\Tests\Unit;
|
|
|
|
use CuyZ\Valinor\MapperBuilder;
|
|
use CuyZ\Valinor\Tests\Fake\Mapper\Tree\Message\FakeErrorMessage;
|
|
use DateTime;
|
|
use DateTimeInterface;
|
|
use PHPUnit\Framework\TestCase;
|
|
use stdClass;
|
|
|
|
use function sys_get_temp_dir;
|
|
|
|
final class MapperBuilderTest extends TestCase
|
|
{
|
|
private MapperBuilder $mapperBuilder;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->mapperBuilder = new MapperBuilder();
|
|
}
|
|
|
|
public function test_builder_methods_return_clone_of_builder_instance(): void
|
|
{
|
|
$builderA = $this->mapperBuilder;
|
|
$builderB = $builderA->infer(DateTimeInterface::class, static fn () => DateTime::class);
|
|
$builderC = $builderA->bind(static fn (): DateTime => new DateTime());
|
|
$builderD = $builderA->registerConstructor(static fn (): stdClass => new stdClass());
|
|
$builderE = $builderA->alter(static fn (string $value): string => 'foo');
|
|
$builderF = $builderA->flexible();
|
|
$builderG = $builderA->filterExceptions(fn () => new FakeErrorMessage());
|
|
$builderH = $builderA->withCacheDir(sys_get_temp_dir());
|
|
$builderI = $builderA->enableLegacyDoctrineAnnotations();
|
|
|
|
self::assertNotSame($builderA, $builderB);
|
|
self::assertNotSame($builderA, $builderC);
|
|
self::assertNotSame($builderA, $builderD);
|
|
self::assertNotSame($builderA, $builderE);
|
|
self::assertNotSame($builderA, $builderF);
|
|
self::assertNotSame($builderA, $builderG);
|
|
self::assertNotSame($builderA, $builderH);
|
|
self::assertNotSame($builderA, $builderI);
|
|
}
|
|
|
|
public function test_mapper_instance_is_the_same(): void
|
|
{
|
|
self::assertSame($this->mapperBuilder->mapper(), $this->mapperBuilder->mapper());
|
|
}
|
|
}
|