feat: add realtime codenames game
This commit is contained in:
126
src/test/java/at/dslan/codenames/game/GameRoomServiceTest.java
Normal file
126
src/test/java/at/dslan/codenames/game/GameRoomServiceTest.java
Normal file
@@ -0,0 +1,126 @@
|
||||
package at.dslan.codenames.game;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import at.dslan.codenames.game.RoomSnapshot.GamePhase;
|
||||
import at.dslan.codenames.game.RoomSnapshot.GameStatus;
|
||||
import at.dslan.codenames.game.RoomSnapshot.SeatRole;
|
||||
import at.dslan.codenames.game.RoomSnapshot.Team;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class GameRoomServiceTest {
|
||||
|
||||
private GameRoomService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
WordBank wordBank = (random, count) -> List.of(
|
||||
"Jahr", "Mensch", "Zeit", "Kind", "Tag",
|
||||
"Leben", "Thema", "Frage", "Arbeit", "Welt",
|
||||
"Buch", "Haus", "Spiel", "Herz", "Wasser",
|
||||
"Berg", "Baum", "Fisch", "Lampe", "Karte",
|
||||
"Ring", "Kamera", "Planet", "Turm", "Kompass"
|
||||
).subList(0, count);
|
||||
service = new GameRoomService(wordBank, new Random(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
void startsGameWhenAllSeatsAreFilled() {
|
||||
GameRoomService.RoomSession room = service.createRoom("Host");
|
||||
GameRoomService.RoomSession redOperative = service.joinRoom(room.roomId(), "Roter Ermittler");
|
||||
GameRoomService.RoomSession blueSpymaster = service.joinRoom(room.roomId(), "Blauer Hinweis");
|
||||
GameRoomService.RoomSession blueOperative = service.joinRoom(room.roomId(), "Blauer Ermittler");
|
||||
|
||||
service.takeSeat(room.roomId(), room.participantId(), Team.RED, SeatRole.SPYMASTER);
|
||||
service.takeSeat(room.roomId(), redOperative.participantId(), Team.RED, SeatRole.OPERATIVE);
|
||||
service.takeSeat(room.roomId(), blueSpymaster.participantId(), Team.BLUE, SeatRole.SPYMASTER);
|
||||
service.takeSeat(room.roomId(), blueOperative.participantId(), Team.BLUE, SeatRole.OPERATIVE);
|
||||
|
||||
service.startGame(room.roomId(), room.participantId());
|
||||
|
||||
RoomSnapshot snapshot = service.getSnapshot(room.roomId(), room.participantId());
|
||||
assertThat(snapshot.game().status()).isEqualTo(GameStatus.IN_PROGRESS);
|
||||
assertThat(snapshot.game().phase()).isEqualTo(GamePhase.CLUE);
|
||||
assertThat(snapshot.game().cards()).hasSize(25);
|
||||
assertThat(snapshot.game().redRemaining() + snapshot.game().blueRemaining()).isEqualTo(17);
|
||||
}
|
||||
|
||||
@Test
|
||||
void correctGuessConsumesAttemptAndCanBeEndedManually() {
|
||||
ReadyRoom room = createReadyRoom();
|
||||
RoomSnapshot hostView = service.getSnapshot(room.roomId(), room.redSpymasterId());
|
||||
Team currentTeam = hostView.game().currentTeam();
|
||||
|
||||
String spymasterId = currentTeam == Team.RED ? room.redSpymasterId() : room.blueSpymasterId();
|
||||
String operativeId = currentTeam == Team.RED ? room.redOperativeId() : room.blueOperativeId();
|
||||
int matchingCardIndex = findHiddenCardFor(room.roomId(), spymasterId, currentTeam);
|
||||
|
||||
service.submitClue(room.roomId(), spymasterId, "Atlas", 1);
|
||||
service.guessCard(room.roomId(), operativeId, matchingCardIndex);
|
||||
|
||||
RoomSnapshot afterGuess = service.getSnapshot(room.roomId(), operativeId);
|
||||
assertThat(afterGuess.game().phase()).isEqualTo(GamePhase.GUESSING);
|
||||
assertThat(afterGuess.game().remainingGuesses()).isEqualTo(1);
|
||||
|
||||
service.endTurn(room.roomId(), operativeId);
|
||||
|
||||
RoomSnapshot afterTurn = service.getSnapshot(room.roomId(), operativeId);
|
||||
assertThat(afterTurn.game().phase()).isEqualTo(GamePhase.CLUE);
|
||||
assertThat(afterTurn.game().currentTeam()).isEqualTo(currentTeam == Team.RED ? Team.BLUE : Team.RED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsGameStartWithoutCompleteRoster() {
|
||||
GameRoomService.RoomSession room = service.createRoom("Host");
|
||||
service.takeSeat(room.roomId(), room.participantId(), Team.RED, SeatRole.SPYMASTER);
|
||||
|
||||
assertThatThrownBy(() -> service.startGame(room.roomId(), room.participantId()))
|
||||
.isInstanceOf(GameRoomService.GameException.class)
|
||||
.hasMessageContaining("vier besetzte Rollen");
|
||||
}
|
||||
|
||||
private ReadyRoom createReadyRoom() {
|
||||
GameRoomService.RoomSession redSpymaster = service.createRoom("Host");
|
||||
GameRoomService.RoomSession redOperative = service.joinRoom(redSpymaster.roomId(), "Rot");
|
||||
GameRoomService.RoomSession blueSpymaster = service.joinRoom(redSpymaster.roomId(), "Blau");
|
||||
GameRoomService.RoomSession blueOperative = service.joinRoom(redSpymaster.roomId(), "Blau 2");
|
||||
|
||||
service.takeSeat(redSpymaster.roomId(), redSpymaster.participantId(), Team.RED, SeatRole.SPYMASTER);
|
||||
service.takeSeat(redSpymaster.roomId(), redOperative.participantId(), Team.RED, SeatRole.OPERATIVE);
|
||||
service.takeSeat(redSpymaster.roomId(), blueSpymaster.participantId(), Team.BLUE, SeatRole.SPYMASTER);
|
||||
service.takeSeat(redSpymaster.roomId(), blueOperative.participantId(), Team.BLUE, SeatRole.OPERATIVE);
|
||||
service.startGame(redSpymaster.roomId(), redSpymaster.participantId());
|
||||
|
||||
return new ReadyRoom(
|
||||
redSpymaster.roomId(),
|
||||
redSpymaster.participantId(),
|
||||
redOperative.participantId(),
|
||||
blueSpymaster.participantId(),
|
||||
blueOperative.participantId()
|
||||
);
|
||||
}
|
||||
|
||||
private int findHiddenCardFor(String roomId, String viewerId, Team team) {
|
||||
return service.getSnapshot(roomId, viewerId).game().cards().stream()
|
||||
.filter(card -> !card.revealed())
|
||||
.filter(card -> card.visibleAffiliation() == (team == Team.RED
|
||||
? RoomSnapshot.CardAffiliation.RED
|
||||
: RoomSnapshot.CardAffiliation.BLUE))
|
||||
.findFirst()
|
||||
.orElseThrow()
|
||||
.index();
|
||||
}
|
||||
|
||||
private record ReadyRoom(
|
||||
String roomId,
|
||||
String redSpymasterId,
|
||||
String redOperativeId,
|
||||
String blueSpymasterId,
|
||||
String blueOperativeId
|
||||
) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user