Files
e-ticket/tests/Controller/AccountControllerTest.php
Serreau Jovann bc4601eb5c aa
2026-03-23 15:44:20 +01:00

2212 lines
78 KiB
PHP

<?php
namespace App\Tests\Controller;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class AccountControllerTest extends WebTestCase
{
public function testAccountRedirectsWhenNotAuthenticated(): void
{
$client = static::createClient();
$client->request('GET', '/mon-compte');
self::assertResponseRedirects();
}
public function testEventQrCodeAccessAndResponse(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
// 1. Setup Organizer and their Event
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$event->setSlug('test-event-slug');
$em->flush();
// 2. Authenticate
$client->loginUser($user);
// 3. Request the QR Code
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/qrcode');
// 4. Assertions for Successful Response
self::assertResponseIsSuccessful();
self::assertResponseHeaderSame('Content-Type', 'image/png');
self::assertResponseHeaderSame(
'Content-Disposition',
'attachment; filename="qrcode-test-event-slug.png"'
);
// 5. Verify the content is a valid PNG binary (Magic numbers: \x89PNG)
$content = $client->getResponse()->getContent();
self::assertStringStartsWith("\x89PNG", $content);
}
public function testEventQrCodeDeniedForOtherOrganizer(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/qrcode');
// Access denied because the event belongs to $owner, not $other
self::assertResponseStatusCodeSame(403);
}
public function testEventQrCodeDeniedForSimpleUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$simpleUser = $this->createUser(['ROLE_USER'], false);
$event = $this->createEvent($em, $owner);
$client->loginUser($simpleUser);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/qrcode');
// Denied because ROLE_ORGANIZER is required
self::assertResponseStatusCodeSame(403);
}
public function testAccountReturnsSuccessWhenAuthenticated(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('GET', '/mon-compte');
self::assertResponseIsSuccessful();
}
public function testAccountTicketsTab(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=tickets');
self::assertResponseIsSuccessful();
}
public function testAccountTicketsTabWithTickets(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setUser($user);
$order->setFirstName($user->getFirstName());
$order->setLastName($user->getLastName());
$order->setEmail($user->getEmail());
$order->setOrderNumber('2026-03-21-'.random_int(10000, 99999));
$order->setTotalHT(1000);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$item = new \App\Entity\BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName('Test Billet');
$item->setQuantity(1);
$item->setUnitPriceHT(1000);
$order->addItem($item);
$em->persist($order);
$em->flush();
$ticket = new \App\Entity\BilletOrder();
$ticket->setBilletBuyer($order);
$ticket->setBillet($billet);
$ticket->setBilletName('Test Billet');
$ticket->setUnitPriceHT(1000);
$em->persist($ticket);
$em->flush();
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=tickets');
self::assertResponseIsSuccessful();
}
public function testAccountPurchasesTab(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=purchases');
self::assertResponseIsSuccessful();
}
public function testAccountInvoicesTab(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=invoices');
self::assertResponseIsSuccessful();
}
public function testAccountSettingsTab(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=settings');
self::assertResponseIsSuccessful();
}
public function testAccountSettingsSubmit(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('POST', '/mon-compte/parametres', [
'first_name' => 'Updated',
'last_name' => 'Name',
'email' => $user->getEmail(),
'phone' => '0699887766',
'address' => '1 rue Test',
'postal_code' => '75001',
'city' => 'Paris',
]);
self::assertResponseRedirects('/mon-compte?tab=settings');
}
public function testOrganizerEventsTab(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=events');
self::assertResponseIsSuccessful();
}
public function testOrganizerSubaccountsTab(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=subaccounts');
self::assertResponseIsSuccessful();
}
public function testOrganizerPayoutsTab(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=payouts');
self::assertResponseIsSuccessful();
}
public function testOrganizerSettingsDisablesNameFields(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('POST', '/mon-compte/parametres', [
'email' => $user->getEmail(),
'phone' => '0699887766',
]);
self::assertResponseRedirects('/mon-compte?tab=settings');
}
public function testOrganizerNotApprovedShowsBlockingMessage(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], false);
$client->loginUser($user);
$client->request('GET', '/mon-compte');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'en cours de validation');
}
public function testOrganizerDefaultTabIsEvents(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte');
self::assertResponseIsSuccessful();
}
public function testStripeConnectRedirectsForNonOrganizer(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('POST', '/mon-compte/stripe-connect');
self::assertResponseRedirects('/mon-compte');
}
public function testOrganizerWithoutStripeShowsSetupMessage(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$crawler = $client->request('GET', '/mon-compte');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'Configuration Stripe requise');
}
public function testOrganizerWithStripePendingShowsMessage(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$user->setStripeAccountId('acct_pending');
$em->flush();
$client->loginUser($user);
$crawler = $client->request('GET', '/mon-compte');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'en cours de verification');
}
public function testOrganizerWithStripeActiveShowsSuccess(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$user->setStripeAccountId('acct_active');
$user->setStripeChargesEnabled(true);
$user->setStripePayoutsEnabled(true);
$em->flush();
$client->loginUser($user);
$crawler = $client->request('GET', '/mon-compte');
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'Stripe Connect actif');
}
public function testStripeConnectReturn(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/stripe/connect/return');
self::assertResponseRedirects('/mon-compte');
}
public function testStripeConnectRefresh(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/stripe/connect/refresh');
self::assertResponseRedirects('/mon-compte/stripe-connect');
}
public function testStripeCancelResetsAccount(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$user->setStripeAccountId('acct_cancel');
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/stripe-cancel');
self::assertResponseRedirects('/mon-compte');
$em->refresh($user);
self::assertNull($user->getStripeAccountId());
}
public function testCreateSubAccountDeniedForNonOrganizer(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('POST', '/mon-compte/sous-compte/creer', [
'first_name' => 'Sub',
'last_name' => 'Test',
'email' => 'sub-denied-'.uniqid().'@example.com',
]);
self::assertResponseRedirects('/mon-compte');
}
public function testEditSubAccountDeniedForWrongOrganizer(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$orga1 = $this->createUser(['ROLE_ORGANIZER'], true);
$orga2 = $this->createUser(['ROLE_ORGANIZER'], true);
$sub = new User();
$sub->setEmail('sub-wrong-'.uniqid().'@example.com');
$sub->setFirstName('Sub');
$sub->setLastName('Wrong');
$sub->setPassword('$2y$13$hashed');
$sub->setParentOrganizer($orga1);
$em->persist($sub);
$em->flush();
$client->loginUser($orga2);
$client->request('GET', '/mon-compte/sous-compte/'.$sub->getId());
self::assertResponseStatusCodeSame(403);
}
public function testEditSubAccountSubmitDeniedForWrongOrganizer(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$orga1 = $this->createUser(['ROLE_ORGANIZER'], true);
$orga2 = $this->createUser(['ROLE_ORGANIZER'], true);
$sub = new User();
$sub->setEmail('sub-wrong2-'.uniqid().'@example.com');
$sub->setFirstName('Sub');
$sub->setLastName('Wrong2');
$sub->setPassword('$2y$13$hashed');
$sub->setParentOrganizer($orga1);
$em->persist($sub);
$em->flush();
$client->loginUser($orga2);
$client->request('POST', '/mon-compte/sous-compte/'.$sub->getId().'/modifier', [
'first_name' => 'Hack',
'last_name' => 'Attempt',
'email' => $sub->getEmail(),
'permissions' => ['scanner'],
]);
self::assertResponseStatusCodeSame(403);
}
public function testDeleteSubAccountDeniedForWrongOrganizer(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$orga1 = $this->createUser(['ROLE_ORGANIZER'], true);
$orga2 = $this->createUser(['ROLE_ORGANIZER'], true);
$sub = new User();
$sub->setEmail('sub-wrong3-'.uniqid().'@example.com');
$sub->setFirstName('Sub');
$sub->setLastName('Wrong3');
$sub->setPassword('$2y$13$hashed');
$sub->setParentOrganizer($orga1);
$em->persist($sub);
$em->flush();
$client->loginUser($orga2);
$client->request('POST', '/mon-compte/sous-compte/'.$sub->getId().'/supprimer');
self::assertResponseStatusCodeSame(403);
}
public function testCreateSubAccount(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$mailer = $this->createMock(\App\Service\MailerService::class);
$mailer->expects(self::once())->method('sendEmail');
static::getContainer()->set(\App\Service\MailerService::class, $mailer);
$client->loginUser($user);
$client->request('POST', '/mon-compte/sous-compte/creer', [
'first_name' => 'Sub',
'last_name' => 'Account',
'email' => 'sub-'.uniqid().'@example.com',
'permissions' => ['scanner', 'events'],
]);
self::assertResponseRedirects('/mon-compte?tab=subaccounts');
}
public function testEditSubAccountPage(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$sub = new User();
$sub->setEmail('sub-edit-'.uniqid().'@example.com');
$sub->setFirstName('Sub');
$sub->setLastName('Edit');
$sub->setPassword('$2y$13$hashed');
$sub->setParentOrganizer($user);
$sub->setSubAccountPermissions(['scanner']);
$em->persist($sub);
$em->flush();
$client->loginUser($user);
$client->request('GET', '/mon-compte/sous-compte/'.$sub->getId());
self::assertResponseIsSuccessful();
}
public function testEditSubAccountSubmit(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$sub = new User();
$sub->setEmail('sub-submit-'.uniqid().'@example.com');
$sub->setFirstName('Sub');
$sub->setLastName('Submit');
$sub->setPassword('$2y$13$hashed');
$sub->setParentOrganizer($user);
$sub->setSubAccountPermissions(['scanner']);
$em->persist($sub);
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/sous-compte/'.$sub->getId().'/modifier', [
'first_name' => 'Updated',
'last_name' => 'Name',
'email' => $sub->getEmail(),
'permissions' => ['scanner', 'events', 'tickets'],
]);
self::assertResponseRedirects('/mon-compte?tab=subaccounts');
$em->refresh($sub);
self::assertSame('Updated', $sub->getFirstName());
self::assertSame(['scanner', 'events', 'tickets'], $sub->getSubAccountPermissions());
}
public function testDeleteSubAccount(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$sub = new User();
$sub->setEmail('sub-del-'.uniqid().'@example.com');
$sub->setFirstName('Sub');
$sub->setLastName('Delete');
$sub->setPassword('$2y$13$hashed');
$sub->setParentOrganizer($user);
$em->persist($sub);
$em->flush();
$subId = $sub->getId();
$client->loginUser($user);
$client->request('POST', '/mon-compte/sous-compte/'.$subId.'/supprimer');
self::assertResponseRedirects('/mon-compte?tab=subaccounts');
self::assertNull($em->getRepository(User::class)->find($subId));
}
public function testOrganizerSettingsWithLogoUpload(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$logoFile = new \Symfony\Component\HttpFoundation\File\UploadedFile(
__DIR__.'/../../public/logo.png',
'logo.png',
'image/png',
null,
true,
);
$client->request('POST', '/mon-compte/parametres', [
'email' => $user->getEmail(),
'phone' => '0699887766',
], ['logo' => $logoFile]);
self::assertResponseRedirects('/mon-compte?tab=settings');
$em->refresh($user);
self::assertNotNull($user->getLogoName());
}
public function testCreateEventPageRequiresOrganizer(): void
{
$client = static::createClient();
$user = $this->createUser();
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/creer');
self::assertResponseStatusCodeSame(403);
}
public function testCreateEventPageReturnsSuccess(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/creer');
self::assertResponseIsSuccessful();
}
public function testCreateEventSubmit(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/creer', [
'title' => 'Convention Test',
'description' => 'Un super evenement',
'start_at' => '2026-07-01T10:00',
'end_at' => '2026-07-01T18:00',
'address' => '42 rue de Saint-Quentin',
'zipcode' => '02800',
'city' => 'Beautor',
]);
self::assertResponseRedirects('/mon-compte?tab=events');
$freshEm = static::getContainer()->get(EntityManagerInterface::class);
$event = $freshEm->getRepository(\App\Entity\Event::class)->findOneBy(['title' => 'Convention Test']);
self::assertNotNull($event);
self::assertSame('Un super evenement', $event->getDescription());
self::assertSame('Beautor', $event->getCity());
}
public function testEditEventPageReturnsSuccess(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('Edit Test');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue test');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier');
self::assertResponseIsSuccessful();
}
public function testEditEventSubmit(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('Before Edit');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue test');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/modifier', [
'title' => 'After Edit',
'description' => 'Nouvelle description',
'start_at' => '2026-09-01T10:00',
'end_at' => '2026-09-01T18:00',
'address' => '2 rue modif',
'zipcode' => '69001',
'city' => 'Lyon',
'is_online' => '1',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier');
}
public function testEditEventDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($owner);
$event->setTitle('Owner Event');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($other);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier');
self::assertResponseStatusCodeSame(403);
}
public function testDeleteEvent(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('To Delete');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$eventId = $event->getId();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$eventId.'/supprimer');
self::assertResponseRedirects('/mon-compte?tab=events');
}
public function testToggleEventOnline(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$user->setStripeChargesEnabled(true);
$user->setStripePayoutsEnabled(true);
$em->flush();
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('Toggle Online');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/en-ligne');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier');
}
public function testToggleEventOnlineBlockedWithoutStripe(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('No Stripe');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/en-ligne');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier');
}
public function testToggleEventSecret(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('Toggle Secret');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/secret');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier');
}
public function testCreateEventWithPicture(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$picture = new \Symfony\Component\HttpFoundation\File\UploadedFile(
__DIR__.'/../../public/logo.png',
'affiche.png',
'image/png',
null,
true,
);
$client->request('POST', '/mon-compte/evenement/creer', [
'title' => 'Event With Picture',
'description' => 'Description',
'start_at' => '2026-09-01T10:00',
'end_at' => '2026-09-01T18:00',
'address' => '1 rue test',
'zipcode' => '75001',
'city' => 'Paris',
], ['event_main_picture' => $picture]);
self::assertResponseRedirects();
}
public function testEditEventWithPicture(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('Edit With Pic');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($user);
$picture = new \Symfony\Component\HttpFoundation\File\UploadedFile(
__DIR__.'/../../public/logo.png',
'affiche.png',
'image/png',
null,
true,
);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/modifier', [
'title' => 'Edited With Pic',
'description' => 'New desc',
'start_at' => '2026-09-01T10:00',
'end_at' => '2026-09-01T18:00',
'address' => '2 rue',
'zipcode' => '69001',
'city' => 'Lyon',
], ['event_main_picture' => $picture]);
self::assertResponseRedirects();
}
public function testEventsSearchReturnsSuccess(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=events&q=brocante');
self::assertResponseIsSuccessful();
}
public function testToggleOnlineDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($owner);
$event->setTitle('Toggle Denied');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/en-ligne');
self::assertResponseStatusCodeSame(403);
}
public function testToggleSecretDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($owner);
$event->setTitle('Secret Denied');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/secret');
self::assertResponseStatusCodeSame(403);
}
public function testDeleteEventDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = new \App\Entity\Event();
$event->setAccount($owner);
$event->setTitle('Delete Denied');
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/supprimer');
self::assertResponseStatusCodeSame(403);
}
public function testAddCategory(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/ajouter', [
'name' => 'VIP',
'start_at' => '2026-06-01T10:00',
'end_at' => '2026-07-31T18:00',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
}
public function testAddCategoryEmptyName(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/ajouter', [
'name' => '',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
}
public function testAddCategoryDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/ajouter', [
'name' => 'Hack',
]);
self::assertResponseStatusCodeSame(403);
}
public function testAddCategoryWithInvertedDates(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/ajouter', [
'name' => 'Inverted',
'start_at' => '2026-08-01T10:00',
'end_at' => '2026-06-01T10:00',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
$category = $em->getRepository(\App\Entity\Category::class)->findOneBy(['name' => 'Inverted']);
self::assertNotNull($category);
self::assertGreaterThanOrEqual($category->getStartAt(), $category->getEndAt());
}
public function testEditCategoryPage(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/modifier');
self::assertResponseIsSuccessful();
}
public function testEditCategorySubmit(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/modifier', [
'name' => 'Updated Name',
'start_at' => '2026-06-01T10:00',
'end_at' => '2026-07-31T18:00',
'is_hidden' => '1',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
$em->refresh($category);
self::assertSame('Updated Name', $category->getName());
self::assertTrue($category->isHidden());
}
public function testEditCategoryWithInvertedDates(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/modifier', [
'name' => 'Inverted Edit',
'start_at' => '2026-08-01T10:00',
'end_at' => '2026-06-01T10:00',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
$em->refresh($category);
self::assertGreaterThanOrEqual($category->getStartAt(), $category->getEndAt());
}
public function testEditCategoryDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$category = $this->createCategory($em, $event);
$client->loginUser($other);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/modifier');
self::assertResponseStatusCodeSame(403);
}
public function testEditCategoryNotFound(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/categorie/999999/modifier');
self::assertResponseStatusCodeSame(404);
}
public function testDeleteCategory(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$categoryId = $category->getId();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$categoryId.'/supprimer');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
self::assertNull($em->getRepository(\App\Entity\Category::class)->find($categoryId));
}
public function testDeleteCategoryDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$category = $this->createCategory($em, $event);
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/supprimer');
self::assertResponseStatusCodeSame(403);
}
public function testReorderCategories(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$cat1 = $this->createCategory($em, $event, 'Cat A', 0);
$cat2 = $this->createCategory($em, $event, 'Cat B', 1);
$client->loginUser($user);
$client->request(
'POST',
'/mon-compte/evenement/'.$event->getId().'/categorie/reorder',
[],
[],
['CONTENT_TYPE' => 'application/json'],
json_encode([$cat2->getId(), $cat1->getId()])
);
self::assertResponseIsSuccessful();
$em->refresh($cat1);
$em->refresh($cat2);
self::assertSame(1, $cat1->getPosition());
self::assertSame(0, $cat2->getPosition());
}
public function testReorderCategoriesDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request(
'POST',
'/mon-compte/evenement/'.$event->getId().'/categorie/reorder',
[],
[],
['CONTENT_TYPE' => 'application/json'],
'[]'
);
self::assertResponseStatusCodeSame(403);
}
public function testEditEventCategoriesTab(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$this->createBillet($em, $category);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
self::assertResponseIsSuccessful();
}
public function testEditEventStatsTab(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=stats');
self::assertResponseIsSuccessful();
}
public function testEditEventStatsTabWithOrders(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('Jean');
$order->setLastName('Dupont');
$order->setEmail('jean@test.fr');
$order->setOrderNumber('2026-03-21-'.random_int(1000, 9999));
$order->setTotalHT(1500);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$order->setPaidAt(new \DateTimeImmutable());
$item = new \App\Entity\BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName('Test');
$item->setQuantity(2);
$item->setUnitPriceHT(750);
$order->addItem($item);
$em->persist($order);
$em->flush();
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=stats');
self::assertResponseIsSuccessful();
}
public function testEditEventStatsTabWithSearch(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=stats&q=dupont');
self::assertResponseIsSuccessful();
}
public function testAddBilletPage(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/billet/ajouter');
self::assertResponseIsSuccessful();
}
public function testAddBilletSubmit(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/billet/ajouter', [
'name' => 'Entree VIP',
'price_ht' => '15.00',
'is_generated_billet' => '1',
'description' => 'Acces backstage',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
$billet = $em->getRepository(\App\Entity\Billet::class)->findOneBy(['name' => 'Entree VIP']);
self::assertNotNull($billet);
self::assertSame(1500, $billet->getPriceHT());
self::assertTrue($billet->isGeneratedBillet());
self::assertSame('Acces backstage', $billet->getDescription());
}
public function testAddBilletDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$category = $this->createCategory($em, $event);
$client->loginUser($other);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/billet/ajouter');
self::assertResponseStatusCodeSame(403);
}
public function testAddBilletCategoryNotFound(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/categorie/999999/billet/ajouter');
self::assertResponseStatusCodeSame(404);
}
public function testEditBilletPage(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/billet/'.$billet->getId().'/modifier');
self::assertResponseIsSuccessful();
}
public function testEditBilletSubmit(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet/'.$billet->getId().'/modifier', [
'name' => 'Entree Premium',
'price_ht' => '25.00',
'is_generated_billet' => '1',
'description' => 'Acces VIP',
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
$em->refresh($billet);
self::assertSame('Entree Premium', $billet->getName());
self::assertSame(2500, $billet->getPriceHT());
}
public function testEditBilletDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$client->loginUser($other);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/billet/'.$billet->getId().'/modifier');
self::assertResponseStatusCodeSame(403);
}
public function testEditBilletNotFound(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/billet/999999/modifier');
self::assertResponseStatusCodeSame(404);
}
public function testDeleteBillet(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$billetId = $billet->getId();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet/'.$billetId.'/supprimer');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=categories');
self::assertNull($em->getRepository(\App\Entity\Billet::class)->find($billetId));
}
public function testDeleteBilletDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet/'.$billet->getId().'/supprimer');
self::assertResponseStatusCodeSame(403);
}
public function testDeleteBilletNotFound(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet/999999/supprimer');
self::assertResponseStatusCodeSame(404);
}
public function testBilletPreview(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/billet-preview');
self::assertResponseIsSuccessful();
}
public function testBilletPreviewDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/billet-preview');
self::assertResponseStatusCodeSame(403);
}
public function testSaveBilletDesign(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet-design', [
'accent_color' => '#ff0000',
'invitation_title' => 'VIP',
'invitation_color' => '#00ff00',
]);
self::assertResponseIsSuccessful();
$design = $em->getRepository(\App\Entity\BilletDesign::class)->findOneBy(['event' => $event]);
self::assertNotNull($design);
self::assertSame('#ff0000', $design->getAccentColor());
self::assertSame('VIP', $design->getInvitationTitle());
}
public function testSaveBilletDesignUpdatesExisting(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$design = new \App\Entity\BilletDesign();
$design->setEvent($event);
$em->persist($design);
$em->flush();
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet-design', [
'accent_color' => '#aabbcc',
'invitation_title' => 'Pass',
'invitation_color' => '#112233',
]);
self::assertResponseIsSuccessful();
$em->refresh($design);
self::assertSame('#aabbcc', $design->getAccentColor());
self::assertSame('Pass', $design->getInvitationTitle());
}
public function testSaveBilletDesignDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet-design', [
'accent_color' => '#ff0000',
]);
self::assertResponseStatusCodeSame(403);
}
public function testReorderBillets(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$b1 = $this->createBillet($em, $category, 'B1', 1000);
$b2 = $this->createBillet($em, $category, 'B2', 2000);
$client->loginUser($user);
$client->request(
'POST',
'/mon-compte/evenement/'.$event->getId().'/billet/reorder',
[],
[],
['CONTENT_TYPE' => 'application/json'],
json_encode([$b2->getId(), $b1->getId()])
);
self::assertResponseIsSuccessful();
$em->refresh($b1);
$em->refresh($b2);
self::assertSame(1, $b1->getPosition());
self::assertSame(0, $b2->getPosition());
}
public function testReorderBilletsDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request(
'POST',
'/mon-compte/evenement/'.$event->getId().'/billet/reorder',
[],
[],
['CONTENT_TYPE' => 'application/json'],
'[]'
);
self::assertResponseStatusCodeSame(403);
}
public function testAddBilletWithPicture(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$picture = new \Symfony\Component\HttpFoundation\File\UploadedFile(
__DIR__.'/../../public/logo.png',
'billet.png',
'image/png',
null,
true,
);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/billet/ajouter', [
'name' => 'With Picture',
'price_ht' => '10.00',
'is_generated_billet' => '1',
], ['picture' => $picture]);
self::assertResponseRedirects();
}
public function testEditBilletWithPicture(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$picture = new \Symfony\Component\HttpFoundation\File\UploadedFile(
__DIR__.'/../../public/logo.png',
'billet.png',
'image/png',
null,
true,
);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/billet/'.$billet->getId().'/modifier', [
'name' => 'Updated With Pic',
'price_ht' => '20.00',
'is_generated_billet' => '1',
], ['picture' => $picture]);
self::assertResponseRedirects();
}
public function testCreateInvitation(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$billetOrderService = $this->createMock(\App\Service\BilletOrderService::class);
$billetOrderService->expects(self::once())->method('generateOrderTickets')->willReturnCallback(function (\App\Entity\BilletBuyer $order) use ($em, $billet) {
$ticket = new \App\Entity\BilletOrder();
$ticket->setBilletBuyer($order);
$ticket->setBillet($billet);
$ticket->setBilletName('Entree');
$ticket->setUnitPriceHT(0);
$em->persist($ticket);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$order->setPaidAt(new \DateTimeImmutable());
$em->flush();
});
$billetOrderService->expects(self::once())->method('generateAndSendTickets');
static::getContainer()->set(\App\Service\BilletOrderService::class, $billetOrderService);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation', [
'first_name' => 'Jean',
'last_name' => 'Invite',
'email' => 'invite@test.fr',
'items' => [
['billet_id' => $billet->getId(), 'quantity' => 2],
],
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=invitations');
$tickets = $em->getRepository(\App\Entity\BilletOrder::class)->findBy(['billet' => $billet]);
$lastTicket = end($tickets);
self::assertTrue($lastTicket->isInvitation());
}
public function testCreateInvitationMultipleBillets(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet1 = $this->createBillet($em, $category, 'VIP', 2000);
$billet2 = $this->createBillet($em, $category, 'Standard', 1000);
$billetOrderService = $this->createMock(\App\Service\BilletOrderService::class);
$billetOrderService->expects(self::once())->method('generateOrderTickets');
$billetOrderService->expects(self::once())->method('generateAndSendTickets');
static::getContainer()->set(\App\Service\BilletOrderService::class, $billetOrderService);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation', [
'first_name' => 'Marie',
'last_name' => 'Double',
'email' => 'marie@test.fr',
'items' => [
['billet_id' => $billet1->getId(), 'quantity' => 1],
['billet_id' => $billet2->getId(), 'quantity' => 3],
],
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=invitations');
}
public function testCreateInvitationEmptyFields(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation', [
'first_name' => '',
'last_name' => '',
'email' => '',
'items' => [],
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=invitations');
}
public function testCreateInvitationInvalidBillet(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation', [
'first_name' => 'Jean',
'last_name' => 'Test',
'email' => 'jean@test.fr',
'items' => [
['billet_id' => 999999, 'quantity' => 1],
],
]);
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=invitations');
}
public function testCreateInvitationDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation', [
'first_name' => 'Hack',
'last_name' => 'Test',
'email' => 'hack@test.fr',
'items' => [],
]);
self::assertResponseStatusCodeSame(403);
}
public function testEditEventInvitationsTab(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=invitations');
self::assertResponseIsSuccessful();
}
public function testResendInvitation(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('Invite');
$order->setLastName('Test');
$order->setEmail('invite@test.fr');
$order->setOrderNumber('2026-03-21-'.random_int(100, 999));
$order->setTotalHT(0);
$order->setIsInvitation(true);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$em->persist($order);
$em->flush();
$billetOrderService = $this->createMock(\App\Service\BilletOrderService::class);
$billetOrderService->expects(self::once())->method('generateAndSendTickets');
static::getContainer()->set(\App\Service\BilletOrderService::class, $billetOrderService);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation/'.$order->getId().'/renvoyer');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=invitations');
}
public function testResendInvitationDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('Test');
$order->setLastName('Test');
$order->setEmail('test@test.fr');
$order->setOrderNumber('2026-03-21-'.random_int(100, 999));
$order->setTotalHT(0);
$order->setIsInvitation(true);
$em->persist($order);
$em->flush();
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation/'.$order->getId().'/renvoyer');
self::assertResponseStatusCodeSame(403);
}
public function testResendInvitationNotFound(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/invitation/999999/renvoyer');
self::assertResponseStatusCodeSame(404);
}
public function testCancelOrder(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('Jean');
$order->setLastName('Dupont');
$order->setEmail('jean@test.fr');
$order->setOrderNumber('2026-03-21-'.random_int(100, 999));
$order->setTotalHT(1000);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$item = new \App\Entity\BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName('Test');
$item->setQuantity(1);
$item->setUnitPriceHT(1000);
$order->addItem($item);
$em->persist($order);
$em->flush();
$ticket = new \App\Entity\BilletOrder();
$ticket->setBilletBuyer($order);
$ticket->setBillet($billet);
$ticket->setBilletName('Test');
$ticket->setUnitPriceHT(1000);
$em->persist($ticket);
$em->flush();
$mailer = $this->createMock(\App\Service\MailerService::class);
static::getContainer()->set(\App\Service\MailerService::class, $mailer);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/commande/'.$order->getId().'/annuler');
self::assertResponseRedirects('/mon-compte/evenement/'.$event->getId().'/modifier?tab=stats');
$em->refresh($order);
self::assertSame(\App\Entity\BilletBuyer::STATUS_CANCELLED, $order->getStatus());
$em->refresh($ticket);
self::assertSame(\App\Entity\BilletOrder::STATE_INVALID, $ticket->getState());
}
public function testCancelOrderDeniedForOtherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$other = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $owner);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('Test');
$order->setLastName('Test');
$order->setEmail('test@test.fr');
$order->setOrderNumber('2026-03-21-'.random_int(100, 999));
$order->setTotalHT(0);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$em->persist($order);
$em->flush();
$client->loginUser($other);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/commande/'.$order->getId().'/annuler');
self::assertResponseStatusCodeSame(403);
}
public function testCancelOrderNotFound(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/commande/999999/annuler');
self::assertResponseStatusCodeSame(404);
}
private function createBillet(EntityManagerInterface $em, \App\Entity\Category $category, string $name = 'Test Billet', int $priceHT = 1000): \App\Entity\Billet
{
$billet = new \App\Entity\Billet();
$billet->setName($name);
$billet->setCategory($category);
$billet->setPriceHT($priceHT);
$em->persist($billet);
$em->flush();
return $billet;
}
private function createEvent(EntityManagerInterface $em, User $user): \App\Entity\Event
{
$event = new \App\Entity\Event();
$event->setAccount($user);
$event->setTitle('Test Event '.uniqid());
$event->setStartAt(new \DateTimeImmutable('2026-08-01 10:00'));
$event->setEndAt(new \DateTimeImmutable('2026-08-01 18:00'));
$event->setAddress('1 rue test');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
return $event;
}
private function createCategory(EntityManagerInterface $em, \App\Entity\Event $event, string $name = 'Test Cat', int $position = 0): \App\Entity\Category
{
$category = new \App\Entity\Category();
$category->setName($name);
$category->setEvent($event);
$category->setPosition($position);
$category->setStartAt(new \DateTimeImmutable('2026-06-01 10:00'));
$category->setEndAt(new \DateTimeImmutable('2026-07-31 18:00'));
$em->persist($category);
$em->flush();
return $category;
}
public function testGetAllowedBilletTypesBasic(): void
{
$types = \App\Controller\AccountController::getAllowedBilletTypes('basic');
self::assertSame(['billet', 'reservation_brocante', 'vote'], $types);
}
public function testGetAllowedBilletTypesSurMesure(): void
{
$types = \App\Controller\AccountController::getAllowedBilletTypes('sur-mesure');
self::assertSame(['billet', 'reservation_brocante', 'vote'], $types);
}
public function testGetAllowedBilletTypesFree(): void
{
$types = \App\Controller\AccountController::getAllowedBilletTypes('free');
self::assertSame(['billet'], $types);
}
public function testGetAllowedBilletTypesNull(): void
{
$types = \App\Controller\AccountController::getAllowedBilletTypes(null);
self::assertSame(['billet'], $types);
}
public function testAddBilletTypeRestriction(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$user->setOffer('free');
$em->flush();
$event = $this->createEvent($em, $user);
$category = $this->createCategory($em, $event);
$client->loginUser($user);
$client->request('POST', '/mon-compte/evenement/'.$event->getId().'/categorie/'.$category->getId().'/billet/ajouter', [
'name' => 'Vote Interdit',
'price_ht' => '5',
'type' => 'vote',
'is_generated_billet' => '1',
]);
self::assertResponseRedirects();
$billet = $em->getRepository(\App\Entity\Billet::class)->findOneBy(['name' => 'Vote Interdit']);
self::assertNotNull($billet);
self::assertSame('billet', $billet->getType());
}
public function testExportCsv(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte/export/2026/3');
self::assertResponseIsSuccessful();
self::assertStringContainsString('text/csv', $client->getResponse()->headers->get('Content-Type'));
}
public function testExportPdf(): void
{
$client = static::createClient();
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$client->loginUser($user);
$client->request('GET', '/mon-compte/export/2026/3/pdf');
self::assertResponseIsSuccessful();
self::assertStringContainsString('application/pdf', $client->getResponse()->headers->get('Content-Type'));
}
public function testOrganizerFinanceStatsWithAllStatuses(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$user->setStripeAccountId('acct_finance_'.uniqid());
$user->setStripeChargesEnabled(true);
$user->setCommissionRate(3.0);
$em->flush();
$event = $this->createEvent($em, $user);
$event->setIsOnline(true);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$em->flush();
$statuses = [
\App\Entity\BilletBuyer::STATUS_PAID,
\App\Entity\BilletBuyer::STATUS_PENDING,
\App\Entity\BilletBuyer::STATUS_REFUNDED,
\App\Entity\BilletBuyer::STATUS_CANCELLED,
];
foreach ($statuses as $i => $status) {
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('F'.$i);
$order->setLastName('L'.$i);
$order->setEmail('f'.$i.'@test.fr');
$order->setOrderNumber('2026-'.random_int(10000, 99999));
$order->setTotalHT(1000);
$order->setStatus($status);
if (\App\Entity\BilletBuyer::STATUS_PAID === $status) {
$order->setPaidAt(new \DateTimeImmutable());
}
$item = new \App\Entity\BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName('Entree');
$item->setQuantity(1);
$item->setUnitPriceHT(1000);
$order->addItem($item);
$em->persist($order);
}
$em->flush();
$client->loginUser($user);
$client->request('GET', '/mon-compte?tab=payouts');
self::assertResponseIsSuccessful();
}
public function testEditEventStatsTabWithSoldCounts(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser(['ROLE_ORGANIZER'], true);
$event = $this->createEvent($em, $user);
$event->setIsOnline(true);
$category = $this->createCategory($em, $event);
$billet = $this->createBillet($em, $category);
$order = new \App\Entity\BilletBuyer();
$order->setEvent($event);
$order->setFirstName('Jean');
$order->setLastName('Sold');
$order->setEmail('sold@test.fr');
$order->setOrderNumber('2026-'.random_int(10000, 99999));
$order->setTotalHT(1000);
$order->setStatus(\App\Entity\BilletBuyer::STATUS_PAID);
$order->setPaidAt(new \DateTimeImmutable());
$item = new \App\Entity\BilletBuyerItem();
$item->setBillet($billet);
$item->setBilletName('Entree');
$item->setQuantity(3);
$item->setUnitPriceHT(1000);
$order->addItem($item);
$em->persist($order);
$ticket = new \App\Entity\BilletOrder();
$ticket->setBilletBuyer($order);
$ticket->setBillet($billet);
$ticket->setBilletName('Entree');
$ticket->setUnitPriceHT(1000);
$em->persist($ticket);
$em->flush();
$client->loginUser($user);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=stats');
self::assertResponseIsSuccessful();
}
/**
* @param list<string> $roles
*/
private function createUser(array $roles = [], bool $approved = false): User
{
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = new User();
$user->setEmail('test-account-'.uniqid().'@example.com');
$user->setFirstName('Test');
$user->setLastName('User');
$user->setPassword('$2y$13$hashed');
$user->setRoles($roles);
if ($approved) {
$user->setIsApproved(true);
}
$em->persist($user);
$em->flush();
return $user;
}
}