Trying to add waiting pages

This commit is contained in:
Frank
2026-01-08 19:32:13 +01:00
parent 37507bd169
commit c4c989db4c
7 changed files with 505 additions and 15 deletions

View File

@@ -8,12 +8,14 @@ use App\Game\Entity\Player;
use App\Game\Entity\Session;
use App\Game\Entity\SessionSetting;
use App\Game\Enum\GameStatus;
use App\Game\Enum\SessionStatus;
use App\Game\Enum\SessionSettingType;
use App\Game\Service\GameDashboardService;
use App\Tech\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use App\Game\Repository\GameRepository;
use App\Game\Repository\SessionRepository;
use Symfony\Component\Mercure\HubInterface;
use PHPUnit\Framework\TestCase;
class GameDashboardServiceTest extends TestCase
@@ -21,6 +23,7 @@ class GameDashboardServiceTest extends TestCase
private $entityManager;
private $gameRepository;
private $sessionRepository;
private $hub;
private $service;
protected function setUp(): void
@@ -28,11 +31,14 @@ class GameDashboardServiceTest extends TestCase
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->gameRepository = $this->createMock(GameRepository::class);
$this->sessionRepository = $this->createMock(SessionRepository::class);
$this->hub = $this->createMock(HubInterface::class);
$this->service = new GameDashboardService(
$this->gameRepository,
$this->sessionRepository,
$this->entityManager
$this->entityManager,
$this->hub,
'http://localhost/topic'
);
}
@@ -193,24 +199,219 @@ class GameDashboardServiceTest extends TestCase
$this->assertCount(1, $session->getPlayers());
}
public function testLeaveSessionDeletesSessionIfLastPlayer(): void
public function testToggleReady(): void
{
$user = new User();
$game = new Game();
$game->setNumberOfPlayers(1);
$session = new Session();
$session->setStatus(\App\Game\Enum\SessionStatus::CREATED);
$session->setTimer(0);
$session->setGame($game);
$session->setStatus(SessionStatus::READY);
$player = new Player();
$player->setUser($user);
$player->setSession($session);
$player->setScreen(1);
$session->addPlayer($player);
$this->entityManager->expects($this->exactly(2))
$repo = $this->createMock(\App\Game\Repository\SessionSettingRepository::class);
$this->entityManager->method('getRepository')
->willReturn($repo);
// First call: toggle ON
$repo->expects($this->atLeastOnce())
->method('getSetting')
->willReturn(null); // No setting initially
$this->entityManager->expects($this->atLeastOnce())
->method('persist')
->with($this->callback(function($entity) {
return $entity instanceof SessionSetting && $entity->getName() === SessionSettingType::READY_AT_FOR_PLAYER1;
}));
$result = $this->service->toggleReady($session, $user);
$this->assertTrue($result);
}
public function testCheckAllPlayersReadyTransitionsStatus(): void
{
$game = new Game();
$game->setNumberOfPlayers(2);
$session = new Session();
$session->setGame($game);
$session->setStatus(SessionStatus::READY);
$player1 = new Player();
$player1->setScreen(1);
$session->addPlayer($player1);
$player2 = new Player();
$player2->setScreen(2);
$session->addPlayer($player2);
$repo = $this->createMock(\App\Game\Repository\SessionSettingRepository::class);
$this->entityManager->method('getRepository')
->willReturn($repo);
$setting1 = new SessionSetting();
$setting1->setName(SessionSettingType::READY_AT_FOR_PLAYER1);
$setting1->setValue((string)time());
$setting1->setPlayer($player1);
$setting2 = new SessionSetting();
$setting2->setName(SessionSettingType::READY_AT_FOR_PLAYER2);
$setting2->setValue((string)time());
$setting2->setPlayer($player2);
$repo->method('getSetting')
->willReturnCallback(function($s, $name, $p) use ($setting1, $setting2) {
if ($name === SessionSettingType::READY_AT_FOR_PLAYER1) return $setting1;
if ($name === SessionSettingType::READY_AT_FOR_PLAYER2) return $setting2;
return null;
});
$this->service->checkAllPlayersReady($session);
$this->assertEquals(SessionStatus::PLAYING, $session->getStatus());
}
public function testCheckAllPlayersReadyTimeouts(): void
{
$game = new Game();
$game->setNumberOfPlayers(2);
$session = new Session();
$session->setGame($game);
$session->setStatus(SessionStatus::READY);
$player1 = new Player();
$player1->setScreen(1);
$session->addPlayer($player1);
$player2 = new Player();
$player2->setScreen(2);
$session->addPlayer($player2);
$repo = $this->createMock(\App\Game\Repository\SessionSettingRepository::class);
$this->entityManager->method('getRepository')
->willReturn($repo);
$setting1 = new SessionSetting();
$setting1->setName(SessionSettingType::READY_AT_FOR_PLAYER1);
$setting1->setValue((string)(time() - 70)); // Timed out
$setting1->setPlayer($player1);
$session->addSetting($setting1);
$repo->method('getSetting')
->willReturnCallback(function($s, $name, $p) use ($setting1) {
if ($name === SessionSettingType::READY_AT_FOR_PLAYER1) return $setting1;
return null;
});
$this->entityManager->expects($this->once())
->method('remove')
->with($setting1);
$this->service->checkAllPlayersReady($session);
$this->assertEquals(SessionStatus::READY, $session->getStatus());
}
public function testJoinSessionTriggersStartSessionWhenFull(): void
{
$user = new User();
$user->setUsername('testuser');
$game = new Game();
$game->setNumberOfPlayers(2);
$session = new Session();
$session->setGame($game);
$session->setStatus(\App\Game\Enum\SessionStatus::CREATED);
$existingUser = new User();
$existingUser->setUsername('existing');
$existingPlayer = new Player();
$existingPlayer->setUser($existingUser);
$session->addPlayer($existingPlayer);
$setting = new SessionSetting();
$setting->setSession($session);
$setting->setName(SessionSettingType::INVITE_CODE);
$setting->setValue('abc-123');
$repo = $this->createMock(\Doctrine\ORM\EntityRepository::class);
$this->entityManager->method('getRepository')
->willReturn($repo);
$repo->method('findOneBy')
->willReturn($setting);
// Expectation:
// 1. Persist new Player
// 2. Persist Player 1 (existing) screen update
// 3. Persist Player 2 (new) screen update
// 4. Persist Session status update
// 5. 5 Settings for Player 1
// 6. 5 Settings for Player 2
// Total = 1 + 1 + 1 + 1 + 5 + 5 = 14 persists
$this->entityManager->expects($this->exactly(14))
->method('persist');
$result = $this->service->joinSession('abc-123', $user);
$this->assertTrue($result);
$this->assertEquals(\App\Game\Enum\SessionStatus::READY, $session->getStatus());
}
public function testLeaveSessionRevertsFromReady(): void
{
$user = new User();
$user->setUsername('testuser');
$session = new Session();
$session->setStatus(\App\Game\Enum\SessionStatus::READY);
$session->setTimer(0);
$player1 = new Player();
$player1->setUser($user);
$player1->setScreen(1);
$player1->setSession($session);
$session->addPlayer($player1);
$player2 = new Player();
$player2->setUser(new User());
$player2->setScreen(2);
$player2->setSession($session);
$session->addPlayer($player2);
$this->entityManager->expects($this->exactly(1))
->method('remove');
// 1. Player, 2. Session
// 1. Player1, any settings (none in this test setup)
$result = $this->service->leaveSession($session, $user);
$this->assertTrue($result);
$this->assertEquals(\App\Game\Enum\SessionStatus::CREATED, $session->getStatus());
$this->assertNull($player2->getScreen());
}
public function testCreateSessionForOnePlayerGame(): void
{
$game = new Game();
$game->setStatus(GameStatus::OPEN);
$game->setNumberOfPlayers(1);
$user = new User();
$user->setUsername('testuser');
// 1. Session persist
// 2. Player persist
// 3. Player screen persist (during startSession)
// 4. Session status persist (during startSession)
// 5. 5 Settings for Player (during startSession)
// Total = 1 + 1 + 1 + 1 + 5 = 9 persists
$this->entityManager->expects($this->exactly(9))
->method('persist');
$session = $this->service->createSession($game, $user, false);
$this->assertInstanceOf(Session::class, $session);
$this->assertEquals(\App\Game\Enum\SessionStatus::READY, $session->getStatus());
}
}