Files
crm_ecosplay/tests/Service/Pdf/ComptaPdfTest.php
Serreau Jovann 8bda02888c test: couverture 83% methodes (1046 tests, 2135 assertions)
Entites completes a 100% :
- AdvertTest : 12 nouveaux (state, customer, totals, hmac, lines, payments)
- CustomerTest : 3 nouveaux (isPendingDelete, revendeurCode, updatedAt)
- DevisTest : 6 nouveaux (customer, submissionId, lines, state constants)
- FactureTest : 10 nouveaux (state, totals, isPaid, lines, hmac, splitIndex)
- OrderNumberTest : 1 nouveau (markAsUnused)
- WebsiteTest : 1 nouveau (revendeurCode)

Services completes/ameliores :
- DocuSealServiceTest : 30 nouveaux (sendDevis, resendDevis, download, compta)
- AdvertServiceTest : 6 nouveaux (isTvaEnabled, getTvaRate, computeTotals)
- DevisServiceTest : 6 nouveaux (idem)
- FactureServiceTest : 8 nouveaux (idem + createPaidFactureFromAdvert)
- MailerServiceTest : 7 nouveaux (unsubscribe headers, VCF, formatFileSize)
- MeilisearchServiceTest : 42 nouveaux (index/remove/search tous types)
- RgpdServiceTest : 6 nouveaux (sendVerificationCode, verifyCode)
- OrderNumberServiceTest : 2 nouveaux (preview/generate unused)
- TarificationServiceTest : 1 nouveau (stripe error logger)
- ComptaPdfTest : 4 nouveaux (totaux, colonnes numeriques, signature)
- FacturePdfTest : 6 nouveaux (QR code, RIB, CGV Twig, footer skip)

Controllers ameliores :
- ComptabiliteControllerTest : 13 nouveaux (JSON, PDF, sign, callback)
- StatsControllerTest : 2 nouveaux (rich data, 6-month evolution)
- SyncControllerTest : 13 nouveaux (sync 6 types + purge)
- ClientsControllerTest : 7 nouveaux (show, delete, resendWelcome)
- FactureControllerTest : 2 nouveaux (generatePdf 404, send success)
- LegalControllerTest : 6 nouveaux (rgpdVerify GET/POST)
- TarificationControllerTest : 3 nouveaux (purge paths)
- AdminControllersTest : 9 nouveaux (dashboard search, services)
- WebhookStripeControllerTest : 3 nouveaux (invalid signatures)
- KeycloakAuthenticatorTest : 4 nouveaux (groups, domain check)

Commands :
- PaymentReminderCommandTest : 1 nouveau (formalNotice step)
- TestMailCommandTest : 2 nouveaux (force-dsn success/failure)

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

233 lines
7.2 KiB
PHP

<?php
namespace App\Tests\Service\Pdf;
use App\Service\Pdf\ComptaPdf;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\KernelInterface;
class ComptaPdfTest extends TestCase
{
private KernelInterface $kernel;
private string $projectDir;
protected function setUp(): void
{
$this->projectDir = sys_get_temp_dir().'/compta-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 makePdf(string $title = 'Journal des ventes', string $from = '01/01/2026', string $to = '31/03/2026'): ComptaPdf
{
return new ComptaPdf($this->kernel, $title, $from, $to);
}
public function testGenerateEmptyDataProducesValidPdf(): void
{
$pdf = $this->makePdf();
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithRowsProducesValidPdf(): void
{
$pdf = $this->makePdf('Journal des ventes');
$pdf->setData([
[
'JournalCode' => 'VTE',
'JournalLib' => 'Ventes',
'EcritureNum' => 'E001',
'EcritureDate' => '01/01/2026',
'CompteNum' => '411000',
'CompteLib' => 'Clients',
'Debit' => '100.00',
'Credit' => '0.00',
'EcritureLib' => 'Facture 001',
],
[
'JournalCode' => 'VTE',
'JournalLib' => 'Ventes',
'EcritureNum' => 'E002',
'EcritureDate' => '15/01/2026',
'CompteNum' => '706000',
'CompteLib' => 'Prestations',
'Debit' => '0.00',
'Credit' => '100.00',
'EcritureLib' => 'Facture 001',
],
]);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithDebitCreditSummarised(): void
{
$pdf = $this->makePdf('Grand Livre');
$pdf->setData([
['Debit' => '200.00', 'Credit' => '50.00', 'EcritureLib' => 'Test'],
['Debit' => '300.00', 'Credit' => '100.00', 'EcritureLib' => 'Test2'],
]);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
// The PDF should contain total text; check binary content for encoded values
$this->assertGreaterThan(1000, \strlen($output));
}
public function testGenerateWithUnknownColumnsDistributesWidth(): void
{
$pdf = $this->makePdf('Rapport custom');
$pdf->setData([
['ColA' => 'Valeur1', 'ColB' => 'Valeur2', 'ColC' => '42.00'],
['ColA' => 'Valeur3', 'ColB' => 'Valeur4', 'ColC' => '99.00'],
]);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithLogoFile(): void
{
// Create a minimal valid JPEG file in the project public dir
// We use a 1x1 white JPEG for testing
$jpegData = base64_decode('/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EABQQAQAAAAAAAAAAAAAAAAAAAAD/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AJQAB/9k=');
file_put_contents($this->projectDir.'/public/logo.jpg', $jpegData);
$pdf = $this->makePdf();
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testSetDataWithEmptyRowsGeneratesNoDataMessage(): void
{
$pdf = $this->makePdf();
$pdf->setData([]);
$pdf->generate();
$output = $pdf->Output('S');
// Should still produce a valid PDF even with empty data
$this->assertStringStartsWith('%PDF', $output);
}
public function testMultiplePagesWithManyRows(): void
{
$rows = [];
for ($i = 1; $i <= 100; ++$i) {
$rows[] = [
'JournalCode' => 'VTE',
'JournalLib' => 'Ventes',
'EcritureNum' => 'E'.str_pad((string) $i, 4, '0', STR_PAD_LEFT),
'EcritureDate' => '01/01/2026',
'CompteNum' => '411000',
'CompteLib' => 'Clients',
'Debit' => number_format($i * 10.5, 2),
'Credit' => '0.00',
'EcritureLib' => 'Ligne '.$i,
];
}
$pdf = $this->makePdf('Export FEC');
$pdf->setData($rows);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithMontantHtColumn(): void
{
// Covers the 'MontantHT' totals path in writeSummary (grand livre / balance)
$pdf = $this->makePdf('Grand Livre');
$pdf->setData([
['MontantHT' => '100.00', 'MontantTVA' => '20.00', 'MontantTTC' => '120.00', 'EcritureLib' => 'Test'],
]);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithAllNumericColumns(): void
{
// Covers isNumericColumn for: Solde, MontantDevise, Montantdevise, JoursRetard
$pdf = $this->makePdf('Balance');
$pdf->setData([
[
'Debit' => '500.00',
'Credit' => '200.00',
'Solde' => '300.00',
'MontantDevise' => '300.00',
'Montantdevise' => '300.00',
'JoursRetard' => '5',
'EcritureLib' => 'Test',
],
]);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateSignatureBlockNearPageBottom(): void
{
// Creates many rows so the signature block needs a new page
$rows = [];
for ($i = 1; $i <= 60; ++$i) {
$rows[] = [
'JournalCode' => 'VTE',
'EcritureLib' => 'Ligne '.$i,
'Debit' => '0.00',
'Credit' => '0.00',
];
}
$pdf = $this->makePdf('Grand Livre');
$pdf->setData($rows);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
}