Files
Starseed/tests/Module/Logistique/Api/WeighingTicketPrintApiTest.php
T
tristan 36149dd521 feat(back) : bon de pesée PDF via template Twig (ERP-192)
Endpoint API Platform GET /api/weighing_tickets/{id}/print.pdf (provider
renvoyant un binaire, pas de controller) sécurisé par
logistique.weighing_tickets.view. Rendu d'un template Twig hydraté avec le
ticket converti en PDF via Dompdf. Reproduit le modèle fourni : en-tête fixe
(logo + identité société, indépendant du site), pesées à vide/plein avec le
numéro de pesée affiché comme un DSD, poids net = plein − vide.
2026-06-24 10:01:49 +02:00

74 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Module\Logistique\Api;
/**
* Tests fonctionnels de l'impression du bon de pesee PDF (M5, spec-back § 2.12 /
* § 4.6 — RG-5.08, ERP-192) : operation `GET /api/weighing_tickets/{id}/print.pdf`.
*
* Couvre la verification du ticket :
* - 200 + PDF non vide (Content-Type application/pdf, disposition inline,
* signature %PDF) pour un ticket existant et visible ;
* - 403 sans la permission `logistique.weighing_tickets.view` ;
* - 404 pour un ticket inexistant.
*
* @internal
*/
final class WeighingTicketPrintApiTest extends AbstractWeighingTicketApiTestCase
{
public function testPrintReturnsNonEmptyPdfForExistingTicket(): void
{
$site = $this->firstSite();
$http = $this->authManageOnSite($site);
$client = $this->seedTestClient('Print');
$created = $this->postTicket($http, $this->validClientTicketPayload($client));
self::assertResponseStatusCodeSame(201);
$ticketId = $created->toArray()['id'];
$response = $http->request('GET', sprintf('/api/weighing_tickets/%d/print.pdf', $ticketId));
self::assertResponseIsSuccessful();
$headers = $response->getHeaders(false);
self::assertStringContainsString('application/pdf', $headers['content-type'][0] ?? '');
self::assertStringContainsString('inline', $headers['content-disposition'][0] ?? '');
// PDF non vide + signature de fichier PDF (« %PDF-1.x »).
$binary = $response->getContent(false);
self::assertNotSame('', $binary, 'Le PDF du bon de pesée ne doit pas être vide.');
self::assertStringStartsWith('%PDF', $binary);
}
public function testForbiddenWithoutViewPermission(): void
{
// On seede un ticket reel via un user habilite, puis on tente l'impression
// avec un user depourvu de `logistique.weighing_tickets.view`.
$site = $this->firstSite();
$manager = $this->authManageOnSite($site);
$client = $this->seedTestClient('Forbidden');
$created = $this->postTicket($manager, $this->validClientTicketPayload($client));
self::assertResponseStatusCodeSame(201);
$ticketId = $created->toArray()['id'];
$creds = $this->createUserWithPermission('core.users.view');
$intrus = $this->authenticatedClient($creds['username'], $creds['password']);
$intrus->request('GET', sprintf('/api/weighing_tickets/%d/print.pdf', $ticketId));
self::assertResponseStatusCodeSame(403);
}
public function testNotFoundForUnknownTicket(): void
{
$http = $this->authManageOnSite($this->firstSite());
$http->request('GET', '/api/weighing_tickets/99999999/print.pdf');
self::assertResponseStatusCodeSame(404);
}
}