request('GET', '/mon-compte'); self::assertResponseRedirects(); } 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 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); $em->flush(); $client->loginUser($user); $client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier?tab=stats'); self::assertResponseIsSuccessful(); } /** * @param list $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; } }