Skip to content

Commit

Permalink
Switching ArgumentValueResolverInterface into ValueResolverInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
Witold Karaś committed Jul 17, 2024
1 parent ba9c72e commit fbedccb
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/ArgumentResolver/DtoValueResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace K4g\DtoBundle\ArgumentResolver;

use K4g\DtoBundle\Event\DtoResolvedEvent;
use K4g\DtoBundle\Exception\Dynamic\ParameterNotSupportedException;
use K4g\DtoBundle\Exception\Type\InvalidTypeCountException;
use K4g\DtoBundle\Interfaces\DtoInterface;
use K4g\DtoBundle\Interfaces\Resolver\DtoResolverInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;

/** @psalm-suppress UndefinedClass */
if (interface_exists(\Symfony\Component\HttpKernel\Controller\ValueResolverInterface::class)) {
class DtoValueResolver implements \Symfony\Component\HttpKernel\Controller\ValueResolverInterface
{
private DtoResolverInterface $dtoResolver;
private EventDispatcherInterface $eventDispatcher;

public function __construct(
DtoResolverInterface $resolverService,
EventDispatcherInterface $eventDispatcher
) {
$this->dtoResolver = $resolverService;
$this->eventDispatcher = $eventDispatcher;
}

/**
* @param Request $request
* @param ArgumentMetadata $argument
*
* @return iterable<DtoInterface>
*
* @throws InvalidTypeCountException
* @throws ParameterNotSupportedException
*/
public function resolve(
Request $request,
ArgumentMetadata $argument
): iterable {
/** @var class-string<DtoInterface> $class */
$class = $argument->getType();
$this->eventDispatcher->dispatch(
new DtoResolvedEvent(
$object = $this->dtoResolver->resolve($request, $class)
)
);

$object->setOptional($argument->isNullable());

yield $object;
}
}
}
74 changes: 74 additions & 0 deletions tests/Unit/ArgumentResolver/DtoValueResolverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace K4g\DtoBundle\Tests\Unit\ArgumentResolver;

use K4g\DtoBundle\ArgumentResolver\DtoValueResolver;
use K4g\DtoBundle\Event\DtoResolvedEvent;
use K4g\DtoBundle\Tests\Fixtures\Model\ResolveDto\SubDto;
use K4g\DtoBundle\Tests\PHPUnit\KernelTestCase;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;

class DtoValueResolverTest extends KernelTestCase
{
private ValueResolverInterface $service;
private MockObject $eventMock;

protected function setUp(): void
{
self::bootKernel();
$this->eventMock = $this->createMock(EventDispatcherInterface::class);
self::$container->set('event_dispatcher', $this->eventMock);

if (interface_exists(\Symfony\Component\HttpKernel\Controller\ValueResolverInterface::class)) {
$this->service = $this->getService(DtoValueResolver::class);
}
}

public function testResolve(): void
{
$this->assertTrue(true);

if (interface_exists(\Symfony\Component\HttpKernel\Controller\ValueResolverInterface::class)) {
$event = $this->deferCallable(function ($event): void {
$this->assertInstanceOf(DtoResolvedEvent::class, $event);
$this->assertInstanceOf(SubDto::class, $event->getDto());
});

$this->eventMock->expects($this->once())
->method('dispatch')
->willReturnCallback(function (...$args) use ($event) {
$event->set($args);

return $args[0];
});

$request = new Request([], [
'value' => 155,
'floaty_boy' => 22.5,
]);

$mock = $this->createMock(ArgumentMetadata::class);
$mock->method('getType')
->willReturn(SubDto::class);
$mock->method('isNullable')
->willReturn(false);

/**
* @var SubDto $dto
* @psalm-suppress InvalidArgument
*/
$dto = iterator_to_array($this->service->resolve($request, $mock))[0];

$this->assertInstanceOf(SubDto::class, $dto);
$this->assertTrue($dto->isValid());
$this->assertEquals(155, $dto->value);
$this->assertEquals(22.5, $dto->floatVal);
$this->assertTrue($dto->visited('value'));
$this->assertTrue($dto->visited('floatVal'));
}
}
}

0 comments on commit fbedccb

Please sign in to comment.