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('Already Imported', awardsImported: true); $this->wikidataGateway->expects($this->never())->method('getAwardsForActors'); $this->importer->importForActors([$actor]); } public function testImportsAwardsAndSetsFlag(): void { $actor = $this->createActorWithFlag('Test Actor', awardsImported: false); $this->wikidataGateway->method('getAwardsForActors')->willReturn([ 'Test Actor' => [ ['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->importForActors([$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('Test Actor', awardsImported: false); $this->wikidataGateway->method('getAwardsForActors')->willReturn([ 'Test Actor' => [ ['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->importForActors([$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('Test Actor', awardsImported: false); $this->wikidataGateway->method('getAwardsForActors') ->willThrowException(new \RuntimeException('Wikidata timeout')); $this->importer->importForActors([$actor]); $this->assertFalse($actor->isAwardsImported()); } public function testHandlesActorWithNoAwards(): void { $actor = $this->createActorWithFlag('Test Actor', awardsImported: false); $this->wikidataGateway->method('getAwardsForActors')->willReturn([]); $this->awardTypeRepository->method('findAll')->willReturn([]); $this->em->expects($this->never())->method('persist'); $this->importer->importForActors([$actor]); $this->assertTrue($actor->isAwardsImported()); } public function testBatchImportsMultipleActors(): void { $actor1 = $this->createActorWithFlag('Actor One', awardsImported: false); $actor2 = $this->createActorWithFlag('Actor Two', awardsImported: false); $alreadyImported = $this->createActorWithFlag('Actor Three', awardsImported: true); $this->wikidataGateway->expects($this->once())->method('getAwardsForActors') ->with($this->callback(fn (array $actors) => 2 === \count($actors))) ->willReturn([ 'Actor One' => [['name' => 'Academy Award for Best Actor', 'year' => 2020]], 'Actor Two' => [['name' => 'Golden Globe for Best Actor', 'year' => 2021]], ]); $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->importForActors([$actor1, $actor2, $alreadyImported]); $this->assertTrue($actor1->isAwardsImported()); $this->assertTrue($actor2->isAwardsImported()); // 2 Awards + 1 new AwardType (Golden Globe) $this->assertCount(3, $persisted); } private function createActorWithFlag(string $name, bool $awardsImported): Actor { $actor = new Actor(); $actor->setName($name); $actor->setAwardsImported($awardsImported); return $actor; } }