setName('Oscar')->setPattern('Academy Award'); $actor = new Actor(); $actor->setName('Test Actor'); $award = new Award(); $award->setName('Academy Award for Best Actor'); $award->setYear(2020); $award->setActor($actor); $award->setAwardType($awardType); $awardRepository = $this->createMock(AwardRepository::class); $awardRepository->method('find')->with(42)->willReturn($award); $generator = new GameGridProvider( $this->createMock(ActorRepository::class), $this->createMock(MovieRoleRepository::class), $this->createMock(MovieRepository::class), $awardRepository, $this->createMock(EntityManagerInterface::class), ); $row = new GameRow(); $row->setHintType('award'); $row->setHintData('42'); // Use reflection to test the private resolveHintText method $method = new \ReflectionMethod($generator, 'resolveHintText'); $result = $method->invoke($generator, $row); $this->assertSame('Academy Award for Best Actor (2020)', $result); } public function testGenerateHintRespectsAllowedTypes(): void { $movieRoleRepo = $this->createMock(MovieRoleRepository::class); $movieRoleRepo->method('findOneRandomByActor')->willReturn(null); $awardRepo = $this->createMock(AwardRepository::class); $awardRepo->method('findOneRandomByActor')->willReturn(null); $awardRepo->method('findOneRandomByActorAndTypes')->willReturn(null); $generator = new GameGridProvider( $this->createMock(ActorRepository::class), $movieRoleRepo, $this->createMock(MovieRepository::class), $awardRepo, $this->createMock(EntityManagerInterface::class), ); $actor = new Actor(); $actor->setName('Test'); // Only allow 'award' type, but no awards exist → should return null $method = new \ReflectionMethod($generator, 'generateHint'); $result = $method->invoke($generator, $actor, ['award'], null); $this->assertNull($result); } public function testGenerateUsesConfiguredMinPopularity(): void { $mainActor = $this->createActorWithId(10, 'AB'); $firstRowActor = $this->createActorWithId(11, 'Anna'); $secondRowActor = $this->createActorWithId(12, 'Bob'); $calls = []; $actors = [$mainActor, $firstRowActor, $secondRowActor]; $actorRepository = $this->createMock(ActorRepository::class); $actorRepository ->method('findOneRandomByPopularityBucketRange') ->willReturnCallback(function (int $minBucket, int $maxBucket, ?string $char = null) use (&$calls, &$actors) { $calls[] = [$minBucket, $maxBucket, $char]; return array_shift($actors); }); $movieRoleRepository = $this->createMock(MovieRoleRepository::class); $movieRoleRepository ->method('findOneRandomByActor') ->willReturnCallback(function (int $actorId): MovieRole { $movie = new Movie(); $movie->setTitle('Film ' . $actorId); $role = new MovieRole(); $role->setCharacter('Character ' . $actorId); $role->setMovie($movie); return $role; }); $em = $this->createMock(EntityManagerInterface::class); $em->expects($this->once())->method('persist'); $em->expects($this->once())->method('flush'); $generator = new GameGridProvider( $actorRepository, $movieRoleRepository, $this->createMock(MovieRepository::class), $this->createMock(AwardRepository::class), $em, ); $game = $generator->generate(config: [ 'popularityRange' => [ 'minBucket' => 5, 'maxBucket' => 10, ], 'hintTypes' => ['film'], ]); $this->assertNotNull($game); $this->assertSame([ [5, 10, null], [5, 10, 'a'], [5, 10, 'b'], ], $calls); } private function createActorWithId(int $id, string $name): Actor { $actor = new Actor(); $actor->setName($name); $idProperty = new \ReflectionProperty(Actor::class, 'id'); $idProperty->setValue($actor, $id); return $actor; } }