163 lines
6.7 KiB
Java
163 lines
6.7 KiB
Java
package games.dmg.spigottyrant;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
import java.time.Duration;
|
|
import java.time.Instant;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
final class RoleMaintenanceServiceTest {
|
|
private static final UUID TYRANT = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
|
private static final UUID VIGILANTE = UUID.fromString("22222222-2222-2222-2222-222222222222");
|
|
private static final UUID CANDIDATE = UUID.fromString("33333333-3333-3333-3333-333333333333");
|
|
private static final UUID OTHER = UUID.fromString("44444444-4444-4444-4444-444444444444");
|
|
private static final UUID FOLLOWER = UUID.fromString("55555555-5555-5555-5555-555555555555");
|
|
private static final Instant NOW = Instant.parse("2026-08-14T12:00:00Z");
|
|
private final RoleMaintenanceService service = new RoleMaintenanceService(
|
|
new TyrantSuccessionService(), Duration.ofHours(48)
|
|
);
|
|
|
|
@Test
|
|
void legacyPendingTyrantIsClearedIntoArenaVacancy() {
|
|
GameState game = game(
|
|
Optional.empty(), Optional.empty(),
|
|
Optional.of(new PendingSelection(CANDIDATE, NOW.plusSeconds(60))),
|
|
Optional.empty()
|
|
);
|
|
PersistentState state = new PersistentState(game, players(active(CANDIDATE)));
|
|
|
|
LifecycleState maintained = service.maintain(state, NOW);
|
|
|
|
assertEquals(Optional.empty(), maintained.game().tyrantId());
|
|
assertEquals(Optional.empty(), maintained.game().pendingTyrant());
|
|
}
|
|
|
|
@Test
|
|
void legacyPendingVigilanteIsClearedForArenaSuccession() {
|
|
GameState game = game(
|
|
Optional.of(TYRANT), Optional.empty(), Optional.empty(),
|
|
Optional.of(new PendingSelection(CANDIDATE, NOW.plusSeconds(60)))
|
|
);
|
|
PersistentState state = new PersistentState(game, players(
|
|
active(TYRANT), active(CANDIDATE)
|
|
));
|
|
|
|
LifecycleState maintained = service.maintain(state, NOW);
|
|
|
|
assertEquals(Optional.empty(), maintained.game().vigilanteId());
|
|
assertEquals(Optional.empty(), maintained.game().pendingVigilante());
|
|
}
|
|
|
|
@Test
|
|
void expiredLegacyPendingVigilanteOpensArenaInsteadOfRerolling() {
|
|
GameState game = game(
|
|
Optional.of(TYRANT), Optional.empty(), Optional.empty(),
|
|
Optional.of(new PendingSelection(CANDIDATE, NOW.minusSeconds(1)))
|
|
);
|
|
PersistentState state = new PersistentState(game, players(
|
|
active(TYRANT), active(CANDIDATE), active(OTHER)
|
|
));
|
|
|
|
LifecycleState maintained = service.maintain(state, NOW);
|
|
|
|
assertEquals(Optional.empty(), maintained.game().vigilanteId());
|
|
assertEquals(Optional.empty(), maintained.game().pendingVigilante());
|
|
}
|
|
|
|
@Test
|
|
void inactiveVigilanteOpensArenaAndFollowersAreCleared() {
|
|
PlayerState follower = withFollower(
|
|
withLogin(active(FOLLOWER), NOW.minus(Duration.ofHours(25))),
|
|
VIGILANTE
|
|
);
|
|
PlayerState staleVigilante = withLogin(active(VIGILANTE), NOW.minus(Duration.ofHours(49)));
|
|
GameState game = game(
|
|
Optional.of(TYRANT), Optional.of(VIGILANTE), Optional.empty(), Optional.empty()
|
|
);
|
|
PersistentState state = new PersistentState(game, Map.of(
|
|
TYRANT, active(TYRANT), VIGILANTE, staleVigilante,
|
|
FOLLOWER, follower, OTHER, active(OTHER)
|
|
));
|
|
|
|
LifecycleState maintained = service.maintain(state, NOW);
|
|
|
|
assertEquals(Optional.empty(), maintained.game().vigilanteId());
|
|
assertEquals(Optional.empty(), maintained.players().get(FOLLOWER).followerOf());
|
|
assertEquals(Optional.of(TYRANT), maintained.game().tyrantId());
|
|
}
|
|
|
|
@Test
|
|
void inactiveTyrantEndsReignAndOpensArena() {
|
|
PlayerState staleTyrant = withLogin(
|
|
active(TYRANT), NOW.minus(Duration.ofHours(48))
|
|
);
|
|
PlayerState successor = new PlayerState(
|
|
OTHER, "Successor", Optional.of(NOW.minusSeconds(60)), Optional.empty(),
|
|
TyrantClass.FIXER, Optional.of(VIGILANTE), Map.of(), Set.of(),
|
|
java.util.List.of()
|
|
);
|
|
GameState game = new GameState(
|
|
GameLifecycle.RUNNING, Optional.of(TYRANT), Optional.of(VIGILANTE),
|
|
Optional.empty(), Optional.empty(), Optional.empty(), Duration.ZERO,
|
|
5, 0, Set.of(TyrantUnlock.FIXER)
|
|
);
|
|
PersistentState state = new PersistentState(game, Map.of(
|
|
TYRANT, staleTyrant, VIGILANTE, active(VIGILANTE), OTHER, successor
|
|
));
|
|
|
|
LifecycleState maintained = service.maintain(state, NOW);
|
|
|
|
assertEquals(Optional.empty(), maintained.game().tyrantId());
|
|
assertEquals(Optional.empty(), maintained.game().pendingTyrant());
|
|
assertEquals(0, maintained.game().tyrantLevel());
|
|
assertEquals(1, maintained.game().unspentChoices());
|
|
assertEquals(Set.of(), maintained.game().purchases());
|
|
assertEquals(TyrantClass.NONE, maintained.players().get(OTHER).tyrantClass());
|
|
assertEquals(Optional.empty(), maintained.players().get(OTHER).followerOf());
|
|
}
|
|
|
|
private static GameState game(
|
|
Optional<UUID> tyrant,
|
|
Optional<UUID> vigilante,
|
|
Optional<PendingSelection> pendingTyrant,
|
|
Optional<PendingSelection> pendingVigilante
|
|
) {
|
|
return new GameState(
|
|
GameLifecycle.RUNNING, tyrant, vigilante, pendingTyrant, pendingVigilante,
|
|
Optional.empty(), Duration.ZERO, 1, 0, Set.of()
|
|
);
|
|
}
|
|
|
|
private static Map<UUID, PlayerState> players(PlayerState... players) {
|
|
java.util.HashMap<UUID, PlayerState> map = new java.util.HashMap<>();
|
|
for (PlayerState player : players) {
|
|
map.put(player.playerId(), player);
|
|
}
|
|
return Map.copyOf(map);
|
|
}
|
|
|
|
private static PlayerState active(UUID id) {
|
|
return withLogin(PlayerState.newPlayer(id, id.toString()), NOW.minusSeconds(60));
|
|
}
|
|
|
|
private static PlayerState withLogin(PlayerState player, Instant login) {
|
|
return new PlayerState(
|
|
player.playerId(), player.latestName(), Optional.of(login), player.optedOutUntil(),
|
|
player.tyrantClass(), player.followerOf(), player.cooldownEnds(),
|
|
player.readyAbilityItems(), player.capturedMobs()
|
|
);
|
|
}
|
|
|
|
private static PlayerState withFollower(PlayerState player, UUID vigilante) {
|
|
return new PlayerState(
|
|
player.playerId(), player.latestName(), player.lastLogin(), player.optedOutUntil(),
|
|
player.tyrantClass(), Optional.of(vigilante), player.cooldownEnds(),
|
|
player.readyAbilityItems(), player.capturedMobs()
|
|
);
|
|
}
|
|
}
|