first commit
This commit is contained in:
201
tests/Taxonomy/TaxonomyControllerTest.php
Normal file
201
tests/Taxonomy/TaxonomyControllerTest.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Taxonomy;
|
||||
|
||||
use Netig\Netslim\Kernel\Http\Application\Flash\FlashServiceInterface;
|
||||
use Netig\Netslim\Kernel\Pagination\Application\PaginatedResult;
|
||||
use Netig\Netslim\Taxonomy\Application\TaxonomyServiceInterface;
|
||||
use Netig\Netslim\Taxonomy\Domain\Entity\Taxon;
|
||||
use Netig\Netslim\Taxonomy\UI\Http\TaxonomyController;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Tests\ControllerTestBase;
|
||||
|
||||
/**
|
||||
* Tests unitaires pour TaxonomyController.
|
||||
*
|
||||
* Couvre index(), create() et delete() :
|
||||
* rendu de la liste, création réussie, erreur de création,
|
||||
* suppression avec taxon introuvable, succès et erreur métier.
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations]
|
||||
final class TaxonomyControllerTest extends ControllerTestBase
|
||||
{
|
||||
/** @var \Slim\Views\Twig&MockObject */
|
||||
private \Slim\Views\Twig $view;
|
||||
|
||||
/** @var TaxonomyServiceInterface&MockObject */
|
||||
private TaxonomyServiceInterface $taxonomyService;
|
||||
|
||||
/** @var FlashServiceInterface&MockObject */
|
||||
private FlashServiceInterface $flash;
|
||||
|
||||
private TaxonomyController $controller;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->view = $this->makeTwigMock();
|
||||
$this->taxonomyService = $this->createMock(TaxonomyServiceInterface::class);
|
||||
$this->flash = $this->createMock(FlashServiceInterface::class);
|
||||
|
||||
$this->controller = new TaxonomyController(
|
||||
$this->view,
|
||||
$this->taxonomyService,
|
||||
$this->flash,
|
||||
);
|
||||
}
|
||||
|
||||
// ── index ────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* index() doit rendre la vue avec la liste des taxons.
|
||||
*/
|
||||
public function testIndexRendersWithCategories(): void
|
||||
{
|
||||
$this->taxonomyService->method('findPaginated')->willReturn(new PaginatedResult([], 0, 1, 20));
|
||||
|
||||
$this->view->expects($this->once())
|
||||
->method('render')
|
||||
->with($this->anything(), '@Taxonomy/admin/index.twig', $this->anything())
|
||||
->willReturnArgument(0);
|
||||
|
||||
$res = $this->controller->index($this->makeGet('/admin/categories'), $this->makeResponse());
|
||||
|
||||
$this->assertStatus($res, 200);
|
||||
}
|
||||
|
||||
// ── create ───────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* create() doit flasher un succès et rediriger en cas de création réussie.
|
||||
*/
|
||||
public function testCreateRedirectsWithSuccessFlash(): void
|
||||
{
|
||||
$this->taxonomyService->method('create')->willReturn(1);
|
||||
|
||||
$this->flash->expects($this->once())->method('set')
|
||||
->with('taxonomy_success', $this->stringContains('PHP'));
|
||||
|
||||
$req = $this->makePost('/admin/categories/create', ['name' => 'PHP']);
|
||||
$res = $this->controller->create($req, $this->makeResponse());
|
||||
|
||||
$this->assertRedirectTo($res, '/admin/categories');
|
||||
}
|
||||
|
||||
/**
|
||||
* create() doit flasher une erreur si le service lève une InvalidArgumentException.
|
||||
*/
|
||||
public function testCreateRedirectsWithErrorOnInvalidArgument(): void
|
||||
{
|
||||
$this->taxonomyService->method('create')
|
||||
->willThrowException(new \InvalidArgumentException('Ce terme existe déjà'));
|
||||
|
||||
$this->flash->expects($this->once())->method('set')
|
||||
->with('taxonomy_error', 'Ce terme existe déjà');
|
||||
|
||||
$req = $this->makePost('/admin/categories/create', ['name' => 'Duplicate']);
|
||||
$res = $this->controller->create($req, $this->makeResponse());
|
||||
|
||||
$this->assertRedirectTo($res, '/admin/categories');
|
||||
}
|
||||
|
||||
/**
|
||||
* create() doit flasher une erreur générique pour toute autre exception.
|
||||
*/
|
||||
public function testCreateRedirectsWithGenericErrorOnUnexpectedException(): void
|
||||
{
|
||||
$this->taxonomyService->method('create')
|
||||
->willThrowException(new \RuntimeException('DB error'));
|
||||
|
||||
$this->flash->expects($this->once())->method('set')
|
||||
->with('taxonomy_error', $this->stringContains('inattendue'));
|
||||
|
||||
$req = $this->makePost('/admin/categories/create', ['name' => 'PHP']);
|
||||
$res = $this->controller->create($req, $this->makeResponse());
|
||||
|
||||
$this->assertRedirectTo($res, '/admin/categories');
|
||||
}
|
||||
|
||||
// ── delete ───────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* delete() doit flasher une erreur et rediriger si le taxon est introuvable.
|
||||
*/
|
||||
public function testDeleteRedirectsWithErrorWhenNotFound(): void
|
||||
{
|
||||
$this->taxonomyService->method('findById')->willReturn(null);
|
||||
|
||||
$this->flash->expects($this->once())->method('set')
|
||||
->with('taxonomy_error', 'Terme de taxonomie introuvable');
|
||||
|
||||
$res = $this->controller->delete(
|
||||
$this->makePost('/admin/categories/delete/99'),
|
||||
$this->makeResponse(),
|
||||
['id' => '99'],
|
||||
);
|
||||
|
||||
$this->assertRedirectTo($res, '/admin/categories');
|
||||
}
|
||||
|
||||
/**
|
||||
* delete() doit flasher un succès et rediriger en cas de suppression réussie.
|
||||
*/
|
||||
public function testDeleteRedirectsWithSuccessFlash(): void
|
||||
{
|
||||
$category = new Taxon(3, 'PHP', 'php');
|
||||
$this->taxonomyService->method('findById')->willReturn($category);
|
||||
$this->flash->expects($this->once())->method('set')
|
||||
->with('taxonomy_success', $this->stringContains('PHP'));
|
||||
|
||||
$res = $this->controller->delete(
|
||||
$this->makePost('/admin/categories/delete/3'),
|
||||
$this->makeResponse(),
|
||||
['id' => '3'],
|
||||
);
|
||||
|
||||
$this->assertRedirectTo($res, '/admin/categories');
|
||||
}
|
||||
|
||||
/**
|
||||
* delete() doit flasher une erreur si le service refuse la suppression
|
||||
* (ex: des contenus sont rattachés au taxon).
|
||||
*/
|
||||
public function testDeleteRedirectsWithErrorWhenServiceRefuses(): void
|
||||
{
|
||||
$category = new Taxon(3, 'PHP', 'php');
|
||||
$this->taxonomyService->method('findById')->willReturn($category);
|
||||
$this->taxonomyService->method('delete')
|
||||
->willThrowException(new \InvalidArgumentException('Le terme « PHP » est encore utilisé et ne peut pas être supprimé'));
|
||||
|
||||
$this->flash->expects($this->once())->method('set')
|
||||
->with('taxonomy_error', 'Le terme « PHP » est encore utilisé et ne peut pas être supprimé');
|
||||
|
||||
$res = $this->controller->delete(
|
||||
$this->makePost('/admin/categories/delete/3'),
|
||||
$this->makeResponse(),
|
||||
['id' => '3'],
|
||||
);
|
||||
|
||||
$this->assertRedirectTo($res, '/admin/categories');
|
||||
}
|
||||
|
||||
/**
|
||||
* delete() doit passer l'identifiant de route au service findById().
|
||||
*/
|
||||
public function testDeletePassesCorrectIdToService(): void
|
||||
{
|
||||
$this->taxonomyService->expects($this->once())
|
||||
->method('findById')
|
||||
->with(7)
|
||||
->willReturn(null);
|
||||
|
||||
$this->flash->method('set');
|
||||
|
||||
$this->controller->delete(
|
||||
$this->makePost('/admin/categories/delete/7'),
|
||||
$this->makeResponse(),
|
||||
['id' => '7'],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user