Add admin event actions (online/offline, edit, delete) and fix Meilisearch depends_on

- Add toggle online/offline and delete routes in AdminController
- Add action buttons (En ligne, Modifier, Supprimer) in admin events template
- Bypass requireEventOwnership and requireStripeReady for ROLE_ROOT so admin can edit any event
- Add Meilisearch healthcheck and depends_on in messenger service (prod + dev)
- Add tests for all new admin routes and ROLE_ROOT bypass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-26 09:04:27 +01:00
parent 531c7da051
commit 23b92f101c
7 changed files with 209 additions and 1 deletions

View File

@@ -2202,6 +2202,30 @@ class AccountControllerTest extends WebTestCase
self::assertResponseIsSuccessful();
}
public function testRootCanEditEventOfAnotherUser(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$owner = $this->createUser(['ROLE_ORGANIZER'], true);
$root = $this->createUser(['ROLE_ROOT']);
$event = new \App\Entity\Event();
$event->setAccount($owner);
$event->setTitle('Owner Event Root');
$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($root);
$client->request('GET', '/mon-compte/evenement/'.$event->getId().'/modifier');
self::assertResponseIsSuccessful();
}
/**
* @param list<string> $roles
*/

View File

@@ -2,7 +2,9 @@
namespace App\Tests\Controller;
use App\Entity\Event;
use App\Entity\User;
use App\Service\EventIndexService;
use App\Service\MailerService;
use App\Service\MeilisearchService;
use Doctrine\ORM\EntityManagerInterface;
@@ -862,4 +864,117 @@ class AdminControllerTest extends WebTestCase
self::assertResponseIsSuccessful();
self::assertStringContainsString('application/pdf', $client->getResponse()->headers->get('Content-Type'));
}
private function createEvent(EntityManagerInterface $em, User $organizer): Event
{
$event = new Event();
$event->setAccount($organizer);
$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 de la Paix');
$event->setZipcode('75001');
$event->setCity('Paris');
$em->persist($event);
$em->flush();
return $event;
}
public function testToggleEventOnline(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$admin = $this->createUser(['ROLE_ROOT']);
$orga = $this->createOrganizer($em);
$event = $this->createEvent($em, $orga);
$eventIndex = $this->createMock(EventIndexService::class);
$eventIndex->expects(self::once())->method('indexEvent');
static::getContainer()->set(EventIndexService::class, $eventIndex);
self::assertFalse($event->isOnline());
$client->loginUser($admin);
$client->request('POST', '/admin/evenement/'.$event->getId().'/en-ligne');
self::assertResponseRedirects('/admin/evenements');
$em->refresh($event);
self::assertTrue($event->isOnline());
}
public function testToggleEventOffline(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$admin = $this->createUser(['ROLE_ROOT']);
$orga = $this->createOrganizer($em);
$event = $this->createEvent($em, $orga);
$event->setIsOnline(true);
$em->flush();
$eventIndex = $this->createMock(EventIndexService::class);
$eventIndex->expects(self::once())->method('indexEvent');
static::getContainer()->set(EventIndexService::class, $eventIndex);
$client->loginUser($admin);
$client->request('POST', '/admin/evenement/'.$event->getId().'/en-ligne');
self::assertResponseRedirects('/admin/evenements');
$em->refresh($event);
self::assertFalse($event->isOnline());
}
public function testDeleteEvent(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$admin = $this->createUser(['ROLE_ROOT']);
$orga = $this->createOrganizer($em);
$event = $this->createEvent($em, $orga);
$eventId = $event->getId();
$eventIndex = $this->createMock(EventIndexService::class);
$eventIndex->expects(self::once())->method('removeEvent');
static::getContainer()->set(EventIndexService::class, $eventIndex);
$client->loginUser($admin);
$client->request('POST', '/admin/evenement/'.$eventId.'/supprimer');
self::assertResponseRedirects('/admin/evenements');
$deleted = $em->getRepository(Event::class)->find($eventId);
self::assertNull($deleted);
}
public function testToggleEventOnlineDeniedForNonRoot(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser();
$orga = $this->createOrganizer($em);
$event = $this->createEvent($em, $orga);
$client->loginUser($user);
$client->request('POST', '/admin/evenement/'.$event->getId().'/en-ligne');
self::assertResponseStatusCodeSame(403);
}
public function testDeleteEventDeniedForNonRoot(): void
{
$client = static::createClient();
$em = static::getContainer()->get(EntityManagerInterface::class);
$user = $this->createUser();
$orga = $this->createOrganizer($em);
$event = $this->createEvent($em, $orga);
$client->loginUser($user);
$client->request('POST', '/admin/evenement/'.$event->getId().'/supprimer');
self::assertResponseStatusCodeSame(403);
}
}