Files
e-ticket/tests/Controller/AttestationControllerTest.php
Serreau Jovann 2ffb407323 Fix failing tests: AttestationController payload keys and StripeSyncCommand event mock
- AttestationControllerTest: add required template keys (ref, organizer,
  generatedAt, etc.) to test payloads so check_ventes.html.twig renders
- StripeSyncCommandTest: add getAccount() mock to event in
  testPendingOrderFailedWithoutEmail so order is not skipped

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

243 lines
8.1 KiB
PHP

<?php
namespace App\Tests\Controller;
use App\Controller\AttestationController;
use App\Entity\Attestation;
use App\Entity\Event;
use App\Entity\Payout;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class AttestationControllerTest extends WebTestCase
{
public function testCheckWithValidPayout(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = new User();
$user->setEmail('test-attest-'.uniqid().'@example.com');
$user->setFirstName('Test');
$user->setLastName('User');
$user->setPassword('$2y$13$hashed');
$em->persist($user);
$payout = new Payout();
$payout->setOrganizer($user);
$payout->setStripePayoutId('po_check_'.uniqid());
$payout->setStatus('paid');
$payout->setAmount(10000);
$payout->setCurrency('eur');
$em->persist($payout);
$em->flush();
$client->request('GET', '/attestation/check/'.$payout->getStripePayoutId());
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'Attestation authentique');
}
public function testCheckWithInvalidPayout(): void
{
$client = static::createClient();
$client->request('GET', '/attestation/check/po_fake_invalid');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'Attestation introuvable');
}
public function testVentesRefWithValidReference(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = new User();
$user->setEmail('test-vref-'.uniqid().'@example.com');
$user->setFirstName('Test');
$user->setLastName('User');
$user->setPassword('$2y$13$hashed');
$em->persist($user);
$event = new Event();
$event->setAccount($user);
$event->setTitle('Test Event');
$event->setStartAt(new \DateTimeImmutable('+1 day'));
$event->setEndAt(new \DateTimeImmutable('+2 days'));
$event->setAddress('123 Rue Test');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$reference = 'REF-'.uniqid();
$payload = [
'ref' => $reference,
'event' => 'Test Event',
'organizer' => 'Test User',
'generatedAt' => '01/04/2026 10:00:00',
'totalSold' => 10,
'billets' => [],
'categories' => [],
];
$attestation = new Attestation($reference, 'sig_'.uniqid(), $event, $user, 10, $payload);
$em->persist($attestation);
$em->flush();
$client->request('GET', '/attestation/ventes/r/'.$reference);
self::assertResponseIsSuccessful();
}
public function testVentesRefWithInvalidReference(): void
{
$client = static::createClient();
$client->request('GET', '/attestation/ventes/r/INVALID_REF');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'introuvable');
}
public function testVentesWithValidHash(): void
{
$client = static::createClient();
$appSecret = static::getContainer()->getParameter('kernel.secret');
$data = ['event' => 'Test Event', 'total' => 5000];
$hash = AttestationController::generateHash($data, $appSecret);
$client->request('GET', '/attestation/ventes/'.$hash);
self::assertResponseIsSuccessful();
}
public function testVentesWithValidHashAndRegisteredAttestation(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$appSecret = static::getContainer()->getParameter('kernel.secret');
$user = new User();
$user->setEmail('test-vreg-'.uniqid().'@example.com');
$user->setFirstName('Test');
$user->setLastName('User');
$user->setPassword('$2y$13$hashed');
$em->persist($user);
$event = new Event();
$event->setAccount($user);
$event->setTitle('Test Event');
$event->setStartAt(new \DateTimeImmutable('+1 day'));
$event->setEndAt(new \DateTimeImmutable('+2 days'));
$event->setAddress('123 Rue Test');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$ref = 'REF-'.uniqid();
$data = [
'ref' => $ref,
'event' => 'Registered Event',
'organizer' => 'Test User',
'generatedAt' => '01/04/2026 10:00:00',
'totalSold' => 20,
'billets' => [],
'categories' => [],
];
$json = json_encode($data, \JSON_UNESCAPED_UNICODE);
$signatureHash = hash_hmac('sha256', $json, $appSecret);
$attestation = new Attestation($ref, $signatureHash, $event, $user, 20, $data);
$em->persist($attestation);
$em->flush();
$hash = AttestationController::generateHash($data, $appSecret);
$client->request('GET', '/attestation/ventes/'.$hash);
self::assertResponseIsSuccessful();
}
public function testVentesWithInvalidBase64(): void
{
$client = static::createClient();
$client->request('GET', '/attestation/ventes/!!!invalid-base64!!!');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'introuvable');
}
public function testVentesWithMissingPipeSeparator(): void
{
$client = static::createClient();
$hash = rtrim(strtr(base64_encode('no-pipe-here'), '+/', '-_'), '=');
$client->request('GET', '/attestation/ventes/'.$hash);
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'introuvable');
}
public function testVentesWithInvalidSignature(): void
{
$client = static::createClient();
$json = json_encode(['event' => 'Test'], \JSON_UNESCAPED_UNICODE);
$hash = rtrim(strtr(base64_encode('invalidsignature|'.$json), '+/', '-_'), '=');
$client->request('GET', '/attestation/ventes/'.$hash);
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'introuvable');
}
public function testVentesWithInvalidJsonPayload(): void
{
$client = static::createClient();
$appSecret = static::getContainer()->getParameter('kernel.secret');
$invalidJson = '{invalid json}';
$signature = hash_hmac('sha256', $invalidJson, $appSecret);
$hash = rtrim(strtr(base64_encode($signature.'|'.$invalidJson), '+/', '-_'), '=');
$client->request('GET', '/attestation/ventes/'.$hash);
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'introuvable');
}
public function testGenerateHash(): void
{
$data = ['key' => 'value', 'amount' => 1000];
$secret = 'test-secret';
$hash = AttestationController::generateHash($data, $secret);
self::assertNotEmpty($hash);
self::assertMatchesRegularExpression('/^[A-Za-z0-9\-_]+$/', $hash);
$decoded = base64_decode(strtr($hash, '-_', '+/'), true);
self::assertNotFalse($decoded);
$parts = explode('|', $decoded, 2);
self::assertCount(2, $parts);
[$signature, $jsonPayload] = $parts;
$expectedSignature = hash_hmac('sha256', $jsonPayload, $secret);
self::assertTrue(hash_equals($expectedSignature, $signature));
self::assertSame($data, json_decode($jsonPayload, true));
}
public function testGenerateHashWithUnicodeData(): void
{
$data = ['name' => 'Événement été', 'city' => 'Zürich'];
$secret = 'test-secret';
$hash = AttestationController::generateHash($data, $secret);
$decoded = base64_decode(strtr($hash, '-_', '+/'), true);
$parts = explode('|', $decoded, 2);
self::assertStringContainsString('Événement été', $parts[1]);
self::assertStringContainsString('Zürich', $parts[1]);
}
}