Entites completes a 100% : - AdvertLineTest : 12 tests (constructor, setters, fluent interface) - DevisLineTest : 12 tests (idem) Services ameliores vers 100% : - DocuSealServiceTest : +1 (getLogoBase64 avec logo.jpg) - FactureServiceTest : +1 (createFromAdvert avec lines description/type) - MailerServiceTest : +1 (injectAttachmentsList sans <tr> avant footer) - OrderNumberServiceTest : +4 (generate/preview create new number) - ComptaPdfTest : +2 (Header/Footer explicites, setData re-assign) - FacturePdfTest : +3 (displayHmac, appendRib sans/avec fichier) Controllers ameliores : - ComptabiliteControllerTest : +22 (tous exports avec donnees, TVA, sign) - StatsControllerTest : +8 (factures payees, AdvertPayment, services, resolveStatus) - ClientsControllerTest : +12 (contacts, NDD, securite, DNS check) - WebhookStripeControllerTest : +8 (handlePaymentSucceeded/Failed tous chemins) - AdminControllersTest : +1 (dashboard globalSearch empty) - FactureControllerTest : +2 (customer null, generatePdf 404) - PrestatairesControllerTest : +1 (deleteFacture mismatch) - SyncControllerTest : +1 (syncAll error) - TarificationControllerTest : +1 (purge avec stripeId) - LegalControllerTest : +3 (rgpdVerify access/deletion/missing params) Progression : 83% -> 87% methodes, 18 -> 10 classes restantes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
229 lines
8.1 KiB
PHP
229 lines
8.1 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Service;
|
|
|
|
use App\Entity\OrderNumber;
|
|
use App\Repository\OrderNumberRepository;
|
|
use App\Service\OrderNumberService;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\ORM\Query;
|
|
use Doctrine\ORM\QueryBuilder;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class OrderNumberServiceTest extends TestCase
|
|
{
|
|
private function createQueryBuilder(?OrderNumber $lastOrder = null): QueryBuilder
|
|
{
|
|
$query = $this->createStub(Query::class);
|
|
$query->method('getOneOrNullResult')->willReturn($lastOrder);
|
|
|
|
$qb = $this->createStub(QueryBuilder::class);
|
|
$qb->method('where')->willReturnSelf();
|
|
$qb->method('setParameter')->willReturnSelf();
|
|
$qb->method('orderBy')->willReturnSelf();
|
|
$qb->method('setMaxResults')->willReturnSelf();
|
|
$qb->method('getQuery')->willReturn($query);
|
|
|
|
return $qb;
|
|
}
|
|
|
|
public function testGenerateFirstOfMonth(): void
|
|
{
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder(null));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->generate();
|
|
|
|
$now = new \DateTimeImmutable();
|
|
$expected = $now->format('m/Y').'-00001';
|
|
$this->assertSame($expected, $result->getNumOrder());
|
|
}
|
|
|
|
public function testGenerateIncrementsCounter(): void
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
$lastOrder = new OrderNumber($now->format('m/Y').'-00042');
|
|
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder($lastOrder));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->generate();
|
|
|
|
$expected = $now->format('m/Y').'-00042';
|
|
$this->assertSame($expected, $result->getNumOrder());
|
|
}
|
|
|
|
public function testGenerateAndUse(): void
|
|
{
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder(null));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->generateAndUse();
|
|
|
|
$this->assertTrue($result->isUsed());
|
|
}
|
|
|
|
public function testPreviewFirstOfMonth(): void
|
|
{
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder(null));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->preview();
|
|
|
|
$now = new \DateTimeImmutable();
|
|
$this->assertSame($now->format('m/Y').'-00001', $result);
|
|
}
|
|
|
|
public function testPreviewIncrementsCounter(): void
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
$lastOrder = new OrderNumber($now->format('m/Y').'-00010');
|
|
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder($lastOrder));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->preview();
|
|
|
|
$this->assertSame($now->format('m/Y').'-00010', $result);
|
|
}
|
|
|
|
public function testPreviewReturnsUnusedOrderNumber(): void
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
// An existing unused order number
|
|
$unused = new OrderNumber($now->format('m/Y').'-00005');
|
|
// unused query returns it; lastOrder query also returns it (only first call matters)
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder($unused));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->preview();
|
|
|
|
// When unused order exists, preview returns its numOrder
|
|
$this->assertSame($now->format('m/Y').'-00005', $result);
|
|
}
|
|
|
|
public function testGenerateReturnsUnusedOrderNumberWhenExists(): void
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
$unused = new OrderNumber($now->format('m/Y').'-00003');
|
|
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturn($this->createQueryBuilder($unused));
|
|
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->generate();
|
|
|
|
$this->assertSame($unused, $result);
|
|
}
|
|
|
|
/**
|
|
* Creates a repo stub that returns different QueryBuilders per call.
|
|
* First call (unused lookup) returns null, second call (last order lookup) returns $lastOrder.
|
|
*/
|
|
private function createSequentialRepo(?OrderNumber $lastOrder = null): OrderNumberRepository
|
|
{
|
|
$queryNull = $this->createStub(Query::class);
|
|
$queryNull->method('getOneOrNullResult')->willReturn(null);
|
|
|
|
$queryLast = $this->createStub(Query::class);
|
|
$queryLast->method('getOneOrNullResult')->willReturn($lastOrder);
|
|
|
|
$qbNull = $this->createStub(QueryBuilder::class);
|
|
$qbNull->method('where')->willReturnSelf();
|
|
$qbNull->method('setParameter')->willReturnSelf();
|
|
$qbNull->method('orderBy')->willReturnSelf();
|
|
$qbNull->method('setMaxResults')->willReturnSelf();
|
|
$qbNull->method('getQuery')->willReturn($queryNull);
|
|
|
|
$qbLast = $this->createStub(QueryBuilder::class);
|
|
$qbLast->method('where')->willReturnSelf();
|
|
$qbLast->method('setParameter')->willReturnSelf();
|
|
$qbLast->method('orderBy')->willReturnSelf();
|
|
$qbLast->method('setMaxResults')->willReturnSelf();
|
|
$qbLast->method('getQuery')->willReturn($queryLast);
|
|
|
|
$callCount = 0;
|
|
$repo = $this->createStub(OrderNumberRepository::class);
|
|
$repo->method('createQueryBuilder')->willReturnCallback(
|
|
function () use ($qbNull, $qbLast, &$callCount) {
|
|
return 0 === $callCount++ ? $qbNull : $qbLast;
|
|
}
|
|
);
|
|
|
|
return $repo;
|
|
}
|
|
|
|
public function testGenerateCreatesNewWhenNoUnusedAndNoLastOrder(): void
|
|
{
|
|
$repo = $this->createSequentialRepo(null);
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->generate();
|
|
|
|
$now = new \DateTimeImmutable();
|
|
$this->assertSame($now->format('m/Y').'-00001', $result->getNumOrder());
|
|
$this->assertFalse($result->isUsed());
|
|
}
|
|
|
|
public function testGenerateCreatesNewIncrementingFromLastOrder(): void
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
$lastOrder = new OrderNumber($now->format('m/Y').'-00042');
|
|
|
|
$repo = $this->createSequentialRepo($lastOrder);
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->generate();
|
|
|
|
$this->assertSame($now->format('m/Y').'-00043', $result->getNumOrder());
|
|
}
|
|
|
|
public function testPreviewCreatesNewWhenNoUnusedAndNoLastOrder(): void
|
|
{
|
|
$repo = $this->createSequentialRepo(null);
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->preview();
|
|
|
|
$now = new \DateTimeImmutable();
|
|
$this->assertSame($now->format('m/Y').'-00001', $result);
|
|
}
|
|
|
|
public function testPreviewIncrementingFromLastOrder(): void
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
$lastOrder = new OrderNumber($now->format('m/Y').'-00010');
|
|
|
|
$repo = $this->createSequentialRepo($lastOrder);
|
|
$em = $this->createStub(EntityManagerInterface::class);
|
|
|
|
$service = new OrderNumberService($repo, $em);
|
|
$result = $service->preview();
|
|
|
|
$this->assertSame($now->format('m/Y').'-00011', $result);
|
|
}
|
|
}
|