From 596eec76d93d803236a2ae1f26465cca1ce54641 Mon Sep 17 00:00:00 2001 From: chafficui Date: Fri, 20 Feb 2026 18:40:42 +0100 Subject: [PATCH] feat: Add /mininglevels info command (#38) --- .../MiningLevelsCommandListener.java | 8 +- .../listeners/commands/LevelingCommands.java | 15 ++ .../mininglevels/utils/ConfigStrings.java | 1 + src/main/resources/plugin.yml | 3 + .../listeners/commands/InfoCommandTest.java | 133 ++++++++++++++++++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/test/java/de/chafficplugins/mininglevels/listeners/commands/InfoCommandTest.java diff --git a/src/main/java/de/chafficplugins/mininglevels/listeners/MiningLevelsCommandListener.java b/src/main/java/de/chafficplugins/mininglevels/listeners/MiningLevelsCommandListener.java index 730354a..130e285 100644 --- a/src/main/java/de/chafficplugins/mininglevels/listeners/MiningLevelsCommandListener.java +++ b/src/main/java/de/chafficplugins/mininglevels/listeners/MiningLevelsCommandListener.java @@ -84,8 +84,12 @@ public boolean onCommand(CommandSender sender, Command command, String label, St return true; } case "info" -> { - sender.sendMessage("§aMining Levels by §c" + plugin.getDescription().getAuthors()); - sender.sendMessage("§aVersion: §c" + plugin.getDescription().getVersion()); + if(!hasOnePermissions(sender, "mininglevels.info")) { + sendMessage(sender, NO_PERMISSION); + return true; + } + LevelingCommands.info(sender); + return true; } case "self" -> { if(!(sender instanceof Player)) { diff --git a/src/main/java/de/chafficplugins/mininglevels/listeners/commands/LevelingCommands.java b/src/main/java/de/chafficplugins/mininglevels/listeners/commands/LevelingCommands.java index 4aef3ee..c18d818 100644 --- a/src/main/java/de/chafficplugins/mininglevels/listeners/commands/LevelingCommands.java +++ b/src/main/java/de/chafficplugins/mininglevels/listeners/commands/LevelingCommands.java @@ -74,6 +74,21 @@ public static void level(CommandSender sender, String[] args) { sendMessage(sender, USAGE_LEVEL); } + public static void info(CommandSender sender) { + if(!(sender instanceof Player player)) { + sendMessage(sender, NO_CONSOLE_COMMAND); + return; + } + MiningPlayer miningPlayer = MiningPlayer.getMiningPlayer(player.getUniqueId()); + if(miningPlayer == null) { + sendMessage(sender, ERROR_OCCURRED); + return; + } + MiningLevel miningLevel = miningPlayer.getLevel(); + sendMessage(sender, CURRENT_LEVEL, miningLevel.getName()); + sendMessage(sender, CURRENT_XP, String.valueOf(miningPlayer.getXp()), String.valueOf(miningLevel.getNextLevelXP())); + } + public static void leaderboard(CommandSender sender) { //sort miningPlayers by level and xp List miningPlayers = getSortedPlayers(); diff --git a/src/main/java/de/chafficplugins/mininglevels/utils/ConfigStrings.java b/src/main/java/de/chafficplugins/mininglevels/utils/ConfigStrings.java index d096c3a..a90e6a1 100644 --- a/src/main/java/de/chafficplugins/mininglevels/utils/ConfigStrings.java +++ b/src/main/java/de/chafficplugins/mininglevels/utils/ConfigStrings.java @@ -17,6 +17,7 @@ public class ConfigStrings { public final static String PERMISSION_RELOAD = "mininglevels.reload"; public final static String PERMISSION_EDITOR = "mininglevels.editor"; public final static String PERMISSIONS_LEADERBOARD = "mininglevels.leaderboard"; + public final static String PERMISSION_INFO = "mininglevels.info"; //Configuration public final static String LVL_UP_SOUND = "levelup_sound"; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index dc9392b..aa4665a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -16,3 +16,6 @@ commands: - mr usage: /miningrewards permissions: + mininglevels.info: + description: Allows the player to view their mining level and XP + default: true diff --git a/src/test/java/de/chafficplugins/mininglevels/listeners/commands/InfoCommandTest.java b/src/test/java/de/chafficplugins/mininglevels/listeners/commands/InfoCommandTest.java new file mode 100644 index 0000000..775b21e --- /dev/null +++ b/src/test/java/de/chafficplugins/mininglevels/listeners/commands/InfoCommandTest.java @@ -0,0 +1,133 @@ +package de.chafficplugins.mininglevels.listeners.commands; + +import de.chafficplugins.mininglevels.api.MiningLevel; +import de.chafficplugins.mininglevels.api.MiningPlayer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests for the /mininglevels info command logic. + *

+ * Since CrucialLib's Localizer is not available in tests, we verify that + * the data retrieval and state used by the info command is correct: + * the player's MiningPlayer exists and exposes the expected level and XP. + */ +class InfoCommandTest { + + private static ServerMock server; + + @BeforeAll + static void setUpServer() { + server = MockBukkit.mock(); + } + + @AfterAll + static void tearDown() { + MockBukkit.unmock(); + } + + @BeforeEach + void setUp() { + MiningPlayer.miningPlayers.clear(); + MiningLevel.miningLevels.clear(); + MiningLevel.miningLevels.add(new MiningLevel("Beginner", 100, 0)); + MiningLevel.miningLevels.add(new MiningLevel("Apprentice", 300, 1)); + MiningLevel.miningLevels.add(new MiningLevel("Expert", 500, 2)); + } + + @Test + void infoCommand_playerHasLevel0_shouldShowBeginnerLevelAndZeroXp() { + PlayerMock mockPlayer = server.addPlayer(); + MiningPlayer mp = new MiningPlayer(mockPlayer.getUniqueId(), 0, 0); + + MiningLevel level = mp.getLevel(); + assertNotNull(level); + assertEquals("Beginner", level.getName()); + assertEquals(0, mp.getXp()); + assertEquals(100, level.getNextLevelXP()); + } + + @Test + void infoCommand_playerHasLevel1WithXp_shouldShowApprenticeAndXp() { + PlayerMock mockPlayer = server.addPlayer(); + MiningPlayer mp = new MiningPlayer(mockPlayer.getUniqueId(), 1, 150); + + MiningLevel level = mp.getLevel(); + assertNotNull(level); + assertEquals("Apprentice", level.getName()); + assertEquals(150, mp.getXp()); + assertEquals(300, level.getNextLevelXP()); + } + + @Test + void infoCommand_playerAtMaxLevel_shouldShowExpertLevel() { + PlayerMock mockPlayer = server.addPlayer(); + MiningPlayer mp = new MiningPlayer(mockPlayer.getUniqueId(), 2, 400); + + MiningLevel level = mp.getLevel(); + assertNotNull(level); + assertEquals("Expert", level.getName()); + assertEquals(400, mp.getXp()); + assertEquals(500, level.getNextLevelXP()); + } + + @Test + void infoCommand_noMiningPlayer_shouldReturnNull() { + PlayerMock mockPlayer = server.addPlayer(); + + MiningPlayer mp = MiningPlayer.getMiningPlayer(mockPlayer.getUniqueId()); + assertNull(mp); + } + + @Test + void infoCommand_afterLevelChange_shouldReflectNewLevel() { + PlayerMock mockPlayer = server.addPlayer(); + MiningPlayer mp = new MiningPlayer(mockPlayer.getUniqueId(), 0, 50); + + assertEquals("Beginner", mp.getLevel().getName()); + assertEquals(50, mp.getXp()); + + mp.setLevel(2); + mp.setXp(450); + + assertEquals("Expert", mp.getLevel().getName()); + assertEquals(450, mp.getXp()); + } + + @Test + void infoCommand_requiresPlayerSender() { + // The info command should only work for Player senders. + // Console senders should get a "no console command" response. + // Verified by the instanceof Player check in LevelingCommands.info(). + UUID consoleUUID = UUID.randomUUID(); + MiningPlayer mp = MiningPlayer.getMiningPlayer(consoleUUID); + assertNull(mp, "Console has no MiningPlayer"); + } + + @Test + void infoCommand_correctPlayerLookup_shouldFindRightPlayer() { + PlayerMock player1 = server.addPlayer(); + PlayerMock player2 = server.addPlayer(); + new MiningPlayer(player1.getUniqueId(), 0, 25); + new MiningPlayer(player2.getUniqueId(), 2, 350); + + MiningPlayer mp1 = MiningPlayer.getMiningPlayer(player1.getUniqueId()); + MiningPlayer mp2 = MiningPlayer.getMiningPlayer(player2.getUniqueId()); + + assertNotNull(mp1); + assertNotNull(mp2); + assertEquals("Beginner", mp1.getLevel().getName()); + assertEquals(25, mp1.getXp()); + assertEquals("Expert", mp2.getLevel().getName()); + assertEquals(350, mp2.getXp()); + } +}