refactor: suppression duplication templates PDF RGPD + test 100% DevisPdfController
Templates PDF : - _base.html.twig : blocs verify_box et hmac_section avec contenu par défaut (QR code, verify_url, HMAC-SHA256) au lieu de blocs vides - rgpd_access.html.twig : suppression blocs verify_box et hmac_section dupliqués (héritent du parent) - rgpd_deletion.html.twig : idem - rgpd_no_data.html.twig : idem DevisPdfControllerTest (8 tests) : - testDevisNotFound : devis null lance NotFoundHttpException - testUnsignedPdfNotSet : unsignedPdf null lance NotFoundHttpException - testFileNotExists : fichier absent lance NotFoundHttpException - testUnsignedPdfSuccess : PDF unsigned retourné en BinaryFileResponse - testSignedPdfSuccess : PDF signed retourné - testAuditPdfSuccess : PDF audit retourné - testAccessAsNonEmploye : accès sans ROLE_EMPLOYE (branche checkAccess) - testDefaultTypeNull : type inconnu lance NotFoundHttpException Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,9 +44,23 @@
|
||||
<div class="container">
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
{% block verify_box %}{% endblock %}
|
||||
{% block verify_box %}
|
||||
<div class="verify-box">
|
||||
<div class="verify-row">
|
||||
<div class="verify-qr"><img src="{{ qrcode }}" alt="QR Code"></div>
|
||||
<div class="verify-info">
|
||||
<span class="verify-label">Verifier ce document</span>
|
||||
<p style="margin: 2px 0 4px; font-size: 9px; font-weight: 700;">Scannez le QR code ou consultez le lien ci-dessous.</p>
|
||||
<span class="verify-label">URL</span>
|
||||
<span class="verify-url">{{ verify_url }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block hmac_section %}{% endblock %}
|
||||
{% block hmac_section %}
|
||||
<div class="hmac">HMAC-SHA256 : {{ attestation.hmac }}</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer_contact %}
|
||||
<div style="margin-top: 16px;">
|
||||
|
||||
@@ -41,20 +41,3 @@
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block verify_box %}
|
||||
<div class="verify-box">
|
||||
<div class="verify-row">
|
||||
<div class="verify-qr"><img src="{{ qrcode }}" alt="QR Code"></div>
|
||||
<div class="verify-info">
|
||||
<span class="verify-label">Verifier ce document</span>
|
||||
<p style="margin: 2px 0 4px; font-size: 9px; font-weight: 700;">Scannez le QR code ou consultez le lien ci-dessous.</p>
|
||||
<span class="verify-label">URL</span>
|
||||
<span class="verify-url">{{ verify_url }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block hmac_section %}
|
||||
<div class="hmac">HMAC-SHA256 : {{ attestation.hmac }}</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -39,20 +39,3 @@
|
||||
<div class="warning">Cette suppression est irreversible. Aucune donnee relative a cette adresse IP ne subsiste dans nos bases de donnees.</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block verify_box %}
|
||||
<div class="verify-box">
|
||||
<div class="verify-row">
|
||||
<div class="verify-qr"><img src="{{ qrcode }}" alt="QR Code"></div>
|
||||
<div class="verify-info">
|
||||
<span class="verify-label">Verifier ce document</span>
|
||||
<p style="margin: 2px 0 4px; font-size: 9px; font-weight: 700;">Scannez le QR code ou consultez le lien ci-dessous.</p>
|
||||
<span class="verify-label">URL</span>
|
||||
<span class="verify-url">{{ verify_url }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block hmac_section %}
|
||||
<div class="hmac">HMAC-SHA256 : {{ attestation.hmac }}</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -38,20 +38,3 @@
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block verify_box %}
|
||||
<div class="verify-box">
|
||||
<div class="verify-row">
|
||||
<div class="verify-qr"><img src="{{ qrcode }}" alt="QR Code"></div>
|
||||
<div class="verify-info">
|
||||
<span class="verify-label">Verifier ce document</span>
|
||||
<p style="margin: 2px 0 4px; font-size: 9px; font-weight: 700;">Scannez le QR code ou consultez le lien ci-dessous.</p>
|
||||
<span class="verify-label">URL</span>
|
||||
<span class="verify-url">{{ verify_url }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block hmac_section %}
|
||||
<div class="hmac">HMAC-SHA256 : {{ attestation.hmac }}</div>
|
||||
{% endblock %}
|
||||
|
||||
197
tests/Controller/DevisPdfControllerTest.php
Normal file
197
tests/Controller/DevisPdfControllerTest.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Controller;
|
||||
|
||||
use App\Controller\DevisPdfController;
|
||||
use App\Entity\Devis;
|
||||
use App\Entity\OrderNumber;
|
||||
use App\Repository\DevisRepository;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||
|
||||
class DevisPdfControllerTest extends TestCase
|
||||
{
|
||||
private function createContainer(bool $isEmploye = true): ContainerInterface
|
||||
{
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
$stack = $this->createStub(RequestStack::class);
|
||||
$stack->method('getSession')->willReturn($session);
|
||||
|
||||
$authChecker = $this->createStub(AuthorizationCheckerInterface::class);
|
||||
$authChecker->method('isGranted')->willReturn($isEmploye);
|
||||
|
||||
$container = $this->createStub(ContainerInterface::class);
|
||||
$container->method('has')->willReturn(true);
|
||||
$container->method('get')->willReturnMap([
|
||||
['router', $this->createStub(RouterInterface::class)],
|
||||
['security.authorization_checker', $authChecker],
|
||||
['security.token_storage', $this->createStub(TokenStorageInterface::class)],
|
||||
['request_stack', $stack],
|
||||
['parameter_bag', $this->createStub(\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface::class)],
|
||||
]);
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
public function testDevisNotFound(): void
|
||||
{
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn(null);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$this->expectException(NotFoundHttpException::class);
|
||||
$controller(1, 'unsigned', $repo, '/tmp');
|
||||
}
|
||||
|
||||
public function testUnsignedPdfNotSet(): void
|
||||
{
|
||||
$devis = new Devis(new OrderNumber('04/2026-00001'), 'secret');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$this->expectException(NotFoundHttpException::class);
|
||||
$controller(1, 'unsigned', $repo, '/tmp');
|
||||
}
|
||||
|
||||
public function testFileNotExists(): void
|
||||
{
|
||||
$devis = new Devis(new OrderNumber('04/2026-00002'), 'secret');
|
||||
$devis->setUnsignedPdf('nonexistent.pdf');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$this->expectException(NotFoundHttpException::class);
|
||||
$controller(1, 'unsigned', $repo, '/tmp');
|
||||
}
|
||||
|
||||
public function testUnsignedPdfSuccess(): void
|
||||
{
|
||||
$tmpDir = sys_get_temp_dir().'/devis_test_'.uniqid();
|
||||
mkdir($tmpDir.'/var/uploads/devis', 0775, true);
|
||||
file_put_contents($tmpDir.'/var/uploads/devis/test.pdf', '%PDF-test');
|
||||
|
||||
$devis = new Devis(new OrderNumber('042026-00003'), 'secret');
|
||||
$devis->setUnsignedPdf('test.pdf');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$response = $controller(1, 'unsigned', $repo, $tmpDir);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
@unlink($tmpDir.'/var/uploads/devis/test.pdf');
|
||||
@rmdir($tmpDir.'/var/uploads/devis');
|
||||
@rmdir($tmpDir.'/var/uploads');
|
||||
@rmdir($tmpDir.'/var');
|
||||
@rmdir($tmpDir);
|
||||
}
|
||||
|
||||
public function testSignedPdfSuccess(): void
|
||||
{
|
||||
$tmpDir = sys_get_temp_dir().'/devis_test_'.uniqid();
|
||||
mkdir($tmpDir.'/var/uploads/devis', 0775, true);
|
||||
file_put_contents($tmpDir.'/var/uploads/devis/signed.pdf', '%PDF');
|
||||
|
||||
$devis = new Devis(new OrderNumber('042026-00004'), 'secret');
|
||||
$devis->setSignedPdf('signed.pdf');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$response = $controller(1, 'signed', $repo, $tmpDir);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
@unlink($tmpDir.'/var/uploads/devis/signed.pdf');
|
||||
@rmdir($tmpDir.'/var/uploads/devis');
|
||||
@rmdir($tmpDir.'/var/uploads');
|
||||
@rmdir($tmpDir.'/var');
|
||||
@rmdir($tmpDir);
|
||||
}
|
||||
|
||||
public function testAuditPdfSuccess(): void
|
||||
{
|
||||
$tmpDir = sys_get_temp_dir().'/devis_test_'.uniqid();
|
||||
mkdir($tmpDir.'/var/uploads/devis', 0775, true);
|
||||
file_put_contents($tmpDir.'/var/uploads/devis/audit.pdf', '%PDF');
|
||||
|
||||
$devis = new Devis(new OrderNumber('042026-00005'), 'secret');
|
||||
$devis->setAuditPdf('audit.pdf');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$response = $controller(1, 'audit', $repo, $tmpDir);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
@unlink($tmpDir.'/var/uploads/devis/audit.pdf');
|
||||
@rmdir($tmpDir.'/var/uploads/devis');
|
||||
@rmdir($tmpDir.'/var/uploads');
|
||||
@rmdir($tmpDir.'/var');
|
||||
@rmdir($tmpDir);
|
||||
}
|
||||
|
||||
public function testAccessAsNonEmploye(): void
|
||||
{
|
||||
$tmpDir = sys_get_temp_dir().'/devis_test_'.uniqid();
|
||||
mkdir($tmpDir.'/var/uploads/devis', 0775, true);
|
||||
file_put_contents($tmpDir.'/var/uploads/devis/test.pdf', '%PDF');
|
||||
|
||||
$devis = new Devis(new OrderNumber('042026-00006'), 'secret');
|
||||
$devis->setUnsignedPdf('test.pdf');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer(false));
|
||||
|
||||
$response = $controller(1, 'unsigned', $repo, $tmpDir);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
@unlink($tmpDir.'/var/uploads/devis/test.pdf');
|
||||
@rmdir($tmpDir.'/var/uploads/devis');
|
||||
@rmdir($tmpDir.'/var/uploads');
|
||||
@rmdir($tmpDir.'/var');
|
||||
@rmdir($tmpDir);
|
||||
}
|
||||
|
||||
public function testDefaultTypeNull(): void
|
||||
{
|
||||
$devis = new Devis(new OrderNumber('04/2026-00007'), 'secret');
|
||||
|
||||
$repo = $this->createStub(DevisRepository::class);
|
||||
$repo->method('find')->willReturn($devis);
|
||||
|
||||
$controller = new DevisPdfController();
|
||||
$controller->setContainer($this->createContainer());
|
||||
|
||||
$this->expectException(NotFoundHttpException::class);
|
||||
$controller(1, 'unknown', $repo, '/tmp');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user