From 1e4348d4174f8ee7ed047a42f5913dd73c5de67e Mon Sep 17 00:00:00 2001 From: Adrien Roches Date: Fri, 31 May 2024 09:04:56 +0200 Subject: [PATCH] [UPDATE] Better tests (#52) * Fix risky tests * Add tests * Fix issues with parsing int / float * Add unit of enum PaperSize to tests --- phpstan.neon | 4 - .../Pdf/AbstractChromiumPdfBuilder.php | 26 +- src/Builder/Pdf/AbstractPdfBuilder.php | 14 +- .../Screenshot/AbstractScreenshotBuilder.php | 12 +- src/DependencyInjection/Configuration.php | 11 +- src/Enum/PaperSize.php | 44 +-- src/Enum/Unit.php | 16 +- tests/Builder/AbstractBuilderTestCase.php | 35 ++- .../Pdf/AbstractChromiumPdfBuilderTest.php | 230 ++++++++++++++++ tests/Builder/Pdf/HtmlPdfBuilderTest.php | 256 +++++------------- .../Screenshot/HtmlScreenshotBuilderTest.php | 221 +++++---------- .../MarkdownScreenshotBuilderTest.php | 4 + .../Screenshot/UrlScreenshotBuilderTest.php | 4 + tests/Enum/PaperSizeTest.php | 8 + tests/Enum/UnitTest.php | 31 +++ tests/Fixtures/templates/content.html.twig | 2 +- tests/Fixtures/templates/header.html.twig | 2 +- tests/GotenbergPdfTest.php | 2 + tests/GotenbergScreenshotTest.php | 12 + 19 files changed, 543 insertions(+), 391 deletions(-) create mode 100644 tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php create mode 100644 tests/Enum/UnitTest.php diff --git a/phpstan.neon b/phpstan.neon index bcf89a33..19c25ac4 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,10 +5,6 @@ parameters: - 'src' - 'tests' ignoreErrors: - - - message: "#^Cannot use array destructuring on array\\\\|null\\.$#" - count: 1 - path: src/DataCollector/GotenbergDataCollector.php - message: "#^Method Sensiolabs\\\\GotenbergBundle\\\\Tests\\\\Kernel\\:\\:configureContainer\\(\\) is unused\\.$#" count: 1 diff --git a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php index 13226fa5..72e81499 100644 --- a/src/Builder/Pdf/AbstractChromiumPdfBuilder.php +++ b/src/Builder/Pdf/AbstractChromiumPdfBuilder.php @@ -3,7 +3,7 @@ namespace Sensiolabs\GotenbergBundle\Builder\Pdf; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; -use Sensiolabs\GotenbergBundle\Enum\PaperSize; +use Sensiolabs\GotenbergBundle\Enum\EmulatedMediaType; use Sensiolabs\GotenbergBundle\Enum\PaperSizeInterface; use Sensiolabs\GotenbergBundle\Enum\Part; use Sensiolabs\GotenbergBundle\Enum\PdfFormat; @@ -315,9 +315,9 @@ public function waitForExpression(string $expression): static * * @see https://gotenberg.dev/docs/routes#console-exceptions */ - public function emulatedMediaType(string $mediaType): static + public function emulatedMediaType(EmulatedMediaType $mediaType): static { - $this->formFields['emulatedMediaType'] = $mediaType; + $this->formFields['emulatedMediaType'] = $mediaType->value; return $this; } @@ -525,22 +525,16 @@ protected function withRenderedPart(Part $pdfPart, string $template, array $cont private function addConfiguration(string $configurationName, mixed $value): void { - $splitAndParseStringWithUnit = static function (mixed $raw, callable $callback): void { - [$value, $unit] = sscanf((string) $raw, '%d%s') ?? throw new \InvalidArgumentException(sprintf('Unexpected value "%s", expected format is "%%d%%s"', $raw)); - - $callback((float) $value, Unit::tryFrom((string) $unit) ?? Unit::Inches); - }; - match ($configurationName) { 'single_page' => $this->singlePage($value), 'pdf_format' => $this->pdfFormat(PdfFormat::from($value)), 'pdf_universal_access' => $this->pdfUniversalAccess($value), - 'paper_width' => $this->paperWidth($value), - 'paper_height' => $this->paperHeight($value), - 'margin_top' => $splitAndParseStringWithUnit($value, $this->marginTop(...)), - 'margin_bottom' => $splitAndParseStringWithUnit($value, $this->marginBottom(...)), - 'margin_left' => $splitAndParseStringWithUnit($value, $this->marginLeft(...)), - 'margin_right' => $splitAndParseStringWithUnit($value, $this->marginRight(...)), + 'paper_width' => $this->paperWidth(...Unit::parse($value)), + 'paper_height' => $this->paperHeight(...Unit::parse($value)), + 'margin_top' => $this->marginTop(...Unit::parse($value)), + 'margin_bottom' => $this->marginBottom(...Unit::parse($value)), + 'margin_left' => $this->marginLeft(...Unit::parse($value)), + 'margin_right' => $this->marginRight(...Unit::parse($value)), 'prefer_css_page_size' => $this->preferCssPageSize($value), 'print_background' => $this->printBackground($value), 'omit_background' => $this->omitBackground($value), @@ -549,7 +543,7 @@ private function addConfiguration(string $configurationName, mixed $value): void 'native_page_ranges' => $this->nativePageRanges($value), 'wait_delay' => $this->waitDelay($value), 'wait_for_expression' => $this->waitForExpression($value), - 'emulated_media_type' => $this->emulatedMediaType($value), + 'emulated_media_type' => $this->emulatedMediaType(EmulatedMediaType::from($value)), 'cookies' => $this->cookies($value), 'extra_http_headers' => $this->extraHttpHeaders($value), 'fail_on_http_status_codes' => $this->failOnHttpStatusCodes($value), diff --git a/src/Builder/Pdf/AbstractPdfBuilder.php b/src/Builder/Pdf/AbstractPdfBuilder.php index 089034c1..0803b9eb 100644 --- a/src/Builder/Pdf/AbstractPdfBuilder.php +++ b/src/Builder/Pdf/AbstractPdfBuilder.php @@ -51,7 +51,7 @@ public function __construct( return $this->encodeData('failOnHttpStatusCodes', $value); }, 'cookies' => function (mixed $value): array { - return $this->encodeData('cookies', \array_values($value)); + return $this->encodeData('cookies', array_values($value)); }, 'metadata' => function (mixed $value): array { return $this->encodeData('metadata', $value); @@ -164,12 +164,22 @@ private function addToMultipart(string $key, array|string|int|float|bool|DataPar ]]; } - if (\is_int($value) || \is_float($value)) { + if (\is_int($value)) { return [[ $key => (string) $value, ]]; } + if (\is_float($value)) { + [$left, $right] = sscanf((string) $value, '%d.%s') ?? [$value, '']; + + $right ??= '0'; + + return [[ + $key => "{$left}.{$right}", + ]]; + } + if (\is_array($value)) { $result = []; foreach ($value as $nestedValue) { diff --git a/src/Builder/Screenshot/AbstractScreenshotBuilder.php b/src/Builder/Screenshot/AbstractScreenshotBuilder.php index 53220903..0f528995 100644 --- a/src/Builder/Screenshot/AbstractScreenshotBuilder.php +++ b/src/Builder/Screenshot/AbstractScreenshotBuilder.php @@ -161,12 +161,22 @@ private function addToMultipart(string $key, array|string|int|float|bool|DataPar ]]; } - if (\is_int($value) || \is_float($value)) { + if (\is_int($value)) { return [[ $key => (string) $value, ]]; } + if (\is_float($value)) { + [$left, $right] = sscanf((string) $value, '%d.%s') ?? [$value, '']; + + $right ??= '0'; + + return [[ + $key => "{$left}.{$right}", + ]]; + } + if (\is_array($value)) { $result = []; foreach ($value as $nestedValue) { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index b1f7b1b6..dabe0c65 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -9,7 +9,6 @@ use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; -use function array_map; class Configuration implements ConfigurationInterface { @@ -205,7 +204,7 @@ private function addChromiumPdfOptionsNode(NodeBuilder $treeBuilder): void ->end() ->enumNode('emulated_media_type') ->info('The media type to emulate, either "screen" or "print" - default "print". https://gotenberg.dev/docs/routes#emulated-media-type') - ->values(array_map(static fn(EmulatedMediaType $case): string => $case->value, EmulatedMediaType::cases())) + ->values(\array_map(static fn (EmulatedMediaType $case): string => $case->value, EmulatedMediaType::cases())) ->defaultNull() ->end() ->arrayNode('cookies') @@ -274,7 +273,7 @@ private function addChromiumPdfOptionsNode(NodeBuilder $treeBuilder): void ->end() ->enumNode('pdf_format') ->info('Convert the resulting PDF into the given PDF/A format - default None. https://gotenberg.dev/docs/routes#pdfa-chromium') - ->values(array_map(static fn(PdfFormat $case): string => $case->value, PdfFormat::cases())) + ->values(\array_map(static fn (PdfFormat $case): string => $case->value, PdfFormat::cases())) ->defaultNull() ->end() ->booleanNode('pdf_universal_access') @@ -302,7 +301,7 @@ private function addChromiumScreenshotOptionsNode(NodeBuilder $treeBuilder): voi ->end() ->enumNode('format') ->info('The image compression format, either "png", "jpeg" or "webp" - default png. https://gotenberg.dev/docs/routes#screenshots-route') - ->values(array_map(static fn(ScreenshotFormat $case): string => $case->value, ScreenshotFormat::cases())) + ->values(\array_map(static fn (ScreenshotFormat $case): string => $case->value, ScreenshotFormat::cases())) ->defaultNull() ->end() ->integerNode('quality') @@ -341,7 +340,7 @@ private function addChromiumScreenshotOptionsNode(NodeBuilder $treeBuilder): voi ->end() ->enumNode('emulated_media_type') ->info('The media type to emulate, either "screen" or "print" - default "print". https://gotenberg.dev/docs/routes#emulated-media-type') - ->values(array_map(static fn(EmulatedMediaType $case): string => $case->value, EmulatedMediaType::cases())) + ->values(\array_map(static fn (EmulatedMediaType $case): string => $case->value, EmulatedMediaType::cases())) ->defaultNull() ->end() ->arrayNode('cookies') @@ -438,7 +437,7 @@ private function addPdfOfficeNode(): NodeDefinition ->end() ->enumNode('pdf_format') ->info('Convert the resulting PDF into the given PDF/A format - default None. https://gotenberg.dev/docs/routes#pdfa-chromium') - ->values(array_map(static fn(PdfFormat $case): string => $case->value, PdfFormat::cases())) + ->values(\array_map(static fn (PdfFormat $case): string => $case->value, PdfFormat::cases())) ->defaultNull() ->end() ->booleanNode('pdf_universal_access') diff --git a/src/Enum/PaperSize.php b/src/Enum/PaperSize.php index ed557f0a..5a442d88 100644 --- a/src/Enum/PaperSize.php +++ b/src/Enum/PaperSize.php @@ -19,34 +19,34 @@ enum PaperSize implements PaperSizeInterface public function width(): float { return match ($this) { - PaperSize::Letter => 8.5, - PaperSize::Legal => 8.5, - PaperSize::Tabloid => 11, - PaperSize::Ledger => 17, - PaperSize::A0 => 33.1, - PaperSize::A1 => 23.4, - PaperSize::A2 => 16.54, - PaperSize::A3 => 11.7, - PaperSize::A4 => 8.27, - PaperSize::A5 => 5.83, - PaperSize::A6 => 4.13, + self::Letter => 8.5, + self::Legal => 8.5, + self::Tabloid => 11, + self::Ledger => 17, + self::A0 => 33.1, + self::A1 => 23.4, + self::A2 => 16.54, + self::A3 => 11.7, + self::A4 => 8.27, + self::A5 => 5.83, + self::A6 => 4.13, }; } public function height(): float { return match ($this) { - PaperSize::Letter => 11, - PaperSize::Legal => 14, - PaperSize::Tabloid => 17, - PaperSize::Ledger => 11, - PaperSize::A0 => 46.8, - PaperSize::A1 => 33.1, - PaperSize::A2 => 23.4, - PaperSize::A3 => 16.54, - PaperSize::A4 => 11.7, - PaperSize::A5 => 8.27, - PaperSize::A6 => 5.83, + self::Letter => 11, + self::Legal => 14, + self::Tabloid => 17, + self::Ledger => 11, + self::A0 => 46.8, + self::A1 => 33.1, + self::A2 => 23.4, + self::A3 => 16.54, + self::A4 => 11.7, + self::A5 => 8.27, + self::A6 => 5.83, }; } diff --git a/src/Enum/Unit.php b/src/Enum/Unit.php index f7717a20..702a5cf0 100644 --- a/src/Enum/Unit.php +++ b/src/Enum/Unit.php @@ -1,7 +1,5 @@ gotenbergClient = $this->createMock(GotenbergClientInterface::class); + } + + /** + * @param array $data + */ + protected function assertFile(array $data, string $filename, string $expectedContent): void + { + self::assertArrayHasKey('files', $data); + + $file = $data['files']; + + self::assertInstanceOf(DataPart::class, $file); + + self::assertSame($expectedContent, $file->getBody()); + self::assertSame($filename, $file->getFilename()); } } diff --git a/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php b/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php new file mode 100644 index 00000000..eb345722 --- /dev/null +++ b/tests/Builder/Pdf/AbstractChromiumPdfBuilderTest.php @@ -0,0 +1,230 @@ + ['single_page', false, [ + 'singlePage' => 'false', + ]]; + yield 'pdf_format - A-1b' => ['pdf_format', 'PDF/A-1b', [ + 'pdfa' => 'PDF/A-1b', + ]]; + yield 'pdf_universal_access' => ['pdf_universal_access', false, [ + 'pdfua' => 'false', + ]]; + yield 'paper_width' => ['paper_width', 10.0, [ + 'paperWidth' => '10in', + ]]; + yield 'paper_height' => ['paper_height', 10.0, [ + 'paperHeight' => '10in', + ]]; + yield 'margin_top' => ['margin_top', 10.0, [ + 'marginTop' => '10in', + ]]; + yield 'margin_bottom' => ['margin_bottom', 10.0, [ + 'marginBottom' => '10in', + ]]; + yield 'margin_left' => ['margin_left', 10.0, [ + 'marginLeft' => '10in', + ]]; + yield 'margin_right' => ['margin_right', 10.0, [ + 'marginRight' => '10in', + ]]; + yield 'prefer_css_page_size' => ['prefer_css_page_size', false, [ + 'preferCssPageSize' => 'false', + ]]; + yield 'print_background' => ['print_background', false, [ + 'printBackground' => 'false', + ]]; + yield 'omit_background' => ['omit_background', false, [ + 'omitBackground' => 'false', + ]]; + yield 'landscape' => ['landscape', false, [ + 'landscape' => 'false', + ]]; + yield 'scale' => ['scale', 2.0, [ + 'scale' => '2.0', + ]]; + yield 'native_page_ranges' => ['native_page_ranges', '1-10', [ + 'nativePageRanges' => '1-10', + ]]; + yield 'wait_delay' => ['wait_delay', '3ms', [ + 'waitDelay' => '3ms', + ]]; + yield 'wait_for_expression' => ['wait_for_expression', "window.status === 'ready'", [ + 'waitForExpression' => "window.status === 'ready'", + ]]; + yield 'emulated_media_type' => ['emulated_media_type', 'screen', [ + 'emulatedMediaType' => 'screen', + ]]; + yield 'cookies' => ['cookies', [['name' => 'MyCookie', 'value' => 'raspberry']], [ + 'cookies' => '[{"name":"MyCookie","value":"raspberry"}]', + ]]; + yield 'extra_http_headers' => ['extra_http_headers', ['MyHeader' => 'SomeValue'], [ + 'extraHttpHeaders' => '{"MyHeader":"SomeValue"}', + ]]; + yield 'fail_on_http_status_codes' => ['fail_on_http_status_codes', [499, 500], [ + 'failOnHttpStatusCodes' => '[499,500]', + ]]; + yield 'fail_on_console_exceptions' => ['fail_on_console_exceptions', false, [ + 'failOnConsoleExceptions' => 'false', + ]]; + yield 'skip_network_idle_event' => ['skip_network_idle_event', false, [ + 'skipNetworkIdleEvent' => 'false', + ]]; + yield 'metadata' => ['metadata', ['Author' => 'SensioLabs'], [ + 'metadata' => '{"Author":"SensioLabs"}', + ]]; + } + + /** + * @param array $expected + */ + #[DataProvider('configurationIsCorrectlySetProvider')] + public function testConfigurationIsCorrectlySet(string $key, mixed $value, array $expected): void + { + $builder = $this->getChromiumPdfBuilder(); + $builder->setConfigurations([ + $key => $value, + ]); + + self::assertEquals($expected, $builder->getMultipartFormData()[0]); + } + + public function testPaperSizeAppliesWidthAndHeight(): void + { + $builder = $this->getChromiumPdfBuilder(); + $builder->paperSize(10.0, 50.5, Unit::Centimeters); + + self::assertEquals([ + ['paperWidth' => '10cm'], + ['paperHeight' => '50.5cm'], + ], $builder->getMultipartFormData()); + } + + public function testPaperStandardSizeAppliesCorrectly(): void + { + $paperStandardSize = new class() implements PaperSizeInterface { + public function width(): float + { + return 10.0; + } + + public function height(): float + { + return 50.5; + } + + public function unit(): Unit + { + return Unit::Pixels; + } + }; + + $builder = $this->getChromiumPdfBuilder(); + $builder->paperStandardSize($paperStandardSize); + + self::assertEquals([ + ['paperWidth' => '10px'], + ['paperHeight' => '50.5px'], + ], $builder->getMultipartFormData()); + } + + public function testMarginsAppliesCorrectly(): void + { + $builder = $this->getChromiumPdfBuilder(); + $builder->margins(1.1, 2.2, 3.3, 4.4, Unit::Picas); + + self::assertEquals([ + ['marginTop' => '1.1pc'], + ['marginBottom' => '2.2pc'], + ['marginLeft' => '3.3pc'], + ['marginRight' => '4.4pc'], + ], $builder->getMultipartFormData()); + } + + public function testPdfFormatCanBeReset(): void + { + $builder = $this->getChromiumPdfBuilder(); + $builder->pdfFormat(PdfFormat::Pdf1b); + + self::assertEquals([ + ['pdfa' => 'PDF/A-1b'], + ], $builder->getMultipartFormData()); + + $builder->pdfFormat(null); + + self::assertEquals([], $builder->getMultipartFormData()); + } + + public function testHeaderIsCorrectlyRendered(): void + { + $builder = $this->getChromiumPdfBuilder(); + $builder->header('templates/header.html.twig', ['name' => 'World']); + + $data = $builder->getMultipartFormData()[0]; + + $expected = << + + + + My Header + + +

Hello World!

+ + + + HTML; + + $this->assertFile($data, 'header.html', $expected); + } + + public function testThrowIfTwigNotAvailable(): void + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Twig is required to use "Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractChromiumPdfBuilder::withRenderedPart" method. Try to run "composer require symfony/twig-bundle".'); + + $builder = $this->getChromiumPdfBuilder(false); + $builder->header('header.html.twig', ['name' => 'World']); + } + + public function testThrowIfTwigTemplateIsInvalid(): void + { + $this->expectException(PdfPartRenderingException::class); + $this->expectExceptionMessage('Could not render template "templates/invalid.html.twig" into PDF part "header.html". Unexpected character "!".'); + + $builder = $this->getChromiumPdfBuilder(); + $builder->header('templates/invalid.html.twig'); + } + + private function getChromiumPdfBuilder(bool $twig = true): AbstractChromiumPdfBuilder + { + return new class($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null) extends AbstractChromiumPdfBuilder { + protected function getEndpoint(): string + { + return '/fake/endpoint'; + } + }; + } +} diff --git a/tests/Builder/Pdf/HtmlPdfBuilderTest.php b/tests/Builder/Pdf/HtmlPdfBuilderTest.php index 361eb7dd..36191626 100644 --- a/tests/Builder/Pdf/HtmlPdfBuilderTest.php +++ b/tests/Builder/Pdf/HtmlPdfBuilderTest.php @@ -3,224 +3,106 @@ namespace Sensiolabs\GotenbergBundle\Tests\Builder\Pdf; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\UsesClass; use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractChromiumPdfBuilder; use Sensiolabs\GotenbergBundle\Builder\Pdf\AbstractPdfBuilder; use Sensiolabs\GotenbergBundle\Builder\Pdf\HtmlPdfBuilder; -use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; -use Sensiolabs\GotenbergBundle\Enum\PaperSize; -use Sensiolabs\GotenbergBundle\Exception\JsonEncodingException; -use Sensiolabs\GotenbergBundle\Exception\PdfPartRenderingException; +use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Mime\Part\DataPart; #[CoversClass(HtmlPdfBuilder::class)] #[UsesClass(AbstractChromiumPdfBuilder::class)] #[UsesClass(AbstractPdfBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] -#[UsesClass(Filesystem::class)] -#[UsesClass(PaperSize::class)] final class HtmlPdfBuilderTest extends AbstractBuilderTestCase { - public function testWithConfigurations(): void + public function testEndpointIsCorrect(): void { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - $builder->setConfigurations(self::getUserConfig()); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(23, $multipartFormData); - - self::assertIsArray($multipartFormData[0]); - self::assertCount(1, $multipartFormData[0]); - self::assertArrayHasKey('files', $multipartFormData[0]); - self::assertInstanceOf(DataPart::class, $multipartFormData[0]['files']); - self::assertSame('index.html', $multipartFormData[0]['files']->getFilename()); - - self::assertSame(['paperWidth' => '33.1in'], $multipartFormData[1]); - self::assertSame(['paperHeight' => '46.8in'], $multipartFormData[2]); - self::assertSame(['marginTop' => '1in'], $multipartFormData[3]); - self::assertSame(['marginBottom' => '1in'], $multipartFormData[4]); - self::assertSame(['marginLeft' => '1in'], $multipartFormData[5]); - self::assertSame(['marginRight' => '1in'], $multipartFormData[6]); - self::assertSame(['preferCssPageSize' => 'true'], $multipartFormData[7]); - self::assertSame(['printBackground' => 'true'], $multipartFormData[8]); - self::assertSame(['omitBackground' => 'true'], $multipartFormData[9]); - self::assertSame(['landscape' => 'true'], $multipartFormData[10]); - self::assertSame(['scale' => '1.5'], $multipartFormData[11]); - self::assertSame(['nativePageRanges' => '1-5'], $multipartFormData[12]); - self::assertSame(['waitDelay' => '10s'], $multipartFormData[13]); - self::assertSame(['waitForExpression' => 'window.globalVar === "ready"'], $multipartFormData[14]); - self::assertSame(['emulatedMediaType' => 'screen'], $multipartFormData[15]); - self::assertSame(['cookies' => '[{"name":"cook_me","value":"sensio","domain":"sensiolabs.com","secure":true,"httpOnly":true,"sameSite":"Lax"},{"name":"yummy_cookie","value":"choco","domain":"example.com"}]'], $multipartFormData[16]); - self::assertSame(['extraHttpHeaders' => '{"MyHeader":"Value","User-Agent":"MyValue"}'], $multipartFormData[17]); - self::assertSame(['failOnHttpStatusCodes' => '[401,403]'], $multipartFormData[18]); - self::assertSame(['failOnConsoleExceptions' => 'true'], $multipartFormData[19]); - self::assertSame(['skipNetworkIdleEvent' => 'true'], $multipartFormData[20]); - self::assertSame(['pdfa' => 'PDF/A-1b'], $multipartFormData[21]); - self::assertSame(['pdfua' => 'true'], $multipartFormData[22]); + $this->gotenbergClient + ->expects($this->once()) + ->method('call') + ->with( + $this->equalTo('/forms/chromium/convert/html'), + $this->anything(), + $this->anything(), + ) + ; + $builder = $this->getHtmlPdfBuilder(); + $builder->contentFile('files/content.html'); + $builder->generate(); } - public function testWithTemplate(): void + public static function withPlainContentFileProvider(): \Generator { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter, self::$twig); - $builder->content('content.html.twig'); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(1, $multipartFormData); - self::assertArrayHasKey(0, $multipartFormData); - self::assertIsArray($multipartFormData[0]); - self::assertArrayHasKey('files', $multipartFormData[0]); - self::assertInstanceOf(DataPart::class, $multipartFormData[0]['files']); - self::assertSame('text/html', $multipartFormData[0]['files']->getContentType()); - } - - public function testWithAssets(): void - { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - $builder->assets('assets/logo.png'); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(2, $multipartFormData); - - self::assertArrayHasKey(1, $multipartFormData); - self::assertIsArray($multipartFormData[1]); - self::assertArrayHasKey('files', $multipartFormData[1]); - self::assertInstanceOf(DataPart::class, $multipartFormData[1]['files']); - self::assertSame('image/png', $multipartFormData[1]['files']->getContentType()); - } - - public function testWithPaperStandardSize(): void - { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - $builder->paperStandardSize(PaperSize::A3); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(3, $multipartFormData); - - self::assertArrayHasKey('paperWidth', $multipartFormData[1]); - self::assertArrayHasKey('paperHeight', $multipartFormData[2]); - - self::assertSame((string) PaperSize::A3->width().'in', $multipartFormData[1]['paperWidth']); - self::assertSame((string) PaperSize::A3->height().'in', $multipartFormData[2]['paperHeight']); + yield 'with twig' => [true]; + yield 'without twig' => [false]; } - public function testWithHeader(): void + #[DataProvider('withPlainContentFileProvider')] + public function testWithPlainContentFile(bool $withTwig): void { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter); - $builder->headerFile('header.html'); - $builder->contentFile('content.html'); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(2, $multipartFormData); - - self::assertArrayHasKey(1, $multipartFormData); - self::assertIsArray($multipartFormData[1]); - self::assertArrayHasKey('files', $multipartFormData[1]); - self::assertInstanceOf(DataPart::class, $multipartFormData[1]['files']); - self::assertSame('text/html', $multipartFormData[1]['files']->getContentType()); + $builder = $this->getHtmlPdfBuilder($withTwig); + $builder->contentFile('files/content.html'); + + $data = $builder->getMultipartFormData()[0]; + + $expected = << + + + + My PDF + + +

Hello world!

+ + + + + HTML; + + $this->assertFile($data, 'index.html', $expected); } - public function testInvalidTwigTemplate(): void + public function testWithTwigContentFile(): void { - $this->expectException(PdfPartRenderingException::class); - $this->expectExceptionMessage('Could not render template "invalid.html.twig" into PDF part "index.html".'); - - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter, self::$twig); - - $builder->content('invalid.html.twig'); + $builder = $this->getHtmlPdfBuilder(); + $builder->content('templates/content.html.twig', ['name' => 'world']); + + $data = $builder->getMultipartFormData()[0]; + + $expected = << + + + + My PDF + + +

Hello world!

+ + + + + HTML; + + $this->assertFile($data, 'index.html', $expected); } - public function testInvalidExtraHttpHeaders(): void + public function testRequiredFormData(): void { - $this->expectException(JsonEncodingException::class); - $this->expectExceptionMessage('Could not encode property "extraHttpHeaders" into JSON'); - - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); + $builder = $this->getHtmlPdfBuilder(); - $builder = new HtmlPdfBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - // @phpstan-ignore-next-line - $builder->extraHttpHeaders([ - 'invalid' => tmpfile(), - ]); + $this->expectException(MissingRequiredFieldException::class); + $this->expectExceptionMessage('Content is required'); $builder->getMultipartFormData(); } - /** - * @return array - */ - private static function getUserConfig(): array + private function getHtmlPdfBuilder(bool $twig = true): HtmlPdfBuilder { - return [ - 'paper_width' => 33.1, - 'paper_height' => 46.8, - 'margin_top' => 1, - 'margin_bottom' => 1, - 'margin_left' => 1, - 'margin_right' => 1, - 'prefer_css_page_size' => true, - 'print_background' => true, - 'omit_background' => true, - 'landscape' => true, - 'scale' => 1.5, - 'native_page_ranges' => '1-5', - 'wait_delay' => '10s', - 'wait_for_expression' => 'window.globalVar === "ready"', - 'emulated_media_type' => 'screen', - 'cookies' => [ - [ - 'name' => 'cook_me', - 'value' => 'sensio', - 'domain' => 'sensiolabs.com', - 'secure' => true, - 'httpOnly' => true, - 'sameSite' => 'Lax', - ], - [ - 'name' => 'yummy_cookie', - 'value' => 'choco', - 'domain' => 'example.com', - ], - ], - 'extra_http_headers' => [ - 'MyHeader' => 'Value', - 'User-Agent' => 'MyValue', - ], - 'fail_on_http_status_codes' => [401, 403], - 'fail_on_console_exceptions' => true, - 'skip_network_idle_event' => true, - 'pdf_format' => 'PDF/A-1b', - 'pdf_universal_access' => true, - ]; + return new HtmlPdfBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null); } } diff --git a/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php b/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php index adc73e56..f06852dc 100644 --- a/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/HtmlScreenshotBuilderTest.php @@ -3,181 +3,106 @@ namespace Sensiolabs\GotenbergBundle\Tests\Builder\Screenshot; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractChromiumScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractScreenshotBuilder; use Sensiolabs\GotenbergBundle\Builder\Screenshot\HtmlScreenshotBuilder; -use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; -use Sensiolabs\GotenbergBundle\Exception\JsonEncodingException; -use Sensiolabs\GotenbergBundle\Exception\ScreenshotPartRenderingException; +use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\Tests\Builder\AbstractBuilderTestCase; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Mime\Part\DataPart; #[CoversClass(HtmlScreenshotBuilder::class)] +#[UsesClass(AbstractScreenshotBuilder::class)] +#[UsesClass(AbstractChromiumScreenshotBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] -#[UsesClass(Filesystem::class)] final class HtmlScreenshotBuilderTest extends AbstractBuilderTestCase { - public function testWithConfigurations(): void + public function testEndpointIsCorrect(): void { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlScreenshotBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - $builder->setConfigurations(self::getUserScreenshotConfig()); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(16, $multipartFormData); - - self::assertIsArray($multipartFormData[0]); - self::assertCount(1, $multipartFormData[0]); - self::assertArrayHasKey('files', $multipartFormData[0]); - self::assertInstanceOf(DataPart::class, $multipartFormData[0]['files']); - self::assertSame('index.html', $multipartFormData[0]['files']->getFilename()); - - self::assertSame(['width' => '1000'], $multipartFormData[1]); - self::assertSame(['height' => '500'], $multipartFormData[2]); - self::assertSame(['clip' => 'true'], $multipartFormData[3]); - self::assertSame(['format' => 'jpeg'], $multipartFormData[4]); - self::assertSame(['quality' => '75'], $multipartFormData[5]); - self::assertSame(['omitBackground' => 'false'], $multipartFormData[6]); - self::assertSame(['optimizeForSpeed' => 'true'], $multipartFormData[7]); - self::assertSame(['waitDelay' => '5s'], $multipartFormData[8]); - self::assertSame(['waitForExpression' => 'window.globalVar === "ready"'], $multipartFormData[9]); - self::assertSame(['emulatedMediaType' => 'screen'], $multipartFormData[10]); - self::assertSame(['cookies' => '[{"name":"cook_me","value":"sensio","domain":"sensiolabs.com","secure":true,"httpOnly":true,"sameSite":"Lax"},{"name":"yummy_cookie","value":"choco","domain":"example.com"}]'], $multipartFormData[11]); - self::assertSame(['extraHttpHeaders' => '{"MyHeader":"MyValue","User-Agent":"MyValue"}'], $multipartFormData[12]); - self::assertSame(['failOnHttpStatusCodes' => '[401,403]'], $multipartFormData[13]); - self::assertSame(['failOnConsoleExceptions' => 'false'], $multipartFormData[14]); - self::assertSame(['skipNetworkIdleEvent' => 'true'], $multipartFormData[15]); + $this->gotenbergClient + ->expects($this->once()) + ->method('call') + ->with( + $this->equalTo('/forms/chromium/screenshot/html'), + $this->anything(), + $this->anything(), + ) + ; + $builder = $this->getHtmlScreenshotBuilder(); + $builder->contentFile('files/content.html'); + $builder->generate(); } - public function testWithTemplate(): void + public static function withPlainContentFileProvider(): \Generator { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlScreenshotBuilder($client, $assetBaseDirFormatter, self::$twig); - $builder->content('content.html.twig'); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(1, $multipartFormData); - self::assertArrayHasKey(0, $multipartFormData); - self::assertIsArray($multipartFormData[0]); - self::assertArrayHasKey('files', $multipartFormData[0]); - self::assertInstanceOf(DataPart::class, $multipartFormData[0]['files']); - self::assertSame('text/html', $multipartFormData[0]['files']->getContentType()); - } - - public function testWithAssets(): void - { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlScreenshotBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - $builder->assets('assets/logo.png'); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(2, $multipartFormData); - - self::assertArrayHasKey(1, $multipartFormData); - self::assertIsArray($multipartFormData[1]); - self::assertArrayHasKey('files', $multipartFormData[1]); - self::assertInstanceOf(DataPart::class, $multipartFormData[1]['files']); - self::assertSame('image/png', $multipartFormData[1]['files']->getContentType()); + yield 'with twig' => [true]; + yield 'without twig' => [false]; } - public function testWithHeader(): void + #[DataProvider('withPlainContentFileProvider')] + public function testWithPlainContentFile(bool $withTwig): void { - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlScreenshotBuilder($client, $assetBaseDirFormatter); - $builder->headerFile('header.html'); - $builder->contentFile('content.html'); - - $multipartFormData = $builder->getMultipartFormData(); - - self::assertCount(2, $multipartFormData); - - self::assertArrayHasKey(1, $multipartFormData); - self::assertIsArray($multipartFormData[1]); - self::assertArrayHasKey('files', $multipartFormData[1]); - self::assertInstanceOf(DataPart::class, $multipartFormData[1]['files']); - self::assertSame('text/html', $multipartFormData[1]['files']->getContentType()); + $builder = $this->getHtmlScreenshotBuilder($withTwig); + $builder->contentFile('files/content.html'); + + $data = $builder->getMultipartFormData()[0]; + + $expected = << + + + + My PDF + + +

Hello world!

+ + + + + HTML; + + $this->assertFile($data, 'index.html', $expected); } - public function testInvalidTwigTemplate(): void + public function testWithTwigContentFile(): void { - $this->expectException(ScreenshotPartRenderingException::class); - $this->expectExceptionMessage('Could not render template "invalid.html.twig" into PDF part "index.html".'); - - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); - - $builder = new HtmlScreenshotBuilder($client, $assetBaseDirFormatter, self::$twig); - - $builder->content('invalid.html.twig'); + $builder = $this->getHtmlScreenshotBuilder(); + $builder->content('templates/content.html.twig', ['name' => 'world']); + + $data = $builder->getMultipartFormData()[0]; + + $expected = << + + + + My PDF + + +

Hello world!

+ + + + + HTML; + + $this->assertFile($data, 'index.html', $expected); } - public function testInvalidExtraHttpHeaders(): void + public function testRequiredFormData(): void { - $this->expectException(JsonEncodingException::class); - $this->expectExceptionMessage('Could not encode property "extraHttpHeaders" into JSON'); - - $client = $this->createMock(GotenbergClientInterface::class); - $assetBaseDirFormatter = new AssetBaseDirFormatter(new Filesystem(), self::FIXTURE_DIR, self::FIXTURE_DIR); + $builder = $this->getHtmlScreenshotBuilder(); - $builder = new HtmlScreenshotBuilder($client, $assetBaseDirFormatter); - $builder->contentFile('content.html'); - // @phpstan-ignore-next-line - $builder->extraHttpHeaders([ - 'invalid' => tmpfile(), - ]); + $this->expectException(MissingRequiredFieldException::class); + $this->expectExceptionMessage('Content is required'); $builder->getMultipartFormData(); } - /** - * @return array - */ - private static function getUserScreenshotConfig(): array + private function getHtmlScreenshotBuilder(bool $twig = true): HtmlScreenshotBuilder { - return [ - 'width' => 1000, - 'height' => 500, - 'clip' => true, - 'format' => 'jpeg', - 'quality' => 75, - 'omit_background' => false, - 'optimize_for_speed' => true, - 'wait_delay' => '5s', - 'wait_for_expression' => 'window.globalVar === "ready"', - 'emulated_media_type' => 'screen', - 'cookies' => [ - [ - 'name' => 'cook_me', - 'value' => 'sensio', - 'domain' => 'sensiolabs.com', - 'secure' => true, - 'httpOnly' => true, - 'sameSite' => 'Lax', - ], - [ - 'name' => 'yummy_cookie', - 'value' => 'choco', - 'domain' => 'example.com', - ], - ], - 'extra_http_headers' => ['MyHeader' => 'MyValue', 'User-Agent' => 'MyValue'], - 'fail_on_http_status_codes' => [401, 403], - 'fail_on_console_exceptions' => false, - 'skip_network_idle_event' => true, - ]; + return new HtmlScreenshotBuilder($this->gotenbergClient, self::$assetBaseDirFormatter, true === $twig ? self::$twig : null); } } diff --git a/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php b/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php index aa146e5d..f366f33b 100644 --- a/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/MarkdownScreenshotBuilderTest.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractChromiumScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractScreenshotBuilder; use Sensiolabs\GotenbergBundle\Builder\Screenshot\MarkdownScreenshotBuilder; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -12,6 +14,8 @@ use Symfony\Component\Mime\Part\DataPart; #[CoversClass(MarkdownScreenshotBuilder::class)] +#[UsesClass(AbstractScreenshotBuilder::class)] +#[UsesClass(AbstractChromiumScreenshotBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] final class MarkdownScreenshotBuilderTest extends AbstractBuilderTestCase diff --git a/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php b/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php index 055433d0..9d4cd531 100644 --- a/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php +++ b/tests/Builder/Screenshot/UrlScreenshotBuilderTest.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractChromiumScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractScreenshotBuilder; use Sensiolabs\GotenbergBundle\Builder\Screenshot\UrlScreenshotBuilder; use Sensiolabs\GotenbergBundle\Client\GotenbergClientInterface; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; @@ -11,6 +13,8 @@ use Symfony\Component\Filesystem\Filesystem; #[CoversClass(UrlScreenshotBuilder::class)] +#[UsesClass(AbstractScreenshotBuilder::class)] +#[UsesClass(AbstractChromiumScreenshotBuilder::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] final class UrlScreenshotBuilderTest extends AbstractBuilderTestCase diff --git a/tests/Enum/PaperSizeTest.php b/tests/Enum/PaperSizeTest.php index fd3ed425..4769d168 100644 --- a/tests/Enum/PaperSizeTest.php +++ b/tests/Enum/PaperSizeTest.php @@ -5,10 +5,18 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Sensiolabs\GotenbergBundle\Enum\PaperSize; +use Sensiolabs\GotenbergBundle\Enum\Unit; #[CoversClass(PaperSize::class)] final class PaperSizeTest extends TestCase { + public function testUnitIsAlwaysInches(): void + { + foreach (PaperSize::cases() as $size) { + self::assertSame(Unit::Inches, $size->unit()); + } + } + public function testWidth(): void { foreach (PaperSize::cases() as $size) { diff --git a/tests/Enum/UnitTest.php b/tests/Enum/UnitTest.php new file mode 100644 index 00000000..7dc39ea1 --- /dev/null +++ b/tests/Enum/UnitTest.php @@ -0,0 +1,31 @@ + [12, [12.0, Unit::Inches]]; + yield '(string) 12' => ['12', [12.0, Unit::Inches]]; + yield '12.0' => [12.0, [12.0, Unit::Inches]]; + yield '12.1' => [12.1, [12.1, Unit::Inches]]; + yield '12.1in' => ['12.1in', [12.1, Unit::Inches]]; + yield '12.1pc' => ['12.1pc', [12.1, Unit::Picas]]; + } + + /** + * @param array{float, Unit} $expected + */ + #[DataProvider('itCanBeParsedCorrectlyProvider')] + public function testItCanBeParsedCorrectly(string|int|float $raw, array $expected): void + { + $this->assertSame($expected, Unit::parse($raw)); + } +} diff --git a/tests/Fixtures/templates/content.html.twig b/tests/Fixtures/templates/content.html.twig index b7988a6d..1493b0e8 100644 --- a/tests/Fixtures/templates/content.html.twig +++ b/tests/Fixtures/templates/content.html.twig @@ -5,7 +5,7 @@ My PDF -

Hello world!

+

Hello {{ name }}!

diff --git a/tests/Fixtures/templates/header.html.twig b/tests/Fixtures/templates/header.html.twig index 5927a11a..7d9c9136 100644 --- a/tests/Fixtures/templates/header.html.twig +++ b/tests/Fixtures/templates/header.html.twig @@ -5,6 +5,6 @@ My Header -

Hello Header!

+

Hello {{ name }}!

diff --git a/tests/GotenbergPdfTest.php b/tests/GotenbergPdfTest.php index e639319e..e9eda919 100644 --- a/tests/GotenbergPdfTest.php +++ b/tests/GotenbergPdfTest.php @@ -16,6 +16,7 @@ use Sensiolabs\GotenbergBundle\DependencyInjection\CompilerPass\GotenbergPass; use Sensiolabs\GotenbergBundle\DependencyInjection\Configuration; use Sensiolabs\GotenbergBundle\DependencyInjection\SensiolabsGotenbergExtension; +use Sensiolabs\GotenbergBundle\Enum\Unit; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\GotenbergPdf; use Sensiolabs\GotenbergBundle\GotenbergPdfInterface; @@ -40,6 +41,7 @@ #[UsesClass(Configuration::class)] #[UsesClass(SensiolabsGotenbergExtension::class)] #[UsesClass(SensiolabsGotenbergBundle::class)] +#[UsesClass(Unit::class)] final class GotenbergPdfTest extends KernelTestCase { public function testUrlBuilderFactory(): void diff --git a/tests/GotenbergScreenshotTest.php b/tests/GotenbergScreenshotTest.php index c9b99e2b..450f8c45 100644 --- a/tests/GotenbergScreenshotTest.php +++ b/tests/GotenbergScreenshotTest.php @@ -4,6 +4,12 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\UsesClass; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractChromiumScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\AbstractScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\HtmlScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\MarkdownScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Builder\Screenshot\UrlScreenshotBuilder; +use Sensiolabs\GotenbergBundle\Client\GotenbergClient; use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter; use Sensiolabs\GotenbergBundle\GotenbergScreenshot; use Sensiolabs\GotenbergBundle\GotenbergScreenshotInterface; @@ -12,6 +18,12 @@ use Symfony\Component\Mime\Part\DataPart; #[CoversClass(GotenbergScreenshot::class)] +#[UsesClass(AbstractScreenshotBuilder::class)] +#[UsesClass(AbstractChromiumScreenshotBuilder::class)] +#[UsesClass(HtmlScreenshotBuilder::class)] +#[UsesClass(MarkdownScreenshotBuilder::class)] +#[UsesClass(UrlScreenshotBuilder::class)] +#[UsesClass(GotenbergClient::class)] #[UsesClass(AssetBaseDirFormatter::class)] #[UsesClass(Filesystem::class)] final class GotenbergScreenshotTest extends KernelTestCase