Files
spigot-base/src/test/java/games/dmg/spigotbase/BaseAdminCommandTest.java
T
dmg 259ea9410c
Release / release (push) Successful in 2m16s
CI / build (push) Successful in 1m3s
feat(spawning): add spawnable block overlay
2026-08-10 22:46:02 -04:00

324 lines
13 KiB
Java

package games.dmg.spigotbase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.UnaryOperator;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
final class BaseAdminCommandTest {
@Test
void adminCanEnableUnlockedSpawnableOverlayForPlayer() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
UUID playerId = UUID.randomUUID();
PlayerState target = PlayerState.newPlayer(playerId, "Builder")
.withAdministrativeLevels(1, 0, 0, 0, 0, false, false, false)
.withBase(
new BaseLocation(UUID.randomUUID(), "world", 0, 64, 0, 0, 0),
Instant.EPOCH
)
.withTotalBlocksPlaced(250);
AtomicReference<PlayerState> updated = new AtomicReference<>();
BaseStateManager stateManager = mock(BaseStateManager.class);
when(stateManager.findByName("Builder")).thenReturn(Optional.of(target));
when(stateManager.update(any(), anyString(), any())).thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
UnaryOperator<PlayerState> operation = invocation.getArgument(2);
PlayerState result = operation.apply(target);
updated.set(result);
return result;
});
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
stateManager,
new AdminProgressionService(
new PluginSettingsProvider(PluginSettings.from(Map.of()))
),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
try (MockedStatic<Bukkit> bukkit = mockStatic(Bukkit.class)) {
bukkit.when(() -> Bukkit.getPlayerExact("Builder")).thenReturn(null);
command.onCommand(sender, null, "baseadmin",
new String[] {"setsetting", "Builder", "spawnable", "enable"});
}
assertTrue(updated.get().spawnableOverlayEnabled());
}
@Test
void invalidPathShowsFriendlyUsage() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
PlayerState target = PlayerState.newPlayer(UUID.randomUUID(), "Builder");
BaseStateManager stateManager = mock(BaseStateManager.class);
when(stateManager.findByName("Builder")).thenReturn(Optional.of(target));
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
stateManager,
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
try (MockedStatic<Bukkit> bukkit = mockStatic(Bukkit.class)) {
bukkit.when(() -> Bukkit.getPlayerExact("Builder")).thenReturn(null);
command.onCommand(sender, null, "baseadmin",
new String[] {"setlevel", "Builder", "unknown", "1"});
}
verify(sender).sendMessage(ChatColor.RED
+ "Usage: /baseadmin setlevel <player> <base|size|flight|warmup|cooldown> <level>");
verify(stateManager, never()).update(any(), anyString(), any());
}
@Test
void autocompletesValidLevelsAndResetConfirmation() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
mock(BaseStateManager.class),
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
assertEquals(
List.of("0", "1", "2", "3", "4"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"setlevel", "Builder", "base", ""})
);
assertEquals(
List.of("0", "1", "2", "3"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"setlevel", "Builder", "flight", ""})
);
assertEquals(
List.of("confirm"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"reset", "Builder", "all", ""})
);
}
@Test
void autocompletesCommandSpecificOptions() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
mock(BaseStateManager.class),
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
assertEquals(
List.of("base", "size", "flight", "warmup", "cooldown"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"setlevel", "Builder", ""})
);
assertEquals(
List.of(
"grass_dirt", "stone", "deepslate", "obsidian", "placements",
"total_placements", "base_breaks"
),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"setprogress", "Builder", ""})
);
assertEquals(
List.of("spawnable"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"setsetting", "Builder", ""})
);
assertEquals(
List.of("enable"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"setsetting", "Builder", "spawnable", "e"})
);
assertEquals(
List.of("personal", "visitor", "all"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"clearcooldown", "Builder", ""})
);
assertEquals(
List.of("size", "flight", "warmup", "cooldown", "all"),
command.onTabComplete(sender, null, "baseadmin",
new String[] {"reset", "Builder", ""})
);
}
@Test
void adminCanChangeSpawnableOverlayUnlockThreshold() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
JavaPlugin plugin = mock(JavaPlugin.class);
FileConfiguration configuration = mock(FileConfiguration.class);
when(plugin.getConfig()).thenReturn(configuration);
when(configuration.get("spawnable-overlay-unlock-placements")).thenReturn(250);
when(configuration.getValues(false)).thenReturn(Map.of(
"spawnable-overlay-unlock-placements", 250
));
PluginSettingsProvider settings = new PluginSettingsProvider(
PluginSettings.from(Map.of())
);
BaseAdminCommand command = new BaseAdminCommand(
plugin,
mock(BaseStateManager.class),
mock(AdminProgressionService.class),
settings
);
try (MockedStatic<PluginSettingsValidator> validator =
mockStatic(PluginSettingsValidator.class)) {
validator.when(() -> PluginSettingsValidator.validateMaterials(
any(PluginSettings.class)
)).thenAnswer(invocation -> invocation.getArgument(0));
command.onCommand(sender, null, "baseadmin", new String[] {
"config", "spawnable-overlay-unlock-placements", "500"
});
}
verify(configuration).set("spawnable-overlay-unlock-placements", 500L);
verify(plugin).saveConfig();
assertEquals(500, settings.current().spawnableOverlayUnlockPlacements());
}
@Test
void autocompletesNumericConfigurationKeys() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
JavaPlugin plugin = mock(JavaPlugin.class);
FileConfiguration configuration = mock(FileConfiguration.class);
when(plugin.getConfig()).thenReturn(configuration);
when(configuration.getValues(false)).thenReturn(Map.of(
"base-unlock-blocks", 250,
"visitor-currency-material", "DIAMOND",
"title-stay-ticks", 70
));
BaseAdminCommand command = new BaseAdminCommand(
plugin,
mock(BaseStateManager.class),
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
assertEquals(
List.of("base-unlock-blocks"),
command.onTabComplete(sender, null, "baseadmin", new String[] {"config", "base"})
);
}
@Test
void autocompletesKnownOfflinePlayers() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
BaseStateManager stateManager = mock(BaseStateManager.class);
PlayerState alex = PlayerState.newPlayer(UUID.randomUUID(), "Alex");
PlayerState blake = PlayerState.newPlayer(UUID.randomUUID(), "Blake");
when(stateManager.knownPlayers()).thenReturn(Map.of(
alex.playerId(), alex,
blake.playerId(), blake
));
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
stateManager,
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
assertEquals(
List.of("Alex", "Blake"),
command.onTabComplete(sender, null, "baseadmin", new String[] {"status", ""})
);
}
@Test
void autocompletesAdminSubcommandsForPermittedSenders() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
mock(BaseStateManager.class),
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
assertEquals(
List.of(
"status", "setlevel", "setprogress", "setsetting", "clearcooldown", "reset",
"config"
),
command.onTabComplete(sender, null, "baseadmin", new String[] {""})
);
}
@Test
void resetBaseRequiresConfirmedCompleteReset() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
PlayerState target = PlayerState.newPlayer(UUID.randomUUID(), "Builder");
BaseStateManager stateManager = mock(BaseStateManager.class);
when(stateManager.findByName("Builder")).thenReturn(Optional.of(target));
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
stateManager,
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
try (MockedStatic<Bukkit> bukkit = mockStatic(Bukkit.class)) {
bukkit.when(() -> Bukkit.getPlayerExact("Builder")).thenReturn(null);
command.onCommand(
sender,
null,
"baseadmin",
new String[] {"reset", "Builder", "base"}
);
}
verify(stateManager, never()).update(any(), anyString(), any());
verify(sender).sendMessage(ChatColor.RED
+ "Resetting base removes all progression. Use: /baseadmin reset Builder all confirm");
}
@Test
void statusDisplaysKnownPlayerProgress() {
CommandSender sender = mock(CommandSender.class);
when(sender.hasPermission("spigotbase.admin")).thenReturn(true);
PlayerState target = PlayerState.newPlayer(UUID.randomUUID(), "Builder");
BaseStateManager stateManager = mock(BaseStateManager.class);
when(stateManager.findByName("Builder")).thenReturn(Optional.of(target));
BaseAdminCommand command = new BaseAdminCommand(
mock(JavaPlugin.class),
stateManager,
mock(AdminProgressionService.class),
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
try (MockedStatic<Bukkit> bukkit = mockStatic(Bukkit.class)) {
bukkit.when(() -> Bukkit.getPlayerExact("Builder")).thenReturn(null);
command.onCommand(sender, null, "baseadmin", new String[] {"status", "Builder"});
}
verify(sender).sendMessage(ChatColor.GOLD + "=== Builder Base Progress ===");
}
}