Files
crm_ecosplay/tests/Service/Pdf/RapportFinancierPdfTest.php
Serreau Jovann 79c55ba0f9 test: ajout 163 tests unitaires (668->831) avec couverture 73%
Entites (76 tests) :
- PrestataireTest : constructeur, setters, getFullAddress, getTotalPaidHt
- FacturePrestataireTest : constructeur, getPeriodLabel 12 mois, Vich upload
- AdvertPaymentTest : constructeur, types constants, method
- AdvertEventTest : constructeur, getTypeLabel, 5 types + fallback
- FactureLineTest : constructeur, setters, optionnels nullable
- ActionLogTest : constructeur, 10 action constants, severity
- PaymentReminderTest : 8 steps, getStepLabel, getSeverity
- DocusealEventTest : constructeur, nullable fields

Commands (16 tests) :
- ReminderFacturesPrestataireCommandTest : 6 scenarios (aucun presta,
  tous OK, factures manquantes, SIRET vide, mois different)
- PaymentReminderCommandTest : 10 scenarios (skip recent, J+15 emails,
  suspension, termination, exception handling)

Services PDF (24 tests) :
- ComptaPdfTest : empty/FEC/multi-page, totaux Debit/Credit
- RapportFinancierPdfTest : recettes/depenses, bilan equilibre/deficit/excedent
- FacturePdfTest : lignes, TVA, customer address, paid badge, multi-page

Controllers (47 tests) :
- ComptabiliteControllerTest : 18 tests (index, 7 exports CSV, 2 JSON,
  4 PDF, 2 rapport financier)
- PrestatairesControllerTest : 19 tests (CRUD, factures, SIRET proxy)
- FactureControllerTest : 6 tests (search, send)
- FactureVerifyControllerTest : 4 tests (HMAC valid/invalid/not found)

Couverture : 51%->60% classes, 58%->73% methodes

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

170 lines
5.0 KiB
PHP

<?php
namespace App\Tests\Service\Pdf;
use App\Service\Pdf\RapportFinancierPdf;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\KernelInterface;
class RapportFinancierPdfTest extends TestCase
{
private KernelInterface $kernel;
private string $projectDir;
protected function setUp(): void
{
$this->projectDir = sys_get_temp_dir().'/rapport-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 $from = '01/01/2026', string $to = '31/12/2026'): RapportFinancierPdf
{
return new RapportFinancierPdf($this->kernel, $from, $to);
}
public function testGenerateEmptyDataProducesValidPdf(): void
{
$pdf = $this->makePdf();
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithRecettesAndDepensesProducesValidPdf(): void
{
$pdf = $this->makePdf();
$pdf->setData(
[
'Hebergement Web' => 1200.00,
'Noms de domaine' => 350.00,
'Messagerie' => 480.00,
],
[
'Serveur dedie' => 600.00,
'Registrar' => 200.00,
'Divers' => 50.00,
],
);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithPositiveBilanProducesValidPdf(): void
{
$pdf = $this->makePdf();
// Recettes > Depenses => excedent/equilibre
$pdf->setData(
['Service A' => 5000.00, 'Service B' => 3000.00],
['Depense 1' => 1000.00],
);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
$this->assertGreaterThan(1000, \strlen($output));
}
public function testGenerateWithDeficitProducesValidPdf(): void
{
$pdf = $this->makePdf();
// Depenses > Recettes => deficit
$pdf->setData(
['Petite recette' => 100.00],
['Grosse depense' => 9999.00],
);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithExcedentLabelProducesValidPdf(): void
{
$pdf = $this->makePdf();
// Marge > 30% of recettes => 'EXCEDENT'
$recettes = ['Service' => 10000.00];
$depenses = ['Depense' => 1000.00]; // 9000 marge > 3000 (30%)
$pdf->setData($recettes, $depenses);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithLogoFileProducesValidPdf(): void
{
// Minimal valid 1x1 JPEG
$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->setData(['Service' => 500.00], ['Charge' => 200.00]);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithManyRecettesAndDepenses(): void
{
$recettes = [];
$depenses = [];
for ($i = 1; $i <= 20; ++$i) {
$recettes['Recette '.$i] = $i * 100.0;
$depenses['Depense '.$i] = $i * 50.0;
}
$pdf = $this->makePdf('01/01/2025', '31/12/2025');
$pdf->setData($recettes, $depenses);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
public function testGenerateWithZeroTotalsEquilibre(): void
{
$pdf = $this->makePdf();
// Both zero => marge = 0, isPositif = true, but marge (0) <= recettes*0.3 (0) => 'EQUILIBRE'
$pdf->setData([], []);
$pdf->generate();
$output = $pdf->Output('S');
$this->assertStringStartsWith('%PDF', $output);
}
}