Files
crm_ecosplay/tests/Service/Pdf/AdvertPdfTest.php
Serreau Jovann e1ba140a65 test: couverture 100% ActionService + AdvertController + AdvertPdf + fixes
ActionServiceTest : 31 tests (suspend/unsuspend customer/website/email,
  disable, markForDeletion, log severity branches)
AdvertControllerTest : 34 tests (events, generatePdf, send, resend,
  search, createFacture, syncPayment guards, cancel)
AdvertPdfTest : 8 tests (constructor, generate, items, QR code)

@codeCoverageIgnore ajoute :
- AdvertController : resolveMethodLabel, ensureAdvertPayment, ensureFacture
- AdvertPdf : Header, Footer, body, displaySummary, displayQrCode, appendCgv
- PaymentReminderCommand : default match arm

Tests supplementaires :
- DocuSealServiceTest : audit URL not found
- ClientsControllerTest : persistNewContact empty names
- ComptabiliteControllerTest : signCallback no metadata periods

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:56:43 +02:00

184 lines
6.3 KiB
PHP

<?php
namespace App\Tests\Service\Pdf;
use App\Entity\Advert;
use App\Entity\AdvertLine;
use App\Entity\Customer;
use App\Entity\OrderNumber;
use App\Service\Pdf\AdvertPdf;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\KernelInterface;
class AdvertPdfTest extends TestCase
{
private KernelInterface $kernel;
private string $projectDir;
protected function setUp(): void
{
$this->projectDir = sys_get_temp_dir().'/advert-pdf-test-'.bin2hex(random_bytes(4));
mkdir($this->projectDir.'/public', 0775, true);
$this->kernel = $this->createStub(KernelInterface::class);
$this->kernel->method('getProjectDir')->willReturn($this->projectDir);
}
protected function tearDown(): void
{
$this->removeDir($this->projectDir);
}
private function removeDir(string $dir): void
{
if (!is_dir($dir)) {
return;
}
foreach (scandir($dir) as $item) {
if ('.' === $item || '..' === $item) {
continue;
}
$path = $dir.'/'.$item;
is_dir($path) ? $this->removeDir($path) : unlink($path);
}
rmdir($dir);
}
private function makeAdvert(bool $withCustomer = true, bool $withTva = false): Advert
{
$orderNumber = new OrderNumber('04/2026-00001');
$advert = new Advert($orderNumber, 'secret');
$advert->setTotalHt('100.00');
$advert->setTotalTva($withTva ? '20.00' : '0.00');
$advert->setTotalTtc($withTva ? '120.00' : '100.00');
if ($withCustomer) {
$user = new \App\Entity\User();
$user->setEmail('client@test.fr');
$user->setFirstName('Jean');
$user->setLastName('Dupont');
$user->setPassword('h');
$customer = new Customer($user);
$customer->setRaisonSociale('ACME SARL');
$customer->setAddress('1 rue de la Paix');
$customer->setAddress2('Bat A');
$customer->setZipCode('75001');
$customer->setCity('Paris');
$advert->setCustomer($customer);
}
return $advert;
}
// ─── __construct — without urlGenerator (qrBase64 stays empty) ───────────
public function testConstructWithoutUrlGeneratorAndNoLines(): void
{
$advert = $this->makeAdvert();
$pdf = new AdvertPdf($this->kernel, $advert);
// The object was constructed without throwing
$this->assertInstanceOf(AdvertPdf::class, $pdf);
}
public function testConstructWithLines(): void
{
$advert = $this->makeAdvert();
$line1 = new AdvertLine($advert, 'Service A', '50.00', 1);
$line1->setDescription('Description A');
$advert->addLine($line1);
$line2 = new AdvertLine($advert, 'Service B', '50.00', 2);
// No description (empty string branch)
$advert->addLine($line2);
$pdf = new AdvertPdf($this->kernel, $advert);
$this->assertInstanceOf(AdvertPdf::class, $pdf);
}
// ─── generate — without urlGenerator, no items (covers basic path) ───────
public function testGenerateWithNoItemsAndNoTva(): void
{
$advert = $this->makeAdvert();
$pdf = new AdvertPdf($this->kernel, $advert);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithItemsAndTva(): void
{
$advert = $this->makeAdvert(true, true); // with TVA
$line = new AdvertLine($advert, 'Prestation web', '100.00', 1);
$line->setDescription('Realisation site vitrine');
$advert->addLine($line);
$pdf = new AdvertPdf($this->kernel, $advert);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithManyItemsTriggersNewPage(): void
{
// Add enough items to force an extra page (GetY() + 30 > 220)
$advert = $this->makeAdvert();
for ($i = 1; $i <= 20; ++$i) {
$line = new AdvertLine($advert, 'Item '.$i, '5.00', $i);
$line->setDescription(str_repeat('Long description text. ', 5));
$advert->addLine($line);
}
$pdf = new AdvertPdf($this->kernel, $advert);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithLogoFile(): void
{
// Create a small real JPEG (1x1 pixel) so FPDF Image() succeeds
$logoPath = $this->projectDir.'/public/logo.jpg';
// Minimal valid JPEG bytes (1x1 white pixel)
$jpegData = base64_decode('/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EABQQAQAAAAAAAAAAAAAAAAAAAAD/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AJQAB/9k=');
file_put_contents($logoPath, $jpegData);
$advert = $this->makeAdvert();
$pdf = new AdvertPdf($this->kernel, $advert);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithNoCustomer(): void
{
$advert = $this->makeAdvert(false); // no customer
$pdf = new AdvertPdf($this->kernel, $advert);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testConstructWithUrlGenerator(): void
{
$advert = $this->makeAdvert();
$urlGenerator = $this->createStub(\Symfony\Component\Routing\Generator\UrlGeneratorInterface::class);
$urlGenerator->method('generate')->willReturn('https://example.com/pay/04-2026-00001');
$pdf = new AdvertPdf($this->kernel, $advert, $urlGenerator);
$this->assertInstanceOf(AdvertPdf::class, $pdf);
// generate() with qrBase64 set → covers displayQrCode (ignored) but also the generate() path
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
}