Add organizer logo upload, Meilisearch organizer search, and webp URL rewriting

VichUploader organizer logo:
- Add organizer_logo mapping with local Flysystem storage
- Add logoFile, logoName, updatedAt fields to User entity
- Use Vich Attribute (not deprecated Annotation)
- Add migration for logo_name and updated_at columns

Meilisearch organizer search:
- Add search bar on /admin/organisateurs page (hides tabs during search)
- Index organizers in Meilisearch on approval
- Sync button on dashboard now syncs both buyers and organizers
- Add tests: search query, search error

Liip Imagine webp:
- Add format filter to all filter_sets for explicit webp conversion
- Add organizer_logo filter_set (400x400, webp)
- Create WebpExtensionSubscriber to rewrite image URLs to .webp extension
- 8 tests for subscriber (png, jpg, jpeg, gif, webp passthrough, case insensitive, null)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-19 18:46:34 +01:00
parent a047cfa787
commit 82829f6240
11 changed files with 350 additions and 11 deletions

View File

@@ -0,0 +1,81 @@
<?php
namespace App\Tests\EventSubscriber;
use App\EventSubscriber\WebpExtensionSubscriber;
use Liip\ImagineBundle\Events\CacheResolveEvent;
use PHPUnit\Framework\TestCase;
class WebpExtensionSubscriberTest extends TestCase
{
private WebpExtensionSubscriber $subscriber;
protected function setUp(): void
{
$this->subscriber = new WebpExtensionSubscriber();
}
public function testGetSubscribedEvents(): void
{
$events = WebpExtensionSubscriber::getSubscribedEvents();
self::assertArrayHasKey('liip_imagine.post_resolve', $events);
self::assertSame('onPostResolve', $events['liip_imagine.post_resolve']);
}
public function testRewritesPngToWebp(): void
{
$event = new CacheResolveEvent('logo.png', 'thumbnail', '/media/cache/thumbnail/logo.png');
$this->subscriber->onPostResolve($event);
self::assertSame('/media/cache/thumbnail/logo.webp', $event->getUrl());
}
public function testRewritesJpgToWebp(): void
{
$event = new CacheResolveEvent('photo.jpg', 'medium', '/media/cache/medium/photo.jpg');
$this->subscriber->onPostResolve($event);
self::assertSame('/media/cache/medium/photo.webp', $event->getUrl());
}
public function testRewritesJpegToWebp(): void
{
$event = new CacheResolveEvent('image.jpeg', 'large', '/media/cache/large/image.jpeg');
$this->subscriber->onPostResolve($event);
self::assertSame('/media/cache/large/image.webp', $event->getUrl());
}
public function testRewritesGifToWebp(): void
{
$event = new CacheResolveEvent('anim.gif', 'thumbnail', '/media/cache/thumbnail/anim.gif');
$this->subscriber->onPostResolve($event);
self::assertSame('/media/cache/thumbnail/anim.webp', $event->getUrl());
}
public function testDoesNotRewriteWebp(): void
{
$event = new CacheResolveEvent('already.webp', 'thumbnail', '/media/cache/thumbnail/already.webp');
$this->subscriber->onPostResolve($event);
self::assertSame('/media/cache/thumbnail/already.webp', $event->getUrl());
}
public function testCaseInsensitive(): void
{
$event = new CacheResolveEvent('logo.PNG', 'thumbnail', '/media/cache/thumbnail/logo.PNG');
$this->subscriber->onPostResolve($event);
self::assertSame('/media/cache/thumbnail/logo.webp', $event->getUrl());
}
public function testNullUrlIsIgnored(): void
{
$event = new CacheResolveEvent('logo.png', 'thumbnail');
$this->subscriber->onPostResolve($event);
self::assertNull($event->getUrl());
}
}