feat(admin): add Tyrant point grant command
This commit is contained in:
@@ -62,6 +62,93 @@ final class TyrantAdminCommandTest {
|
||||
verify(effects).suppressAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void grantPointAddsAndPersistsOneLevelAndChoice() {
|
||||
UUID tyrant = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||
GameState game = new GameState(
|
||||
GameLifecycle.RUNNING, Optional.of(tyrant), Optional.empty(),
|
||||
Optional.empty(), Optional.empty(), Optional.empty(), Duration.ZERO,
|
||||
2, 1, Set.of(TyrantUnlock.ASSASSIN)
|
||||
);
|
||||
TyrantStateManager manager = mock(TyrantStateManager.class);
|
||||
when(manager.snapshot()).thenReturn(new PersistentState(
|
||||
game, Map.of(tyrant, PlayerState.newPlayer(tyrant, "Tyrant"))
|
||||
));
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
when(sender.hasPermission("spigottyrant.admin")).thenReturn(true);
|
||||
|
||||
command(manager, mock(ManagedRoleEffects.class)).onCommand(
|
||||
sender, mock(Command.class), "tyrantadmin", new String[] {"grantpoint"}
|
||||
);
|
||||
|
||||
verify(manager).replaceState(org.mockito.ArgumentMatchers.argThat(state ->
|
||||
state.game().tyrantLevel() == 3
|
||||
&& state.game().unspentChoices() == 2
|
||||
&& state.game().purchases().equals(Set.of(TyrantUnlock.ASSASSIN))
|
||||
));
|
||||
verify(manager).saveIfDirty();
|
||||
verify(sender).sendMessage(contains("level 3 and 2 unspent choices"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void grantPointRejectsPausedGameWithoutChangingState() {
|
||||
UUID tyrant = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||
GameState paused = new GameState(
|
||||
GameLifecycle.PAUSED, Optional.of(tyrant), Optional.empty(),
|
||||
Optional.empty(), Optional.empty(),
|
||||
Optional.of(Instant.parse("2026-08-14T12:00:00Z")), Duration.ZERO,
|
||||
2, 1, Set.of()
|
||||
);
|
||||
TyrantStateManager manager = mock(TyrantStateManager.class);
|
||||
when(manager.snapshot()).thenReturn(new PersistentState(
|
||||
paused, Map.of(tyrant, PlayerState.newPlayer(tyrant, "Tyrant"))
|
||||
));
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
when(sender.hasPermission("spigottyrant.admin")).thenReturn(true);
|
||||
|
||||
command(manager, mock(ManagedRoleEffects.class)).onCommand(
|
||||
sender, mock(Command.class), "tyrantadmin", new String[] {"grantpoint"}
|
||||
);
|
||||
|
||||
verify(manager, never()).replaceState(org.mockito.ArgumentMatchers.any());
|
||||
verify(sender).sendMessage(contains("must be running"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void grantPointRejectsAdditionalArgumentsWithoutChangingState() {
|
||||
TyrantStateManager manager = mock(TyrantStateManager.class);
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
when(sender.hasPermission("spigottyrant.admin")).thenReturn(true);
|
||||
|
||||
command(manager, mock(ManagedRoleEffects.class)).onCommand(
|
||||
sender, mock(Command.class), "tyrantadmin",
|
||||
new String[] {"grantpoint", "unexpected"}
|
||||
);
|
||||
|
||||
verify(manager, never()).replaceState(org.mockito.ArgumentMatchers.any());
|
||||
verify(sender).sendMessage(contains("Usage: /tyrantadmin grantpoint"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void grantPointRejectsTyrantVacancyWithoutChangingState() {
|
||||
GameState vacant = new GameState(
|
||||
GameLifecycle.RUNNING, Optional.empty(), Optional.empty(),
|
||||
Optional.empty(), Optional.empty(), Optional.empty(), Duration.ZERO,
|
||||
0, 0, Set.of()
|
||||
);
|
||||
TyrantStateManager manager = mock(TyrantStateManager.class);
|
||||
when(manager.snapshot()).thenReturn(new PersistentState(vacant, Map.of()));
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
when(sender.hasPermission("spigottyrant.admin")).thenReturn(true);
|
||||
|
||||
command(manager, mock(ManagedRoleEffects.class)).onCommand(
|
||||
sender, mock(Command.class), "tyrantadmin", new String[] {"grantpoint"}
|
||||
);
|
||||
|
||||
verify(manager, never()).replaceState(org.mockito.ArgumentMatchers.any());
|
||||
verify(sender).sendMessage(contains("no current Tyrant"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void playerCanPersistArenaAtCurrentLocation() {
|
||||
TyrantStateManager manager = mock(TyrantStateManager.class);
|
||||
|
||||
@@ -35,7 +35,7 @@ final class TyrantAdminTabCompleterTest {
|
||||
assertTrue(completer.onTabComplete(
|
||||
admin, command, "tyrantadmin", new String[] {""}
|
||||
).containsAll(java.util.List.of(
|
||||
"status", "start", "pause", "resume", "reset", "arena"
|
||||
"status", "start", "pause", "resume", "reset", "arena", "grantpoint"
|
||||
)));
|
||||
assertEquals(java.util.List.of("Alpha", "Beta"), completer.onTabComplete(
|
||||
admin, command, "tyrantadmin", new String[] {"start", ""}
|
||||
@@ -49,6 +49,9 @@ final class TyrantAdminTabCompleterTest {
|
||||
assertEquals(java.util.List.of("set", "status"), completer.onTabComplete(
|
||||
admin, command, "tyrantadmin", new String[] {"arena", "s"}
|
||||
));
|
||||
assertEquals(java.util.List.of(), completer.onTabComplete(
|
||||
admin, command, "tyrantadmin", new String[] {"grantpoint", ""}
|
||||
));
|
||||
}
|
||||
|
||||
private static Player player(UUID id, String name) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package games.dmg.spigottyrant;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -47,6 +48,38 @@ final class TyrantProgressionServiceTest {
|
||||
assertEquals(paused, service.recordVigilanteDeath(paused, Optional.of(TYRANT)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void administrativePointGrantAddsOneLevelAndChoicePerInvocation() {
|
||||
GameState before = runningState(2, 1, Set.of(TyrantUnlock.ASSASSIN));
|
||||
|
||||
GameState first = service.grantPoint(before);
|
||||
GameState second = service.grantPoint(first);
|
||||
|
||||
assertEquals(4, second.tyrantLevel());
|
||||
assertEquals(3, second.unspentChoices());
|
||||
assertEquals(before.purchases(), second.purchases());
|
||||
assertEquals(before.tyrantId(), second.tyrantId());
|
||||
assertEquals(before.vigilanteId(), second.vigilanteId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void administrativePointGrantRequiresRunningGameAndCurrentTyrant() {
|
||||
GameState running = runningState(0, 1, Set.of());
|
||||
GameState paused = new GameState(
|
||||
GameLifecycle.PAUSED, running.tyrantId(), running.vigilanteId(),
|
||||
running.pendingTyrant(), running.pendingVigilante(),
|
||||
Optional.of(java.time.Instant.parse("2026-08-14T12:00:00Z")),
|
||||
Duration.ZERO, 0, 1, Set.of()
|
||||
);
|
||||
GameState vacant = new GameState(
|
||||
GameLifecycle.RUNNING, Optional.empty(), Optional.empty(), Optional.empty(),
|
||||
Optional.empty(), Optional.empty(), Duration.ZERO, 0, 0, Set.of()
|
||||
);
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> service.grantPoint(paused));
|
||||
assertThrows(IllegalStateException.class, () -> service.grantPoint(vacant));
|
||||
}
|
||||
|
||||
@Test
|
||||
void purchaseConsumesOneChoiceAndCannotBeBoughtTwice() {
|
||||
GameState before = runningState(1, 2, Set.of());
|
||||
|
||||
Reference in New Issue
Block a user