diff --git a/src/Component/Tests/State/Provider/FactoryProviderTest.php b/src/Component/Tests/State/Provider/FactoryProviderTest.php new file mode 100644 index 000000000..7d692112b --- /dev/null +++ b/src/Component/Tests/State/Provider/FactoryProviderTest.php @@ -0,0 +1,135 @@ +decorated = $this->prophesize(ProviderInterface::class); + $this->factory = $this->prophesize(FactoryInterface::class); + + $this->factoryProvider = new FactoryProvider( + $this->decorated->reveal(), + $this->factory->reveal(), + ); + } + + /** @test */ + public function it_uses_factory_from_operation(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $data = $this->prophesize(\stdClass::class); + + $operation = new Create(); + + $context = new Context(new RequestOption($request->reveal())); + + $this->decorated->provide($operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $request->attributes = $attributes; + + $this->factory->create($operation, $context)->willReturn($data)->shouldBeCalled(); + + $attributes->set('data', $data)->shouldBeCalled(); + + $this->factoryProvider->provide($operation, $context); + } + + /** @test */ + public function it_does_not_store_data_on_request_when_it_does_not_exist(): void + { + $attributes = $this->prophesize(ParameterBag::class); + $data = $this->prophesize(\stdClass::class); + + $operation = new Create(); + + $context = new Context(); + + $this->decorated->provide($operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $this->factory->create($operation, $context)->willReturn($data)->shouldBeCalled(); + + $attributes->set('data', $data)->shouldNotBeCalled(); + + $this->factoryProvider->provide($operation, $context); + } + + /** @test */ + public function it_does_nothing_when_operation_is_not_a_factory_aware_operation(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $data = $this->prophesize(\stdClass::class); + + $operation = new Update(); + + $context = new Context(); + + $this->decorated->provide($operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $request->attributes = $attributes; + + $this->factory->create($operation, $context)->willReturn($data)->shouldNotBeCalled(); + + $attributes->set('data', $data)->shouldNotBeCalled(); + + $this->factoryProvider->provide($operation, $context); + } + + /** @test */ + public function it_does_nothing_when_factory_is_disabled(): void + { + $request = $this->prophesize(Request::class); + $attributes = $this->prophesize(ParameterBag::class); + $data = $this->prophesize(\stdClass::class); + + $operation = new Create(factory: false); + + $context = new Context(); + + $this->decorated->provide($operation, $context)->willReturn(['foo' => 'fighters'])->shouldBeCalled(); + + $request->attributes = $attributes; + + $this->factory->create($operation, $context)->willReturn($data)->shouldNotBeCalled(); + + $attributes->set('data', $data)->shouldNotBeCalled(); + + $this->factoryProvider->provide($operation, $context); + } +} diff --git a/src/Component/src/State/Provider/FactoryProvider.php b/src/Component/src/State/Provider/FactoryProvider.php new file mode 100644 index 000000000..5c2bef73e --- /dev/null +++ b/src/Component/src/State/Provider/FactoryProvider.php @@ -0,0 +1,50 @@ +decorated->provide($operation, $context); + + $request = $context->get(RequestOption::class)?->request(); + + if ( + !$operation instanceof FactoryAwareOperationInterface || + !($operation->getFactory() ?? true) + ) { + return $data; + } + + $data = $this->factory->create($operation, $context); + + $request?->attributes->set('data', $data); + + return $data; + } +}