- ScrapingJob: mangaId/chapterNumber/sourceId optionnels (nullable) pour permettre la création en PENDING sans lookup DB dans le StateProcessor - ScrapeChapter: ajoute jobId (pré-généré par le StateProcessor) - ScrapeChapterStateProcessor: crée et persiste le job PENDING avant dispatch; injecte JobRepositoryInterface uniquement - ScrapeChapterHandler: supprime EntityManagerInterface, beginTransaction/ commit/rollback; charge le job existant via jobId, complete() sur succès seulement, fail() si toutes les sources échouent - ScrapeChapterHandlerTest: pré-crée le job, passe jobId dans la commande, supprime le mock EntityManagerInterface - ScrapeChapterTest: accès aux messages via static InMemoryMessageBus, vérifie la présence du jobId dans la commande dispatchée
79 lines
2.2 KiB
PHP
79 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Feature\Scraping;
|
|
|
|
use App\Domain\Scraping\Application\Command\ScrapeChapter;
|
|
use App\Tests\Feature\AbstractApiTestCase;
|
|
use App\Tests\Shared\Adapter\InMemoryMessageBus;
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
|
|
|
class ScrapeChapterTest extends AbstractApiTestCase
|
|
{
|
|
private MessageBusInterface|InMemoryMessageBus $messageBus;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->messageBus = new InMemoryMessageBus();
|
|
$this->container->set(MessageBusInterface::class, $this->messageBus);
|
|
$this->messageBus->clear();
|
|
}
|
|
|
|
public function testInitiateChapterScraping(): void
|
|
{
|
|
// Given
|
|
$payload = [
|
|
'chapterId' => 'chapter-123',
|
|
];
|
|
|
|
// When
|
|
$response = static::createClient()->request('POST', '/api/scraping/chapters', [
|
|
'json' => $payload,
|
|
'headers' => ['Accept' => 'application/json'],
|
|
]);
|
|
|
|
// Then
|
|
$this->assertResponseStatusCodeSame(202);
|
|
|
|
$messages = InMemoryMessageBus::$messages;
|
|
$this->assertCount(1, $messages, 'Un message devrait être dispatché');
|
|
|
|
/** @var ScrapeChapter $message */
|
|
$message = $messages[0];
|
|
$this->assertInstanceOf(ScrapeChapter::class, $message);
|
|
$this->assertEquals('chapter-123', $message->chapterId);
|
|
$this->assertNotEmpty($message->jobId);
|
|
}
|
|
|
|
public function testInitiateChapterScrapingWithInvalidPayload(): void
|
|
{
|
|
// Given
|
|
$payload = [
|
|
'chapterId' => '',
|
|
];
|
|
|
|
// When
|
|
$response = static::createClient()->request('POST', '/api/scraping/chapters', [
|
|
'json' => $payload,
|
|
'headers' => ['Accept' => 'application/json'],
|
|
]);
|
|
|
|
// Then
|
|
$this->assertResponseStatusCodeSame(422);
|
|
$this->assertJsonContains([
|
|
'violations' => [
|
|
[
|
|
'propertyPath' => 'chapterId',
|
|
'message' => 'This value should not be blank.',
|
|
],
|
|
],
|
|
]);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
parent::tearDown();
|
|
InMemoryMessageBus::$messages = [];
|
|
}
|
|
}
|