From 8a8f5b2e700a4caba947b7ce41abb93abaa0dc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Glawaty?= Date: Wed, 29 Nov 2023 07:51:47 +0100 Subject: [PATCH] Added ability to provide custom html attributes via `{banner}` macro --- src/Bridge/Latte/RendererProvider.php | 38 ++++++++----- tests/Bridge/Latte/RendererProviderTest.php | 59 ++++++++++++++++----- 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/Bridge/Latte/RendererProvider.php b/src/Bridge/Latte/RendererProvider.php index 241390c..e2789d7 100644 --- a/src/Bridge/Latte/RendererProvider.php +++ b/src/Bridge/Latte/RendererProvider.php @@ -42,7 +42,7 @@ final class RendererProvider private bool $debugMode = false; - /** @var array */ + /** @var array}> */ private array $queue = []; /** @var array> */ @@ -73,9 +73,9 @@ public function __invoke(object $globals, string $positionCode, array $options = $position = $this->createPosition($positionCode, $options); if ($this->renderingMode->shouldBePositionQueued($position, $globals)) { - return $this->addToQueue($position); + return $this->addToQueue($position, $options); } else { - return $this->render($position); + return $this->render($position, $options); } } @@ -101,9 +101,11 @@ public function addConfigureClientEventHandler(ConfigureClientEventHandlerInterf } /** + * @param array $options + * * @throws AmpExceptionInterface */ - private function render(RequestPosition $position): string + private function render(RequestPosition $position, array $options): string { $positionCode = $position->getCode(); $response = $this->fetchResponse(new BannersRequest([$position])); @@ -112,13 +114,16 @@ private function render(RequestPosition $position): string return ''; } - return $this->renderPosition($response->getPosition($positionCode)); + return $this->renderPosition($response->getPosition($positionCode), $options); } - private function addToQueue(RequestPosition $position): string + /** + * @param array $options * + */ + private function addToQueue(RequestPosition $position, array $options): string { $comment = $this->formatHtmlComment($position->getCode()); - $this->queue[$comment] = $position; + $this->queue[$comment] = [$position, $options]; return $comment; } @@ -148,7 +153,10 @@ public function renderQueuedPositions($output) } $response = $this->fetchResponse( - new BannersRequest(array_values($this->queue)), + new BannersRequest(array_map( + static fn (array $item): RequestPosition => $item[0], + array_values($this->queue), + )), ); if (null === $response) { @@ -159,14 +167,14 @@ public function renderQueuedPositions($output) $replacements = array_filter( array_map( - function (RequestPosition $requestPosition) use ($response): ?string { - $responsePosition = $response->getPosition($requestPosition->getCode()); + function (array $item) use ($response): ?string { + $responsePosition = $response->getPosition($item[0]->getCode()); if (null === $responsePosition) { return null; } - return $this->renderPosition($responsePosition); + return $this->renderPosition($responsePosition, $item[1]); }, $this->queue, ), @@ -230,12 +238,16 @@ private function fetchResponse(BannersRequest $request): ?BannersResponse } /** + * @param array $options + * * @throws RendererException */ - private function renderPosition(ResponsePosition $position): string + private function renderPosition(ResponsePosition $position, array $options): string { try { - return $this->renderer->render($position); + $elementAttributes = (array) ($options['attributes'] ?? []); + + return $this->renderer->render($position, $elementAttributes); } catch (RendererException $e) { if ($this->debugMode) { throw $e; diff --git a/tests/Bridge/Latte/RendererProviderTest.php b/tests/Bridge/Latte/RendererProviderTest.php index 3395c4d..b91855b 100644 --- a/tests/Bridge/Latte/RendererProviderTest.php +++ b/tests/Bridge/Latte/RendererProviderTest.php @@ -56,12 +56,47 @@ public function testInvokingDefaultInstanceWithoutResources(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition) + ->with($responsePosition, []) ->andReturn(''); Assert::same('', $provider(new stdClass(), 'homepage.top')); } + public function testInvokingDefaultInstanceWithAttributes(): void + { + $client = Mockery::mock(AmpClientInterface::class); + $renderer = Mockery::mock(RendererInterface::class); + $provider = new RendererProvider($client, $renderer); + + $responsePosition = new ResponsePosition('1234', 'homepage.top', 'Homepage top', 0, ResponsePosition::DisplayTypeSingle, ResponsePosition::BreakpointTypeMin, []); + $response = new BannersResponse([ + 'homepage.top' => $responsePosition, + ]); + + $client + ->shouldReceive('fetchBanners') + ->once() + ->with(Mockery::type(BannersRequest::class)) + ->andReturnUsing(static function (BannersRequest $request) use ($response): BannersResponse { + Assert::equal( + new BannersRequest([ + new RequestPosition('homepage.top'), + ]), + $request, + ); + + return $response; + }); + + $renderer + ->shouldReceive('render') + ->once() + ->with($responsePosition, ['class' => 'my-custom-class']) + ->andReturn(''); + + Assert::same('', $provider(new stdClass(), 'homepage.top', ['attributes' => ['class' => 'my-custom-class']])); + } + public function testInvokingDefaultInstanceWithResources(): void { $client = Mockery::mock(AmpClientInterface::class); @@ -94,7 +129,7 @@ public function testInvokingDefaultInstanceWithResources(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition) + ->with($responsePosition, []) ->andReturn(''); Assert::same( @@ -140,7 +175,7 @@ public function testClientConfigurationEventsShouldBeInvokedBeforeFirstFetch(): $renderer ->shouldReceive('render') ->twice() - ->with($responsePosition) + ->with($responsePosition, []) ->andReturn(''); Assert::same('', $provider(new stdClass(), 'homepage.top')); @@ -242,7 +277,7 @@ public function testExceptionShouldBeThrownWhenRendererThrowsExceptionInDebugMod $renderer ->shouldReceive('render') ->once() - ->with($responsePosition) + ->with($responsePosition, []) ->andThrow(new RendererException('Test renderer exception')); Assert::exception( @@ -271,7 +306,7 @@ public function testEmptyStringShouldBeReturnedWhenRendererThrowsExceptionInNonD $renderer ->shouldReceive('render') ->once() - ->with($responsePosition) + ->with($responsePosition, []) ->andThrow(new RendererException('Test renderer exception')); Assert::same('', $provider(new stdClass(), 'homepage.top')); @@ -298,7 +333,7 @@ public function testExceptionShouldBeLoggedWhenRendererThrowsExceptionInNonDebug $renderer ->shouldReceive('render') ->once() - ->with($responsePosition) + ->with($responsePosition, []) ->andThrow($exception); $logger @@ -342,7 +377,7 @@ public function testPositionsShouldBeQueuedAndReplacedInStringOutput(): void return true; }); - Assert::same('', $provider($globals, 'homepage.top')); + Assert::same('', $provider($globals, 'homepage.top', ['attributes' => ['class' => 'my-custom-class']])); Assert::same('', $provider($globals, 'homepage.bottom', ['resources' => ['resource' => ['a']]])); Assert::true($provider->isAnythingQueued()); @@ -372,11 +407,11 @@ public function testPositionsShouldBeQueuedAndReplacedInStringOutput(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition1) + ->with($responsePosition1, ['class' => 'my-custom-class']) ->andReturn('') ->shouldReceive('render') ->once() - ->with($responsePosition2) + ->with($responsePosition2, []) ->andReturn(''); Assert::same( @@ -418,7 +453,7 @@ public function testPositionsShouldBeQueuedAndReplacedInArrayOutput(): void return true; }); - Assert::same('', $provider($globals, 'homepage.top')); + Assert::same('', $provider($globals, 'homepage.top', ['attributes' => ['class' => 'my-custom-class']])); Assert::same('', $provider($globals, 'homepage.bottom', ['resources' => ['resource' => ['a']]])); Assert::true($provider->isAnythingQueued()); @@ -448,11 +483,11 @@ public function testPositionsShouldBeQueuedAndReplacedInArrayOutput(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition1) + ->with($responsePosition1, ['class' => 'my-custom-class']) ->andReturn('') ->shouldReceive('render') ->once() - ->with($responsePosition2) + ->with($responsePosition2, []) ->andReturn(''); Assert::same(