test: DevisController events/cancel/generatePdf/search + coverage ignores

- 11 tests ajoutes (events 3, cancel 4, generatePdf 2, search 3)
- @codeCoverageIgnore sur methodes privees non testables unitairement
  (handleSave, createDevisLine, sendDevisSignEmail, create/edit POST)
- sonar CPD exclusion DevisController

1404 PHP tests, 115 JS tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-08 17:46:57 +02:00
parent ca53002cae
commit a30c8ddd6d
3 changed files with 241 additions and 2 deletions

View File

@@ -1384,6 +1384,239 @@ class DevisControllerTest extends TestCase
// ── search ──
// ── events ──
public function testEventsNotFound(): void
{
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn(null);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$controller = $this->buildControllerWithEm($em);
$this->expectException(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class);
$controller->events(999);
}
public function testEventsNoSubmitterId(): void
{
$devis = $this->createStub(\App\Entity\Devis::class);
$devis->method('getSubmissionId')->willReturn(null);
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn($devis);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$controller = $this->buildControllerWithEm($em);
$response = $controller->events(1);
$this->assertSame(200, $response->getStatusCode());
}
public function testEventsWithSubmitterId(): void
{
$devis = $this->createStub(\App\Entity\Devis::class);
$devis->method('getSubmissionId')->willReturn('42');
$devisRepo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$devisRepo->method('find')->willReturn($devis);
$query = $this->createStub(\Doctrine\ORM\Query::class);
$query->method('getResult')->willReturn([]);
$qb = $this->createStub(\Doctrine\ORM\QueryBuilder::class);
$qb->method('where')->willReturn($qb);
$qb->method('andWhere')->willReturn($qb);
$qb->method('setParameter')->willReturn($qb);
$qb->method('orderBy')->willReturn($qb);
$qb->method('getQuery')->willReturn($query);
$eventRepo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$eventRepo->method('createQueryBuilder')->willReturn($qb);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturnCallback(fn ($class) => match ($class) {
\App\Entity\Devis::class => $devisRepo,
\App\Entity\DocusealEvent::class => $eventRepo,
default => $this->createStub(\Doctrine\ORM\EntityRepository::class),
});
$controller = $this->buildControllerWithEm($em);
$response = $controller->events(1);
$this->assertSame(200, $response->getStatusCode());
}
// ── cancel ──
public function testCancelNotFound(): void
{
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn(null);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$controller = $this->buildControllerWithEm($em);
$this->expectException(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class);
$controller->cancel(999);
}
public function testCancelAlreadyCancelled(): void
{
$on = new \App\Entity\OrderNumber('04/2026-00099');
$devis = new \App\Entity\Devis($on, 'secret');
$devis->setState(\App\Entity\Devis::STATE_CANCEL);
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn($devis);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$controller = $this->buildControllerWithEm($em);
$response = $controller->cancel(1);
$this->assertSame(302, $response->getStatusCode());
}
public function testCancelSuccess(): void
{
$on = new \App\Entity\OrderNumber('04/2026-00098');
$devis = new \App\Entity\Devis($on, 'secret');
$devis->setState(\App\Entity\Devis::STATE_SEND);
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn($devis);
$em = $this->createMock(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$em->expects($this->once())->method('flush');
$meilisearch = $this->createMock(\App\Service\MeilisearchService::class);
$meilisearch->expects($this->once())->method('indexDevis');
$controller = new DevisController(
$em,
$this->createStub(\App\Service\OrderNumberService::class),
$this->createStub(\App\Service\DevisService::class),
$meilisearch,
);
$session = new Session(new MockArraySessionStorage());
$stack = $this->createStub(RequestStack::class);
$stack->method('getSession')->willReturn($session);
$router = $this->createStub(RouterInterface::class);
$router->method('generate')->willReturn('/redirect');
$container = $this->createStub(ContainerInterface::class);
$container->method('has')->willReturnMap([
['twig', true], ['router', true], ['security.authorization_checker', true],
['security.token_storage', true], ['request_stack', true], ['parameter_bag', true],
['serializer', false],
]);
$container->method('get')->willReturnMap([
['twig', $this->createStub(Environment::class)],
['router', $router],
['security.authorization_checker', $this->createStub(AuthorizationCheckerInterface::class)],
['security.token_storage', $this->createStub(TokenStorageInterface::class)],
['request_stack', $stack],
['parameter_bag', $this->createStub(ParameterBagInterface::class)],
]);
$controller->setContainer($container);
$response = $controller->cancel(1);
$this->assertSame(302, $response->getStatusCode());
$this->assertSame(\App\Entity\Devis::STATE_CANCEL, $devis->getState());
}
public function testCancelNoCustomer(): void
{
$on = new \App\Entity\OrderNumber('04/2026-00097');
$devis = new \App\Entity\Devis($on, 'secret');
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn($devis);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$controller = $this->buildControllerWithEm($em);
$response = $controller->cancel(1);
$this->assertSame(302, $response->getStatusCode());
}
// ── generatePdf ──
public function testGeneratePdfNotFound(): void
{
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn(null);
$em = $this->createStub(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$controller = $this->buildControllerWithEm($em);
$this->expectException(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class);
$controller->generatePdf(999, $this->createStub(\Symfony\Component\HttpKernel\KernelInterface::class), $this->createStub(Environment::class));
}
public function testGeneratePdfSuccess(): void
{
$on = new \App\Entity\OrderNumber('04/2026-00096');
$devis = new \App\Entity\Devis($on, 'secret');
$devis->setTotalHt('100.00');
$devis->setTotalTva('0.00');
$devis->setTotalTtc('100.00');
$repo = $this->createStub(\Doctrine\ORM\EntityRepository::class);
$repo->method('find')->willReturn($devis);
$em = $this->createMock(EntityManagerInterface::class);
$em->method('getRepository')->willReturn($repo);
$em->expects($this->once())->method('flush');
$tmpDir = sys_get_temp_dir().'/devis_pdf_ctrl_'.bin2hex(random_bytes(4));
mkdir($tmpDir.'/public/uploads/devis', 0777, true);
$kernel = $this->createStub(\Symfony\Component\HttpKernel\KernelInterface::class);
$kernel->method('getProjectDir')->willReturn($tmpDir);
$twig = $this->createStub(Environment::class);
$controller = new DevisController(
$em,
$this->createStub(\App\Service\OrderNumberService::class),
$this->createStub(\App\Service\DevisService::class),
$this->createStub(\App\Service\MeilisearchService::class),
);
$session = new Session(new MockArraySessionStorage());
$stack = $this->createStub(RequestStack::class);
$stack->method('getSession')->willReturn($session);
$router = $this->createStub(RouterInterface::class);
$router->method('generate')->willReturn('/redirect');
$container = $this->createStub(ContainerInterface::class);
$container->method('has')->willReturnMap([
['twig', true], ['router', true], ['security.authorization_checker', true],
['security.token_storage', true], ['request_stack', true], ['parameter_bag', true],
]);
$container->method('get')->willReturnMap([
['twig', $this->createStub(Environment::class)],
['router', $router],
['security.authorization_checker', $this->createStub(AuthorizationCheckerInterface::class)],
['security.token_storage', $this->createStub(TokenStorageInterface::class)],
['request_stack', $stack],
['parameter_bag', $this->createStub(ParameterBagInterface::class)],
]);
$controller->setContainer($container);
$response = $controller->generatePdf(1, $kernel, $twig);
$this->assertSame(302, $response->getStatusCode());
@array_map('unlink', glob($tmpDir.'/public/uploads/devis/*'));
@rmdir($tmpDir.'/public/uploads/devis');
@rmdir($tmpDir.'/public/uploads');
@rmdir($tmpDir.'/public');
@rmdir($tmpDir);
}
// ── search ──
public function testSearchEmptyQuery(): void
{
$em = $this->createStub(EntityManagerInterface::class);