feat: add AwardImporter service with tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
139
tests/Service/AwardImporterTest.php
Normal file
139
tests/Service/AwardImporterTest.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Service;
|
||||
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Award;
|
||||
use App\Entity\AwardType;
|
||||
use App\Gateway\WikidataGateway;
|
||||
use App\Repository\AwardTypeRepository;
|
||||
use App\Service\AwardImporter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AwardImporterTest extends TestCase
|
||||
{
|
||||
private AwardImporter $importer;
|
||||
private WikidataGateway&\PHPUnit\Framework\MockObject\MockObject $wikidataGateway;
|
||||
private AwardTypeRepository&\PHPUnit\Framework\MockObject\MockObject $awardTypeRepository;
|
||||
private EntityManagerInterface&\PHPUnit\Framework\MockObject\MockObject $em;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->wikidataGateway = $this->createMock(WikidataGateway::class);
|
||||
$this->awardTypeRepository = $this->createMock(AwardTypeRepository::class);
|
||||
$this->em = $this->createMock(EntityManagerInterface::class);
|
||||
|
||||
$this->importer = new AwardImporter(
|
||||
$this->wikidataGateway,
|
||||
$this->awardTypeRepository,
|
||||
$this->em,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSkipsActorWithAwardsAlreadyImported(): void
|
||||
{
|
||||
$actor = $this->createActorWithFlag(awardsImported: true);
|
||||
|
||||
$this->wikidataGateway->expects($this->never())->method('getAwards');
|
||||
|
||||
$this->importer->importForActor($actor);
|
||||
}
|
||||
|
||||
public function testImportsAwardsAndSetsFlag(): void
|
||||
{
|
||||
$actor = $this->createActorWithFlag(awardsImported: false);
|
||||
|
||||
$this->wikidataGateway->method('getAwards')->willReturn([
|
||||
['name' => 'Academy Award for Best Actor', 'year' => 2020],
|
||||
]);
|
||||
|
||||
$existingType = new AwardType();
|
||||
$existingType->setName('Oscar')->setPattern('Academy Award');
|
||||
|
||||
$this->awardTypeRepository->method('findAll')->willReturn([$existingType]);
|
||||
|
||||
$persisted = [];
|
||||
$this->em->method('persist')->willReturnCallback(function ($entity) use (&$persisted) {
|
||||
$persisted[] = $entity;
|
||||
});
|
||||
|
||||
$this->importer->importForActor($actor);
|
||||
|
||||
$this->assertTrue($actor->isAwardsImported());
|
||||
$this->assertCount(1, $persisted);
|
||||
$this->assertInstanceOf(Award::class, $persisted[0]);
|
||||
$this->assertSame('Academy Award for Best Actor', $persisted[0]->getName());
|
||||
$this->assertSame(2020, $persisted[0]->getYear());
|
||||
$this->assertSame($existingType, $persisted[0]->getAwardType());
|
||||
$this->assertSame($actor, $persisted[0]->getActor());
|
||||
}
|
||||
|
||||
public function testCreatesNewAwardTypeWhenNoPatternMatches(): void
|
||||
{
|
||||
$actor = $this->createActorWithFlag(awardsImported: false);
|
||||
|
||||
$this->wikidataGateway->method('getAwards')->willReturn([
|
||||
['name' => 'Screen Actors Guild Award for Outstanding Performance', 'year' => 2019],
|
||||
]);
|
||||
|
||||
$this->awardTypeRepository->method('findAll')->willReturn([]);
|
||||
|
||||
$persisted = [];
|
||||
$this->em->method('persist')->willReturnCallback(function ($entity) use (&$persisted) {
|
||||
$persisted[] = $entity;
|
||||
});
|
||||
|
||||
$this->importer->importForActor($actor);
|
||||
|
||||
$this->assertTrue($actor->isAwardsImported());
|
||||
// Should persist both a new AwardType and the Award
|
||||
$this->assertCount(2, $persisted);
|
||||
|
||||
$newType = $persisted[0];
|
||||
$this->assertInstanceOf(AwardType::class, $newType);
|
||||
$this->assertSame('Screen Actors Guild Award', $newType->getName());
|
||||
$this->assertSame('Screen Actors Guild Award', $newType->getPattern());
|
||||
|
||||
$award = $persisted[1];
|
||||
$this->assertInstanceOf(Award::class, $award);
|
||||
$this->assertSame($newType, $award->getAwardType());
|
||||
}
|
||||
|
||||
public function testDoesNotSetFlagOnWikidataError(): void
|
||||
{
|
||||
$actor = $this->createActorWithFlag(awardsImported: false);
|
||||
|
||||
$this->wikidataGateway->method('getAwards')
|
||||
->willThrowException(new \RuntimeException('Wikidata timeout'));
|
||||
|
||||
$this->importer->importForActor($actor);
|
||||
|
||||
$this->assertFalse($actor->isAwardsImported());
|
||||
}
|
||||
|
||||
public function testHandlesActorWithNoAwards(): void
|
||||
{
|
||||
$actor = $this->createActorWithFlag(awardsImported: false);
|
||||
|
||||
$this->wikidataGateway->method('getAwards')->willReturn([]);
|
||||
$this->awardTypeRepository->method('findAll')->willReturn([]);
|
||||
|
||||
$this->em->expects($this->never())->method('persist');
|
||||
|
||||
$this->importer->importForActor($actor);
|
||||
|
||||
$this->assertTrue($actor->isAwardsImported());
|
||||
}
|
||||
|
||||
private function createActorWithFlag(bool $awardsImported): Actor
|
||||
{
|
||||
$actor = new Actor();
|
||||
$actor->setName('Test Actor');
|
||||
$actor->setAwardsImported($awardsImported);
|
||||
|
||||
return $actor;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user