feat(admin): complete configurable progression
Release / release (push) Successful in 3m57s
CI / build (push) Successful in 54s

This commit is contained in:
dmg
2026-08-09 15:12:04 -04:00
parent c87d923cad
commit 8b1064b971
41 changed files with 924 additions and 626 deletions
@@ -0,0 +1,34 @@
package games.dmg.spigotbase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
final class AdminProgressCounterTest {
private final AdminProgressionService service = new AdminProgressionService(
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
@Test
void settingPlacementCounterEvaluatesBaseAndWarmupTiers() {
PlayerState player = PlayerState.newPlayer(UUID.randomUUID(), "Alex");
PlayerState updated = service.setProgress(player, ProgressCounter.PLACEMENTS, 2_000);
assertEquals(3, updated.baseLevel());
assertEquals(2, updated.warmupLevel());
assertEquals(2_000, updated.blocksPlacedInBase());
}
@Test
void settingBaseBreakCounterEvaluatesCooldownTier() {
PlayerState player = PlayerState.newPlayer(UUID.randomUUID(), "Alex");
PlayerState updated = service.setProgress(player, ProgressCounter.BASE_BREAKS, 5_000);
assertEquals(3, updated.baseLevel());
assertEquals(4, updated.cooldownLevel());
}
}
@@ -0,0 +1,37 @@
package games.dmg.spigotbase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
final class AdminResetPathTest {
private final AdminProgressionService service = new AdminProgressionService(
new PluginSettingsProvider(PluginSettings.from(Map.of()))
);
@Test
void resettingSizeClearsItsLevelsAndCounters() {
PlayerState player = PlayerState.newPlayer(UUID.randomUUID(), "Alex")
.withGrassAndDirtProgress(500, 2)
.withSizeProgress(500, 1_000, 1_000, 3);
PlayerState reset = service.resetPath(player, ProgressionPath.SIZE);
assertEquals(0, reset.sizeLevel());
assertEquals(0, reset.stoneBroken());
assertEquals(0, reset.deepslateBroken());
assertEquals(0, reset.obsidianBroken());
}
@Test
void resettingBaseCascadesAllDependentProgress() {
PlayerState player = PlayerState.newPlayer(UUID.randomUUID(), "Alex")
.withAdministrativeLevels(4, 3, 3, 3, 4, true, true, true);
PlayerState reset = service.resetPath(player, ProgressionPath.BASE);
assertEquals(PlayerState.newPlayer(player.playerId(), player.latestName()), reset);
}
}
@@ -0,0 +1,23 @@
package games.dmg.spigotbase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.Duration;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
final class PluginSettingsProviderTest {
@Test
void servicesObserveValidatedRuntimeUpdates() {
PluginSettingsProvider provider =
new PluginSettingsProvider(PluginSettings.from(Map.of()));
TeleportPolicy policy = new TeleportPolicy(provider);
PlayerState player = PlayerState.newPlayer(UUID.randomUUID(), "Alex")
.withGrassAndDirtProgress(500, 3);
provider.update(PluginSettings.from(Map.of("initial-warmup-seconds", 20)));
assertEquals(Duration.ofSeconds(20), policy.warmup(player));
}
}
@@ -56,6 +56,26 @@ final class YamlBaseStateRepositoryTest {
assertFalse(loaded.players().containsKey(playerId));
}
@Test
void preservesUnknownForwardCompatibleFieldsWhenSaving() throws Exception {
UUID playerId = UUID.randomUUID();
Path stateFile = temporaryDirectory.resolve("state.yml");
Files.writeString(stateFile, """
future-root: retained
players:
%s:
name: Alex
future-player-field: retained
""".formatted(playerId));
YamlBaseStateRepository repository = new YamlBaseStateRepository(stateFile);
repository.save(repository.load());
String saved = Files.readString(stateFile);
org.junit.jupiter.api.Assertions.assertTrue(saved.contains("future-root: retained"));
org.junit.jupiter.api.Assertions.assertTrue(saved.contains("future-player-field: retained"));
}
@Test
void missingFileLoadsEmptyState() throws Exception {
YamlBaseStateRepository repository =