setValue($game, 42); $generator = $this->createMock(GameGridProvider::class); $generator ->expects($this->once()) ->method('generate') ->with( null, $this->callback(function (array $config): bool { $this->assertSame([ 'minBucket' => 5, 'maxBucket' => 8, ], $config['popularityRange']); $this->assertSame(['film', 'character', 'award'], $config['hintTypes']); $this->assertArrayNotHasKey('watchedOnly', $config); return true; }) ) ->willReturn($game); $controller = new class extends GameController { protected function isCsrfTokenValid(string $id, ?string $token): bool { return true; } public function getUser(): ?UserInterface { return null; } }; $controller->setContainer($this->createContainer()); $request = Request::create('/game/start', 'POST', [ '_token' => 'test-token', 'popularity_min_bucket' => '5', 'popularity_max_bucket' => '8', ]); $request->setSession(new Session(new MockArraySessionStorage())); $response = $controller->start( $request, $generator, $this->createStub(GameRepository::class), ); $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertSame('/', $response->getTargetUrl()); $this->assertSame(42, $request->getSession()->get('current_game_id')); } public function testAbandonStoresAttemptedLettersForReveal(): void { $game = new Game(); $idProperty = new \ReflectionProperty(Game::class, 'id'); $idProperty->setValue($game, 42); $em = $this->createMock(EntityManagerInterface::class); $em->expects($this->once())->method('flush'); $controller = new class extends GameController { protected function isCsrfTokenValid(string $id, ?string $token): bool { return true; } public function getUser(): ?UserInterface { return null; } }; $controller->setContainer($this->createContainer()); $request = Request::create('/game/42/abandon', 'POST', [ '_token' => 'test-token', 'attempted_letters' => '{"0":{"2":"a","3":"!","4":"bc"},"4":{"1":" z "},"oops":"x"}', ]); $request->setSession(new Session(new MockArraySessionStorage())); $request->getSession()->set('current_game_id', 42); $response = $controller->abandon($game, $request, $em); $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertSame('/?revealed=1', $response->getTargetUrl()); $this->assertSame(Game::STATUS_ABANDONED, $game->getStatus()); $this->assertSame(42, $request->getSession()->get('revealed_game_id')); $this->assertNull($request->getSession()->get('current_game_id')); $this->assertSame([ 0 => [ 2 => 'A', 4 => 'B', ], 4 => [ 1 => 'Z', ], ], $request->getSession()->get('revealed_attempted_letters')); } private function createContainer(): ContainerInterface { $router = $this->createStub(UrlGeneratorInterface::class); $router->method('generate')->willReturn('/'); $container = $this->createStub(ContainerInterface::class); $container->method('has')->willReturnCallback(static fn (string $id): bool => match ($id) { 'router' => true, 'security.token_storage' => false, default => false, }); $container->method('get')->willReturnCallback(static fn (string $id) => match ($id) { 'router' => $router, default => null, }); return $container; } }