From f323d272d137334dfd637a134f0e01e1973d4a5a Mon Sep 17 00:00:00 2001 From: Adrien Roches Date: Tue, 9 Jul 2024 20:56:50 +0200 Subject: [PATCH] [FEATURE] Allow Cookie object from http-foundation & ->forwardCookie(string $name) (#89) --- .php-cs-fixer.dist.php | 1 + config/builder_pdf.php | 3 + config/builder_screenshot.php | 3 + src/Builder/CookieAwareTrait.php | 149 ++++++++++++++++++ src/Builder/DefaultBuilderTrait.php | 2 +- .../Pdf/AbstractChromiumPdfBuilder.php | 104 ++++++------ src/Builder/Pdf/AbstractPdfBuilder.php | 23 --- src/Builder/Pdf/UrlPdfBuilder.php | 4 +- .../AbstractChromiumScreenshotBuilder.php | 98 ++++++------ .../Screenshot/UrlScreenshotBuilder.php | 4 +- .../Pdf/AbstractChromiumPdfBuilderTest.php | 3 +- tests/Builder/Pdf/AbstractPdfBuilderTest.php | 61 ------- tests/Builder/Pdf/HtmlPdfBuilderTest.php | 3 +- tests/Builder/Pdf/MarkdownPdfBuilderTest.php | 3 +- tests/Builder/Pdf/UrlPdfBuilderTest.php | 3 +- .../AbstractChromiumScreenshotBuilderTest.php | 3 +- .../AbstractScreenshotBuilderTest.php | 46 ------ .../Screenshot/HtmlScreenshotBuilderTest.php | 3 +- .../MarkdownScreenshotBuilderTest.php | 3 +- .../Screenshot/UrlScreenshotBuilderTest.php | 2 + 20 files changed, 279 insertions(+), 242 deletions(-) create mode 100644 src/Builder/CookieAwareTrait.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index c0612622..bcc531f2 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -10,6 +10,7 @@ ; return (new PhpCsFixer\Config()) + ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect()) ->setUsingCache(false) ->setRiskyAllowed(true) ->setRules([ diff --git a/config/builder_pdf.php b/config/builder_pdf.php index 00f9904f..a150f137 100644 --- a/config/builder_pdf.php +++ b/config/builder_pdf.php @@ -21,6 +21,7 @@ ->args([ service('sensiolabs_gotenberg.client'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), + service('request_stack'), service('twig')->nullOnInvalid(), ]) ->call('setLogger', [service('logger')->nullOnInvalid()]) @@ -32,6 +33,7 @@ ->args([ service('sensiolabs_gotenberg.client'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), + service('request_stack'), service('twig')->nullOnInvalid(), service('router')->nullOnInvalid(), ]) @@ -45,6 +47,7 @@ ->args([ service('sensiolabs_gotenberg.client'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), + service('request_stack'), service('twig')->nullOnInvalid(), ]) ->call('setLogger', [service('logger')->nullOnInvalid()]) diff --git a/config/builder_screenshot.php b/config/builder_screenshot.php index c6591c02..7e04c109 100644 --- a/config/builder_screenshot.php +++ b/config/builder_screenshot.php @@ -18,6 +18,7 @@ ->args([ service('sensiolabs_gotenberg.client'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), + service('request_stack'), service('twig')->nullOnInvalid(), ]) ->call('setLogger', [service('logger')->nullOnInvalid()]) @@ -29,6 +30,7 @@ ->args([ service('sensiolabs_gotenberg.client'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), + service('request_stack'), service('twig')->nullOnInvalid(), service('router')->nullOnInvalid(), ]) @@ -42,6 +44,7 @@ ->args([ service('sensiolabs_gotenberg.client'), service('sensiolabs_gotenberg.asset.base_dir_formatter'), + service('request_stack'), service('twig')->nullOnInvalid(), ]) ->call('setLogger', [service('logger')->nullOnInvalid()]) diff --git a/src/Builder/CookieAwareTrait.php b/src/Builder/CookieAwareTrait.php new file mode 100644 index 00000000..8e8dc679 --- /dev/null +++ b/src/Builder/CookieAwareTrait.php @@ -0,0 +1,149 @@ + $cookies + */ + abstract public function cookies(array $cookies): static; + + /** + * @param array{cookies?: array} $formFields + * @param list $cookies + */ + private function withCookies(array &$formFields, array $cookies): static + { + if ([] === $cookies) { + unset($formFields['cookies']); + + return $this; + } + + $formFields['cookies'] = []; + + foreach ($cookies as $cookie) { + if ($cookie instanceof Cookie) { + $this->setCookie($cookie->getName(), $cookie); + + continue; + } + + $this->setCookie($cookie['name'], $cookie); + } + + return $this; + } + + /** + * @param Cookie|array{name: string, value: string, domain: string, path?: string|null, secure?: bool|null, httpOnly?: bool|null, sameSite?: 'Strict'|'Lax'|null} $cookie + */ + abstract public function setCookie(string $key, Cookie|array $cookie): static; + + /** + * @param array{cookies?: array} $formFields + * @param Cookie|array{name: string, value: string, domain: string, path?: string|null, secure?: bool|null, httpOnly?: bool|null, sameSite?: 'Strict'|'Lax'|null} $cookie + */ + private function withCookie(array &$formFields, string $key, Cookie|array $cookie): static + { + $formFields['cookies'] ??= []; + $formFields['cookies'][$key] = $cookie; + + return $this; + } + + /** + * Add cookies to store in the Chromium cookie jar. + * + * @see https://gotenberg.dev/docs/routes#cookies-chromium + * + * @param list $cookies + */ + public function addCookies(array $cookies): static + { + foreach ($cookies as $cookie) { + if ($cookie instanceof Cookie) { + $this->setCookie($cookie->getName(), $cookie); + + continue; + } + + $this->setCookie($cookie['name'], $cookie); + } + + return $this; + } + + private function forwardCookieFromRequest(Request|null $request, string $key, LoggerInterface|null $logger = null): static + { + if (null === $request) { + $logger?->debug('Cookie {sensiolabs_gotenberg.cookie_name} cannot be forwarded because there is no Request.', [ + 'sensiolabs_gotenberg.cookie_name' => $key, + ]); + + return $this; + } + + if (false === $request->cookies->has($key)) { + $logger?->debug('Cookie {sensiolabs_gotenberg.cookie_name} does not exists.', [ + 'sensiolabs_gotenberg.cookie_name' => $key, + ]); + + return $this; + } + + $value = $request->cookies->get($key); + $domain = $request->getHost(); + + return $this->setCookie($key, [ + 'name' => $key, + 'value' => $value, + 'domain' => $domain, + ]); + } + + abstract public function forwardCookie(string $name): static; + + /** + * @param (\Closure(string, mixed): array) $encoder + * + * @return array|string|\Stringable|int|float|bool|\BackedEnum|DataPart> + */ + private function cookieNormalizer(mixed $value, callable $encoder): array + { + $cookies = array_values($value); + $data = []; + + foreach ($cookies as $cookie) { + if ($cookie instanceof Cookie) { + $data[] = [ + 'name' => $cookie->getName(), + 'value' => $cookie->getValue(), + 'domain' => $cookie->getDomain(), + 'path' => $cookie->getPath(), + 'secure' => $cookie->isSecure(), + 'httpOnly' => $cookie->isHttpOnly(), + 'sameSite' => null !== ($sameSite = $cookie->getSameSite()) ? ucfirst(strtolower($sameSite)) : null, + ]; + + continue; + } + + $data[] = $cookie; + } + + return $encoder('cookies', $data); + } +} diff --git a/src/Builder/DefaultBuilderTrait.php b/src/Builder/DefaultBuilderTrait.php index a3f81d65..26431dcb 100644 --- a/src/Builder/DefaultBuilderTrait.php +++ b/src/Builder/DefaultBuilderTrait.php @@ -49,7 +49,7 @@ protected function addNormalizer(string $key, \Closure $normalizer): void /** * @return array */ - private function encodeData(string $key, mixed $value): array + protected function encodeData(string $key, mixed $value): array { try { $encodedValue = json_encode($value, \JSON_THROW_ON_ERROR); diff --git a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php index 46a114d6..98cbe150 100644 --- a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php +++ b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php @@ -2,6 +2,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Pdf; +use Sensiolabs\GotenbergBundle\Builder\CookieAwareTrait; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Enumeration\EmulatedMediaType; use Sensiolabs\GotenbergBundle\Enumeration\PaperSizeInterface; @@ -11,18 +12,49 @@ use Sensiolabs\GotenbergBundle\Exception\InvalidBuilderConfiguration; use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; +use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\File as DataPartFile; use Twig\Environment; abstract class AbstractChromiumPdfBuilder extends AbstractPdfBuilder { + use CookieAwareTrait; + public function __construct( GotenbergClientInterface $gotenbergClient, AssetBaseDirFormatter $asset, + private readonly RequestStack $requestStack, private readonly Environment|null $twig = null, ) { parent::__construct($gotenbergClient, $asset); + + $normalizers = [ + 'extraHttpHeaders' => function (mixed $value): array { + return $this->encodeData('extraHttpHeaders', $value); + }, + 'assets' => static function (array $value): array { + return ['files' => $value]; + }, + Part::Header->value => static function (DataPart $value): array { + return ['files' => $value]; + }, + Part::Body->value => static function (DataPart $value): array { + return ['files' => $value]; + }, + Part::Footer->value => static function (DataPart $value): array { + return ['files' => $value]; + }, + 'failOnHttpStatusCodes' => function (mixed $value): array { + return $this->encodeData('failOnHttpStatusCodes', $value); + }, + 'cookies' => fn (mixed $value): array => $this->cookieNormalizer($value, $this->encodeData(...)), + ]; + + foreach ($normalizers as $key => $normalizer) { + $this->addNormalizer($key, $normalizer); + } } /** @@ -39,6 +71,27 @@ public function setConfigurations(array $configurations): static return $this; } + /** + * @param list $cookies + */ + public function cookies(array $cookies): static + { + return $this->withCookies($this->formFields, $cookies); + } + + /** + * @param Cookie|array{name: string, value: string, domain: string, path?: string|null, secure?: bool|null, httpOnly?: bool|null, sameSite?: 'Strict'|'Lax'|null} $cookie + */ + public function setCookie(string $key, Cookie|array $cookie): static + { + return $this->withCookie($this->formFields, $key, $cookie); + } + + public function forwardCookie(string $name): static + { + return $this->forwardCookieFromRequest($this->requestStack->getCurrentRequest(), $name, $this->logger); + } + /** * Define whether to print the entire content in one single page. * @@ -322,57 +375,6 @@ public function emulatedMediaType(EmulatedMediaType $mediaType): static return $this; } - /** - * Cookies to store in the Chromium cookie jar. (overrides any previous cookies). - * - * @see https://gotenberg.dev/docs/routes#cookies-chromium - * - * @param list $cookies - */ - public function cookies(array $cookies): static - { - if ([] === $cookies) { - unset($this->formFields['cookies']); - - return $this; - } - - $this->formFields['cookies'] = []; - - foreach ($cookies as $cookie) { - $this->setCookie($cookie['name'], $cookie); - } - - return $this; - } - - /** - * @param array{name: string, value: string, domain: string, path?: string|null, secure?: bool|null, httpOnly?: bool|null, sameSite?: 'Strict'|'Lax'|null} $cookie - */ - public function setCookie(string $key, array $cookie): static - { - $this->formFields['cookies'] ??= []; - $this->formFields['cookies'][$key] = $cookie; - - return $this; - } - - /** - * Add cookies to store in the Chromium cookie jar. - * - * @see https://gotenberg.dev/docs/routes#cookies-chromium - * - * @param list $cookies - */ - public function addCookies(array $cookies): static - { - foreach ($cookies as $cookie) { - $this->setCookie($cookie['name'], $cookie); - } - - return $this; - } - /** * Sets extra HTTP headers that Chromium will send when loading the HTML * document. (default None). (overrides any previous headers). diff --git a/src/Builder/Pdf/AbstractPdfBuilder.php b/src/Builder/Pdf/AbstractPdfBuilder.php index 3f9f7072..1458fa4d 100644 --- a/src/Builder/Pdf/AbstractPdfBuilder.php +++ b/src/Builder/Pdf/AbstractPdfBuilder.php @@ -5,9 +5,7 @@ use Sensiolabs\GotenbergBundle\Builder\DefaultBuilderTrait; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Client\GotenbergResponse; -use Sensiolabs\GotenbergBundle\Enumeration\Part; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; -use Symfony\Component\Mime\Part\DataPart; abstract class AbstractPdfBuilder implements PdfBuilderInterface { @@ -21,27 +19,6 @@ public function __construct( $this->asset = $asset; $this->normalizers = [ - 'extraHttpHeaders' => function (mixed $value): array { - return $this->encodeData('extraHttpHeaders', $value); - }, - 'assets' => static function (array $value): array { - return ['files' => $value]; - }, - Part::Header->value => static function (DataPart $value): array { - return ['files' => $value]; - }, - Part::Body->value => static function (DataPart $value): array { - return ['files' => $value]; - }, - Part::Footer->value => static function (DataPart $value): array { - return ['files' => $value]; - }, - 'failOnHttpStatusCodes' => function (mixed $value): array { - return $this->encodeData('failOnHttpStatusCodes', $value); - }, - 'cookies' => function (mixed $value): array { - return $this->encodeData('cookies', array_values($value)); - }, 'metadata' => function (mixed $value): array { return $this->encodeData('metadata', $value); }, diff --git a/src/Builder/Pdf/UrlPdfBuilder.php b/src/Builder/Pdf/UrlPdfBuilder.php index a8179f7a..4d6c3fce 100644 --- a/src/Builder/Pdf/UrlPdfBuilder.php +++ b/src/Builder/Pdf/UrlPdfBuilder.php @@ -5,6 +5,7 @@ use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RequestContext; use Twig\Environment; @@ -18,10 +19,11 @@ final class UrlPdfBuilder extends AbstractChromiumPdfBuilder public function __construct( GotenbergClientInterface $gotenbergClient, AssetBaseDirFormatter $asset, + RequestStack $requestStack, Environment|null $twig = null, private readonly UrlGeneratorInterface|null $urlGenerator = null, ) { - parent::__construct($gotenbergClient, $asset, $twig); + parent::__construct($gotenbergClient, $asset, $requestStack, $twig); $this->addNormalizer('route', $this->generateUrlFromRoute(...)); } diff --git a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php index f5af4867..b83fc44d 100644 --- a/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractChromiumScreenshotBuilder.php @@ -2,6 +2,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Screenshot; +use Sensiolabs\GotenbergBundle\Builder\CookieAwareTrait; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Enumeration\EmulatedMediaType; use Sensiolabs\GotenbergBundle\Enumeration\Part; @@ -9,18 +10,43 @@ use Sensiolabs\GotenbergBundle\Exception\InvalidBuilderConfiguration; use Sensiolabs\GotenbergBundle\Exception\ScreenshotPartRenderingException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; +use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\File as DataPartFile; use Twig\Environment; abstract class AbstractChromiumScreenshotBuilder extends AbstractScreenshotBuilder { + use CookieAwareTrait; + public function __construct( GotenbergClientInterface $gotenbergClient, AssetBaseDirFormatter $asset, + private readonly RequestStack $requestStack, private readonly Environment|null $twig = null, ) { parent::__construct($gotenbergClient, $asset); + + $normalizers = [ + 'extraHttpHeaders' => function (mixed $value): array { + return $this->encodeData('extraHttpHeaders', $value); + }, + 'assets' => static function (array $value): array { + return ['files' => $value]; + }, + Part::Body->value => static function (DataPart $value): array { + return ['files' => $value]; + }, + 'failOnHttpStatusCodes' => function (mixed $value): array { + return $this->encodeData('failOnHttpStatusCodes', $value); + }, + 'cookies' => fn (mixed $value): array => $this->cookieNormalizer($value, $this->encodeData(...)), + ]; + + foreach ($normalizers as $key => $normalizer) { + $this->addNormalizer($key, $normalizer); + } } /** @@ -37,6 +63,27 @@ public function setConfigurations(array $configurations): static return $this; } + /** + * @param list $cookies + */ + public function cookies(array $cookies): static + { + return $this->withCookies($this->formFields, $cookies); + } + + /** + * @param Cookie|array{name: string, value: string, domain: string, path?: string|null, secure?: bool|null, httpOnly?: bool|null, sameSite?: 'Strict'|'Lax'|null} $cookie + */ + public function setCookie(string $key, Cookie|array $cookie): static + { + return $this->withCookie($this->formFields, $key, $cookie); + } + + public function forwardCookie(string $name): static + { + return $this->forwardCookieFromRequest($this->requestStack->getCurrentRequest(), $name, $this->logger); + } + /** * The device screen width in pixels. (Default 800). * @@ -164,57 +211,6 @@ public function emulatedMediaType(EmulatedMediaType $mediaType): static return $this; } - /** - * Cookies to store in the Chromium cookie jar. (overrides any previous cookies). - * - * @see https://gotenberg.dev/docs/routes#cookies-chromium - * - * @param list $cookies - */ - public function cookies(array $cookies): static - { - if ([] === $cookies) { - unset($this->formFields['cookies']); - - return $this; - } - - $this->formFields['cookies'] = []; - - foreach ($cookies as $cookie) { - $this->setCookie($cookie['name'], $cookie); - } - - return $this; - } - - /** - * @param array{name: string, value: string, domain: string, path: string|null, secure: bool|null, httpOnly: bool|null, sameSite: 'Strict'|'Lax'|null} $cookie - */ - public function setCookie(string $key, array $cookie): static - { - $this->formFields['cookies'] ??= []; - $this->formFields['cookies'][$key] = $cookie; - - return $this; - } - - /** - * Add cookies to store in the Chromium cookie jar. - * - * @see https://gotenberg.dev/docs/routes#cookies-chromium - * - * @param list $cookies - */ - public function addCookies(array $cookies): static - { - foreach ($cookies as $cookie) { - $this->setCookie($cookie['name'], $cookie); - } - - return $this; - } - /** * Sets extra HTTP headers that Chromium will send when loading the HTML * document. (default None). (overrides any previous headers). diff --git a/src/Builder/Screenshot/UrlScreenshotBuilder.php b/src/Builder/Screenshot/UrlScreenshotBuilder.php index 38369559..ff797e7e 100644 --- a/src/Builder/Screenshot/UrlScreenshotBuilder.php +++ b/src/Builder/Screenshot/UrlScreenshotBuilder.php @@ -5,6 +5,7 @@ use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RequestContext; use Twig\Environment; @@ -18,10 +19,11 @@ final class UrlScreenshotBuilder extends AbstractChromiumScreenshotBuilder public function __construct( GotenbergClientInterface $gotenbergClient, AssetBaseDirFormatter $asset, + RequestStack $requestStack, Environment|null $twig = null, private readonly UrlGeneratorInterface|null $urlGenerator = null, ) { - parent::__construct($gotenbergClient, $asset, $twig); + parent::__construct($gotenbergClient, $asset, $requestStack, $twig); $this->addNormalizer('route', $this->generateUrlFromRoute(...)); } diff --git a/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php b/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php index 6bd0649a..e2d1e3bc 100644 --- a/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php +++ b/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php @@ -17,6 +17,7 @@ use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; use Sensiolabs\GotenbergBundle\Twig\GotenbergAssetExtension; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(AbstractChromiumPdfBuilder::class)] #[UsesClass(AbstractPdfBuilder::class)] @@ -384,7 +385,7 @@ public function testThrowIfTwigTemplateIsInvalid(): void private function getChromiumPdfBuilder(bool $twig = true): AbstractChromiumPdfBuilder { - return new class($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null) extends AbstractChromiumPdfBuilder { + return new class($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack(), true === $twig ? self::$twig : null) extends AbstractChromiumPdfBuilder { protected function getEndpoint(): string { return '/fake/endpoint'; diff --git a/tests/Builder/Pdf/AbstractPdfBuilderTest.php b/tests/Builder/Pdf/AbstractPdfBuilderTest.php index 378686e1..8310656f 100644 --- a/tests/Builder/Pdf/AbstractPdfBuilderTest.php +++ b/tests/Builder/Pdf/AbstractPdfBuilderTest.php @@ -12,14 +12,12 @@ use Sensiolabs\GotenbergBundle\Client\GotenbergClient; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Client\GotenbergResponse; -use Sensiolabs\GotenbergBundle\Enumeration\PdfFormat; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpFoundation\HeaderUtils; use Symfony\Component\Mime\Part\DataPart; -use Symfony\Component\Mime\Part\File as DataPartFile; #[CoversClass(AbstractPdfBuilder::class)] #[UsesClass(GotenbergClient::class)] @@ -41,65 +39,6 @@ public function testFilenameIsCorrectlySetOnResponse(): void self::assertSame('attachment; filename=some_file.png', $response->headers->get('Content-Disposition')); } - public static function formFieldsNormalizerProvider(): \Generator - { - yield 'extraHttpHeaders' => [ - ['extraHttpHeaders' => ['MyHeader' => 'SomeValue']], - 'extraHttpHeaders', '{"MyHeader":"SomeValue"}', - ]; - - yield 'assets' => [ - ['assets' => ['logo.png' => $dataPart = new DataPart(new DataPartFile(self::FIXTURE_DIR.'/assets/logo.png'))]], - 'files', $dataPart, - ]; - - yield 'header.html' => [ - ['header.html' => $dataPart = new DataPart(new DataPartFile(self::FIXTURE_DIR.'/files/header.html'))], - 'files', $dataPart, - ]; - - yield 'index.html' => [ - ['index.html' => $dataPart = new DataPart(new DataPartFile(self::FIXTURE_DIR.'/files/index.html'))], - 'files', $dataPart, - ]; - - yield 'footer.html' => [ - ['footer.html' => $dataPart = new DataPart(new DataPartFile(self::FIXTURE_DIR.'/files/footer.html'))], - 'files', $dataPart, - ]; - - yield 'failOnHttpStatusCodes' => [ - ['failOnHttpStatusCodes' => [499, 500]], - 'failOnHttpStatusCodes', '[499,500]', - ]; - - yield 'cookies' => [ - ['cookies' => ['MyCookie' => ['name' => 'MyCookieName', 'value' => 'Chocolate', 'domain' => 'sensiolabs.com']]], - 'cookies', '[{"name":"MyCookieName","value":"Chocolate","domain":"sensiolabs.com"}]', - ]; - - yield 'metadata' => [ - ['metadata' => ['Author' => 'SensioLabs']], - 'metadata', '{"Author":"SensioLabs"}', - ]; - - yield 'using BackedEnum' => [ - ['backed_enum' => PdfFormat::Pdf3b], - 'backed_enum', 'PDF/A-3b', - ]; - } - - #[DataProvider('formFieldsNormalizerProvider')] - #[TestDox('Form field "$_dataName" is correctly normalized')] - public function testFormFieldsNormalizer(mixed $raw, string $key, mixed $expected): void - { - $builder = $this->getPdfBuilder($raw); - $data = $builder->getMultipartFormData()[0]; - - self::assertArrayHasKey($key, $data); - self::assertSame($expected, $data[$key]); - } - public static function nativeNormalizersProvider(): \Generator { yield 'boolean (true)' => ['boolean', true, 'true']; diff --git a/tests/Builder/Pdf/HtmlPdfBuilderTest.php b/tests/Builder/Pdf/HtmlPdfBuilderTest.php index 3fa6d2aa..5b434fb4 100644 --- a/tests/Builder/Pdf/HtmlPdfBuilderTest.php +++ b/tests/Builder/Pdf/HtmlPdfBuilderTest.php @@ -12,6 +12,7 @@ use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; use Sensiolabs\GotenbergBundle\Twig\GotenbergAssetExtension; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(HtmlPdfBuilder::class)] #[UsesClass(AbstractChromiumPdfBuilder::class)] @@ -107,6 +108,6 @@ public function testRequiredFormData(): void private function getHtmlPdfBuilder(bool $twig = true): HtmlPdfBuilder { - return new HtmlPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null); + return new HtmlPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack(), true === $twig ? self::$twig : null); } } diff --git a/tests/Builder/Pdf/MarkdownPdfBuilderTest.php b/tests/Builder/Pdf/MarkdownPdfBuilderTest.php index 72e5faa4..2a1b4557 100644 --- a/tests/Builder/Pdf/MarkdownPdfBuilderTest.php +++ b/tests/Builder/Pdf/MarkdownPdfBuilderTest.php @@ -10,6 +10,7 @@ use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(MarkdownPdfBuilder::class)] #[UsesClass(AbstractChromiumPdfBuilder::class)] @@ -64,6 +65,6 @@ public function testRequiredMarkdownFile(): void private function getMarkdownPdfBuilder(bool $twig = true): MarkdownPdfBuilder { - return new MarkdownPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null); + return new MarkdownPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack(), true === $twig ? self::$twig : null); } } diff --git a/tests/Builder/Pdf/UrlPdfBuilderTest.php b/tests/Builder/Pdf/UrlPdfBuilderTest.php index 61196355..a2884552 100644 --- a/tests/Builder/Pdf/UrlPdfBuilderTest.php +++ b/tests/Builder/Pdf/UrlPdfBuilderTest.php @@ -9,6 +9,7 @@ use Sensiolabs\GotenbergBundle\Builder\Pdf\UrlPdfBuilder; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(UrlPdfBuilder::class)] #[UsesClass(AbstractChromiumPdfBuilder::class)] @@ -57,6 +58,6 @@ public function testRequiredFormData(): void private function getUrlPdfBuilder(): UrlPdfBuilder { - return new UrlPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter); + return new UrlPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack()); } } diff --git a/tests/Builder/Screenshot/AbstractChromiumScreenshotBuilderTest.php b/tests/Builder/Screenshot/AbstractChromiumScreenshotBuilderTest.php index 4469c8a6..19bc594e 100644 --- a/tests/Builder/Screenshot/AbstractChromiumScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/AbstractChromiumScreenshotBuilderTest.php @@ -12,6 +12,7 @@ use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractScreenshotBuilder; use Sensiolabs\GotenbergBundle\Enumeration\EmulatedMediaType; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(AbstractChromiumScreenshotBuilder::class)] #[UsesClass(AbstractScreenshotBuilder::class)] @@ -83,7 +84,7 @@ public function testConfigurationIsCorrectlySet(string $key, mixed $value, array private function getChromiumScreenshotBuilder(bool $twig = true): AbstractChromiumScreenshotBuilder { - return new class($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null) extends AbstractChromiumScreenshotBuilder { + return new class($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack(), true === $twig ? self::$twig : null) extends AbstractChromiumScreenshotBuilder { protected function getEndpoint(): string { return '/fake/endpoint'; diff --git a/tests/Builder/Screenshot/AbstractScreenshotBuilderTest.php b/tests/Builder/Screenshot/AbstractScreenshotBuilderTest.php index ea23f00c..39acbcf4 100644 --- a/tests/Builder/Screenshot/AbstractScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/AbstractScreenshotBuilderTest.php @@ -12,14 +12,12 @@ use Sensiolabs\GotenbergBundle\Client\GotenbergClient; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Client\GotenbergResponse; -use Sensiolabs\GotenbergBundle\Enumeration\PdfFormat; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpFoundation\HeaderUtils; use Symfony\Component\Mime\Part\DataPart; -use Symfony\Component\Mime\Part\File as DataPartFile; #[CoversClass(AbstractScreenshotBuilder::class)] #[UsesClass(GotenbergClient::class)] @@ -41,50 +39,6 @@ public function testFilenameIsCorrectlySetOnResponse(): void self::assertSame('attachment; filename=some_file.png', $response->headers->get('Content-Disposition')); } - public static function formFieldsNormalizerProvider(): \Generator - { - yield 'extraHttpHeaders' => [ - ['extraHttpHeaders' => ['MyHeader' => 'SomeValue']], - 'extraHttpHeaders', '{"MyHeader":"SomeValue"}', - ]; - - yield 'assets' => [ - ['assets' => ['logo.png' => $dataPart = new DataPart(new DataPartFile(self::FIXTURE_DIR.'/assets/logo.png'))]], - 'files', $dataPart, - ]; - - yield 'index.html' => [ - ['index.html' => $dataPart = new DataPart(new DataPartFile(self::FIXTURE_DIR.'/files/index.html'))], - 'files', $dataPart, - ]; - - yield 'failOnHttpStatusCodes' => [ - ['failOnHttpStatusCodes' => [499, 500]], - 'failOnHttpStatusCodes', '[499,500]', - ]; - - yield 'cookies' => [ - ['cookies' => ['MyCookie' => ['name' => 'MyCookieName', 'value' => 'Chocolate', 'domain' => 'sensiolabs.com']]], - 'cookies', '[{"name":"MyCookieName","value":"Chocolate","domain":"sensiolabs.com"}]', - ]; - - yield 'using BackedEnum' => [ - ['backed_enum' => PdfFormat::Pdf3b], - 'backed_enum', 'PDF/A-3b', - ]; - } - - #[DataProvider('formFieldsNormalizerProvider')] - #[TestDox('Form field "$_dataName" is correctly normalized')] - public function testFormFieldsNormalizer(mixed $raw, string $key, mixed $expected): void - { - $builder = $this->getScreenshotBuilder($raw); - $data = $builder->getMultipartFormData()[0]; - - self::assertArrayHasKey($key, $data); - self::assertSame($expected, $data[$key]); - } - public static function nativeNormalizersProvider(): \Generator { yield 'boolean (true)' => ['boolean', true, 'true']; diff --git a/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php b/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php index b79ed3a6..61775f38 100644 --- a/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php @@ -12,6 +12,7 @@ use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; use Sensiolabs\GotenbergBundle\Twig\GotenbergAssetExtension; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(HtmlScreenshotBuilder::class)] #[UsesClass(AbstractChromiumScreenshotBuilder::class)] @@ -107,6 +108,6 @@ public function testRequiredFormData(): void private function getHtmlScreenshotBuilder(bool $twig = true): HtmlScreenshotBuilder { - return new HtmlScreenshotBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null); + return new HtmlScreenshotBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack(), true === $twig ? self::$twig : null); } } diff --git a/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php b/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php index abdbd4c4..51c8252e 100644 --- a/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php @@ -10,6 +10,7 @@ use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; +use Symfony\Component\HttpFoundation\RequestStack; #[CoversClass(MarkdownScreenshotBuilder::class)] #[UsesClass(AbstractChromiumScreenshotBuilder::class)] @@ -92,6 +93,6 @@ public function testRequiredMarkdownFile(): void private function getMarkdownScreenshotBuilder(bool $twig = true): MarkdownScreenshotBuilder { - return new MarkdownScreenshotBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null); + return new MarkdownScreenshotBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, new RequestStack(), true === $twig ? self::$twig : null); } } diff --git a/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php b/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php index 8dff5f9e..fe921db1 100644 --- a/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php @@ -10,6 +10,7 @@ use Sensiolabs\GotenbergBundle\Builder\Screenshot\UrlScreenshotBuilder; use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\RouterInterface; #[CoversClass(UrlScreenshotBuilder::class)] @@ -73,6 +74,7 @@ private function getUrlScreenshotBuilder(bool $twig = true): UrlScreenshotBuilde return new UrlScreenshotBuilder( $this->gotenbergClient, self::$assetBaseDirFormatter, + new RequestStack(), true === $twig ? self::$twig : null, $this->router, );