✨ feat(ReserverController): Ajoute vérification de disponibilité produit. 🛠️ refactor(BackupCommand): Utilise DatabaseDumper et ZipArchiver. ✨ feat(GitSyncLogCommand): Utilise Gemini pour messages plus clairs. ✨ feat(GenerateVideoThumbsCommand): Utilise VideoThumbnailer service. ✨ feat(AppWarmupImagesCommand): Utilise StorageInterface pour warmup. 🔒️ security(nelmio_security): Renforce la sécurité avec des en-têtes. 🔧 chore(caddy): Améliore la configuration de Caddy pour la performance. 🐛 fix(makefile): Corrige les commandes de test. 🧪 chore(.env.test): Supprime la ligne vide à la fin du fichier. 🔧 chore(doctrine): Active native_lazy_objects. 🔧 chore(cache): Ajoute un cache system. ```
127 lines
4.9 KiB
PHP
127 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Repository;
|
|
|
|
use App\Entity\Product;
|
|
use App\Entity\ProductReserve;
|
|
use App\Repository\ProductReserveRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
|
|
|
class ProductReserveRepositoryTest extends KernelTestCase
|
|
{
|
|
private ?EntityManagerInterface $entityManager;
|
|
private ?ProductReserveRepository $repository;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$kernel = self::bootKernel();
|
|
|
|
$this->entityManager = $kernel->getContainer()
|
|
->get('doctrine')
|
|
->getManager();
|
|
|
|
$this->repository = $this->entityManager->getRepository(ProductReserve::class);
|
|
|
|
// Optional: Purge database or ensure clean state
|
|
// For now, we assume a test DB or we just append data.
|
|
// Ideally, we should use a separate test DB.
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
parent::tearDown();
|
|
$this->entityManager->close();
|
|
$this->entityManager = null;
|
|
$this->repository = null;
|
|
}
|
|
|
|
public function testCheckAvailability()
|
|
{
|
|
// 1. Create a Product
|
|
$product = new Product();
|
|
$product->setRef('TEST-REF-' . uniqid());
|
|
$product->setCategory('TEST-CAT');
|
|
$product->setName('Test Product ' . uniqid());
|
|
$product->setPriceDay(10.0);
|
|
$product->setCaution(100.0);
|
|
|
|
$this->entityManager->persist($product);
|
|
|
|
// 2. Create an existing reservation
|
|
// From 2026-02-10 to 2026-02-15
|
|
$existing = new ProductReserve();
|
|
$existing->setProduct($product);
|
|
$existing->setStartAt(new \DateTimeImmutable('2026-02-10 10:00:00'));
|
|
$existing->setEndAt(new \DateTimeImmutable('2026-02-15 10:00:00'));
|
|
|
|
$this->entityManager->persist($existing);
|
|
$this->entityManager->flush();
|
|
|
|
// 3. Test Cases
|
|
|
|
// Case A: Completely before (Available)
|
|
// 2026-02-01 to 2026-02-05
|
|
$reserveA = new ProductReserve();
|
|
$reserveA->setProduct($product);
|
|
$reserveA->setStartAt(new \DateTimeImmutable('2026-02-01 10:00:00'));
|
|
$reserveA->setEndAt(new \DateTimeImmutable('2026-02-05 10:00:00'));
|
|
|
|
$this->assertTrue($this->repository->checkAvailability($reserveA), 'Should be available (before)');
|
|
|
|
// Case B: Completely after (Available)
|
|
// 2026-02-16 to 2026-02-20
|
|
$reserveB = new ProductReserve();
|
|
$reserveB->setProduct($product);
|
|
$reserveB->setStartAt(new \DateTimeImmutable('2026-02-16 10:00:00'));
|
|
$reserveB->setEndAt(new \DateTimeImmutable('2026-02-20 10:00:00'));
|
|
|
|
$this->assertTrue($this->repository->checkAvailability($reserveB), 'Should be available (after)');
|
|
|
|
// Case C: Overlapping (exact match) (Not Available)
|
|
// 2026-02-10 to 2026-02-15
|
|
$reserveC = new ProductReserve();
|
|
$reserveC->setProduct($product);
|
|
$reserveC->setStartAt(new \DateTimeImmutable('2026-02-10 10:00:00'));
|
|
$reserveC->setEndAt(new \DateTimeImmutable('2026-02-15 10:00:00'));
|
|
|
|
$this->assertFalse($this->repository->checkAvailability($reserveC), 'Should NOT be available (exact match)');
|
|
|
|
// Case D: Overlapping (partial start) (Not Available)
|
|
// 2026-02-09 to 2026-02-11
|
|
$reserveD = new ProductReserve();
|
|
$reserveD->setProduct($product);
|
|
$reserveD->setStartAt(new \DateTimeImmutable('2026-02-09 10:00:00'));
|
|
$reserveD->setEndAt(new \DateTimeImmutable('2026-02-11 10:00:00'));
|
|
|
|
$this->assertFalse($this->repository->checkAvailability($reserveD), 'Should NOT be available (overlap start)');
|
|
|
|
// Case E: Overlapping (partial end) (Not Available)
|
|
// 2026-02-14 to 2026-02-16
|
|
$reserveE = new ProductReserve();
|
|
$reserveE->setProduct($product);
|
|
$reserveE->setStartAt(new \DateTimeImmutable('2026-02-14 10:00:00'));
|
|
$reserveE->setEndAt(new \DateTimeImmutable('2026-02-16 10:00:00'));
|
|
|
|
$this->assertFalse($this->repository->checkAvailability($reserveE), 'Should NOT be available (overlap end)');
|
|
|
|
// Case F: Inside (Not Available)
|
|
// 2026-02-11 to 2026-02-14
|
|
$reserveF = new ProductReserve();
|
|
$reserveF->setProduct($product);
|
|
$reserveF->setStartAt(new \DateTimeImmutable('2026-02-11 10:00:00'));
|
|
$reserveF->setEndAt(new \DateTimeImmutable('2026-02-14 10:00:00'));
|
|
|
|
$this->assertFalse($this->repository->checkAvailability($reserveF), 'Should NOT be available (inside)');
|
|
|
|
// Case G: Encompassing (Not Available)
|
|
// 2026-02-09 to 2026-02-16
|
|
$reserveG = new ProductReserve();
|
|
$reserveG->setProduct($product);
|
|
$reserveG->setStartAt(new \DateTimeImmutable('2026-02-09 10:00:00'));
|
|
$reserveG->setEndAt(new \DateTimeImmutable('2026-02-16 10:00:00'));
|
|
|
|
$this->assertFalse($this->repository->checkAvailability($reserveG), 'Should NOT be available (encompassing)');
|
|
}
|
|
}
|