diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index b2967c2..2cd562e 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -23,3 +23,16 @@ jobs: uses: gradle/actions/setup-gradle@v4 - name: Build on ${{ matrix.os }} run: ./gradlew clean build test + - name: Generate JaCoCo Coverage Report + if: matrix.os == 'ubuntu-latest' + run: ./gradlew jacocoTestReport + - name: Jacoco Report to PR + id: jacoco + uses: madrapps/jacoco-report@v1.7.2 + with: + paths: ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 40 + min-coverage-changed-files: 60 + title: Code Coverage + update-comment: true diff --git a/build.gradle.kts b/build.gradle.kts index b3baa5a..a26d4b2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.shadow) alias(libs.plugins.runServer) `maven-publish` + jacoco } dependencies { @@ -46,14 +47,23 @@ tasks { } test { useJUnitPlatform() + jvmArgs("-Dstardust.insideTest=true") testLogging { events("passed", "skipped", "failed") } + finalizedBy(rootProject.tasks.jacocoTestReport) } runServer { minecraftVersion("1.21.4") jvmArgs("-Dcom.mojang.eula.agree=true") } + jacocoTestReport { + dependsOn(rootProject.tasks.test) + reports { + xml.required.set(true) + csv.required.set(true) + } + } } paper { diff --git a/src/main/java/net/onelitefeather/stardust/util/Constants.java b/src/main/java/net/onelitefeather/stardust/util/Constants.java index 54cf080..ec061ad 100644 --- a/src/main/java/net/onelitefeather/stardust/util/Constants.java +++ b/src/main/java/net/onelitefeather/stardust/util/Constants.java @@ -11,4 +11,6 @@ private Constants() { public static final double RADIUS_REMOVE_ENEMIES = 32.0; public static final String PERMISSION_SECURE_MESSAGE = "stardust.secure.message"; public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy"); + + public static final boolean INSIDE_TEST = Boolean.parseBoolean(System.getProperty("stardust.insideTest", "false")); } diff --git a/src/main/java/net/onelitefeather/stardust/util/PlayerUtil.java b/src/main/java/net/onelitefeather/stardust/util/PlayerUtil.java index ea4dbd4..afb431a 100644 --- a/src/main/java/net/onelitefeather/stardust/util/PlayerUtil.java +++ b/src/main/java/net/onelitefeather/stardust/util/PlayerUtil.java @@ -21,6 +21,7 @@ public static boolean canEnterFlyMode(Player player) { * Prevents looks from entities to the player. **/ public static void removeEnemies(Player player, double radius) { + if (Constants.INSIDE_TEST) return; var plugin = JavaPlugin.getPlugin(StardustPlugin.class); player.getServer().getScheduler().getMainThreadExecutor(plugin).execute(() -> player.getNearbyEntities(radius, radius, radius).forEach(entity -> { diff --git a/src/test/java/net/onelitefeather/stardust/command/commands/FlightCommandTest.java b/src/test/java/net/onelitefeather/stardust/command/commands/FlightCommandTest.java new file mode 100644 index 0000000..3671892 --- /dev/null +++ b/src/test/java/net/onelitefeather/stardust/command/commands/FlightCommandTest.java @@ -0,0 +1,120 @@ +package net.onelitefeather.stardust.command.commands; + +import net.kyori.adventure.text.Component; +import net.onelitefeather.stardust.StardustPlugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.*; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; + +import java.io.File; + +class FlightCommandTest { + + private @NotNull ServerMock server; + private StardustPlugin plugin; + private FlightCommand command; + + @SuppressWarnings("removal") + public static class MockStardustPlugin extends StardustPlugin { + + public MockStardustPlugin() { + } + + public MockStardustPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } + + @Override + public void onEnable() { + // Mock enable logic if needed + } + + @Override + public void onDisable() { + + } + + @Override + public Component getPrefix() { + return Component.text("[Stardust]"); + } + } + + + @BeforeEach + void setUp() { + // Initialize MockBukkit + server = MockBukkit.mock(); + plugin = MockBukkit.load(MockStardustPlugin.class); + + // Create the command instance + command = new FlightCommand(plugin); + } + + @AfterEach + void tearDown() { + // Unmock MockBukkit + MockBukkit.unmock(); + } + + @Disabled + @Test + void testFlightCommand() { + // Create a mock player + var player = server.addPlayer(); + + // Check initial flight state + Assertions.assertFalse(player.getAllowFlight(), "Player should not be able to fly initially"); + + // Execute the command to toggle flight + command.handleFlightCommand(player, null); + + // Check if the player is now able to fly + Assertions.assertTrue(player.getAllowFlight(), "Player should be able to fly after command execution"); + + // Execute the command again to toggle back + command.handleFlightCommand(player, null); + + // Check if the player is no longer able to fly + Assertions.assertFalse(player.getAllowFlight(), "Player should not be able to fly after toggling back"); + } + + @Disabled + @Test + void testGlowCommandWithTarget() { + // Create a mock player + var player = server.addPlayer(); + player.addAttachment(plugin, "stardust.command.flight.others", true); + var target = server.addPlayer(); + target.setAllowFlight(false); + // Check initial flight state + Assertions.assertFalse(target.getAllowFlight(), "Target player should not be able to fly initially"); + // Execute the command to toggle flight for the target + command.handleFlightCommand(player, target); + // Check if the target player is now able to fly + Assertions.assertTrue(target.getAllowFlight(), "Target player should be able to fly after command execution"); + // Execute the command again to toggle back + command.handleFlightCommand(player, target); + // Check if the target player is no longer able to fly + Assertions.assertFalse(target.getAllowFlight(), "Target player should not be able to fly after toggling back"); + } + + @Disabled + @Test + void testFlightCommandWithoutPermission() { + // Create a mock player without permission + var player = server.addPlayer(); + player.addAttachment(plugin, "stardust.command.flight.others", false); + var target = server.addPlayer(); + + // Attempt to execute the command with a target + command.handleFlightCommand(player, target); + + // Check if the target is still not able to fly + Assertions.assertFalse(target.getAllowFlight(), "Target player should not be able to fly after command execution without permission"); + } + +} diff --git a/src/test/java/net/onelitefeather/stardust/command/commands/GlowCommandTest.java b/src/test/java/net/onelitefeather/stardust/command/commands/GlowCommandTest.java new file mode 100644 index 0000000..6cfaf3a --- /dev/null +++ b/src/test/java/net/onelitefeather/stardust/command/commands/GlowCommandTest.java @@ -0,0 +1,133 @@ +package net.onelitefeather.stardust.command.commands; + +import net.kyori.adventure.text.Component; +import net.onelitefeather.stardust.StardustPlugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; + +import java.io.File; + +class GlowCommandTest { + + private @NotNull ServerMock server; + private StardustPlugin plugin; + private GlowCommand command; + + @SuppressWarnings("removal") + public static class MockStardustPlugin extends StardustPlugin { + + public MockStardustPlugin() { + } + + public MockStardustPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } + + @Override + public void onEnable() { + // Mock enable logic if needed + } + + @Override + public void onDisable() { + + } + + @Override + public Component getPrefix() { + return Component.text("[Stardust]"); + } + } + + + @BeforeEach + void setUp() { + // Initialize MockBukkit + server = MockBukkit.mock(); + plugin = MockBukkit.load(MockStardustPlugin.class); + + // Create the command instance + command = new GlowCommand(plugin); + } + + @AfterEach + void tearDown() { + // Unmock MockBukkit + MockBukkit.unmock(); + } + + @Test + void testGlowCommand() { + // Create a mock player + var player = server.addPlayer(); + + // Check initial invulnerability state + Assertions.assertFalse(player.isGlowing(), "Player should not be glowing initially"); + + // Execute the command to toggle invulnerability + command.handleCommand(player, null); + + // Check if the player is now invulnerable + Assertions.assertTrue(player.isGlowing(), "Player should be glowing after command execution"); + + // Execute the command again to toggle back + command.handleCommand(player, null); + + // Check if the player is no longer invulnerable + Assertions.assertFalse(player.isGlowing(), "Player should not be glowing after toggling back"); + } + + @Test + void testGlowCommandWithTarget() { + // Create a mock player + var player = server.addPlayer(); + player.addAttachment(plugin, "stardust.command.glow.others", true); + var target = server.addPlayer(); + + // Check initial glowing state + Assertions.assertFalse(target.isGlowing(), "Target player should not be glowing initially"); + + // Execute the command with a target + command.handleCommand(player, target); + + // Check if the target is now glowing + Assertions.assertTrue(target.isGlowing(), "Target player should be glowing after command execution"); + + // Execute the command again to toggle back + command.handleCommand(player, target); + + // Check if the target is no longer glowing + Assertions.assertFalse(target.isGlowing(), "Target player should not be glowing after toggling back"); + } + + @Test + void testGlowCommandWithPermission() { + // Create a mock player with permission + var player = server.addPlayer(); + player.addAttachment(plugin, "stardust.command.glow.others", true); + var target = server.addPlayer("target"); + + // Check initial glowing state + Assertions.assertFalse(target.isGlowing(), "Target player should not be glowing initially"); + + // Execute the command with a target + command.handleCommand(player, target); + + // Check if the target is now glowing + Assertions.assertTrue(target.isGlowing(), "Target player should be glowing after command execution"); + + // Execute the command again to toggle back + command.handleCommand(player, target); + + // Check if the target is no longer glowing + Assertions.assertFalse(target.isGlowing(), "Target player should not be glowing after toggling back"); + } + +} diff --git a/src/test/java/net/onelitefeather/stardust/command/commands/GodmodeCommandTest.java b/src/test/java/net/onelitefeather/stardust/command/commands/GodmodeCommandTest.java new file mode 100644 index 0000000..e8f9170 --- /dev/null +++ b/src/test/java/net/onelitefeather/stardust/command/commands/GodmodeCommandTest.java @@ -0,0 +1,126 @@ +package net.onelitefeather.stardust.command.commands; + +import net.kyori.adventure.text.Component; +import net.onelitefeather.stardust.StardustPlugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; + +import java.io.File; + +class GodmodeCommandTest { + + private @NotNull ServerMock server; + private StardustPlugin plugin; + private GodmodeCommand command; + + @SuppressWarnings("removal") + public static class MockStardustPlugin extends StardustPlugin { + + public MockStardustPlugin() { + } + + public MockStardustPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } + + @Override + public void onEnable() { + // Mock enable logic if needed + } + + @Override + public void onDisable() { + + } + + @Override + public Component getPrefix() { + return Component.text("[Stardust]"); + } + } + + + @BeforeEach + void setUp() { + // Initialize MockBukkit + server = MockBukkit.mock(); + plugin = MockBukkit.load(MockStardustPlugin.class); + + // Create the command instance + command = new GodmodeCommand(plugin); + } + + @AfterEach + void tearDown() { + // Unmock MockBukkit + MockBukkit.unmock(); + } + + @Test + void test_is_invulnerable() { + // Create a mock player + var player = server.addPlayer(); + + // Check initial invulnerability state + Assertions.assertFalse(player.isInvulnerable(), "Player should not be invulnerable initially"); + + // Execute the command to toggle invulnerability + command.handleCommand(player, null); + + // Check if the player is now invulnerable + Assertions.assertTrue(player.isInvulnerable(), "Player should be invulnerable after command execution"); + + // Execute the command again to toggle back + command.handleCommand(player, null); + + // Check if the player is no longer invulnerable + Assertions.assertFalse(player.isInvulnerable(), "Player should not be invulnerable after toggling back"); + } + + @Test + void test_invulnerability_others() { + // Create a mock player and another player + var player = server.addPlayer(); + player.addAttachment(plugin, "stardust.command.godmode.others", true); + var target = server.addPlayer("target"); + + // Check initial invulnerability state + Assertions.assertFalse(target.isInvulnerable(), "Target should not be invulnerable initially"); + + // Execute the command as the player to toggle invulnerability for the target + command.handleCommand(player, target); + + // Check if the target is now invulnerable + Assertions.assertTrue(target.isInvulnerable(), "Target should be invulnerable after command execution"); + + // Execute the command again to toggle back + command.handleCommand(player, target); + + // Check if the target is no longer invulnerable + Assertions.assertFalse(target.isInvulnerable(), "Target should not be invulnerable after toggling back"); + } + + @Test + void test_invulnerability_no_permission() { + // Create a mock player and another player + var player = server.addPlayer(); + var target = server.addPlayer("target"); + + // Check initial invulnerability state + Assertions.assertFalse(target.isInvulnerable(), "Target should not be invulnerable initially"); + + // Execute the command as the player to toggle invulnerability for the target + command.handleCommand(player, target); + + // Check if the target is still not invulnerable due to lack of permission + Assertions.assertFalse(target.isInvulnerable(), "Target should not be invulnerable without permission"); + } + +} diff --git a/src/test/java/net/onelitefeather/stardust/command/commands/HealCommandTest.java b/src/test/java/net/onelitefeather/stardust/command/commands/HealCommandTest.java new file mode 100644 index 0000000..cad48e1 --- /dev/null +++ b/src/test/java/net/onelitefeather/stardust/command/commands/HealCommandTest.java @@ -0,0 +1,128 @@ +package net.onelitefeather.stardust.command.commands; + +import net.kyori.adventure.text.Component; +import net.onelitefeather.stardust.StardustPlugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +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.io.File; + +class HealCommandTest { + + + private @NotNull ServerMock server; + private StardustPlugin plugin; + private HealCommand healCommand; + + @SuppressWarnings("removal") + public static class MockStardustPlugin extends StardustPlugin { + + public MockStardustPlugin() { + } + + public MockStardustPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } + + @Override + public void onEnable() { + // Mock enable logic if needed + } + + @Override + public void onDisable() { + + } + + @Override + public Component getPrefix() { + return Component.text("[Stardust]"); + } + } + + + @BeforeEach + void setUp() { + // Initialize MockBukkit + server = MockBukkit.mock(); + plugin = MockBukkit.load(MockStardustPlugin.class); + + // Create the command instance + healCommand = new HealCommand(plugin); + } + + @AfterEach + void tearDown() { + // Unmock MockBukkit + MockBukkit.unmock(); + } + + @Test + void test_heal() { + PlayerMock player = server.addPlayer(); + player.setHealth(10.0); + player.setFoodLevel(10); + player.setSaturation(2.0f); + player.setFireTicks(100); + + // Execute the heal command + healCommand.onCommand(player, player); + // Verify that the player's health, food level, saturation, and fire ticks are reset + Assertions.assertEquals(20.0, player.getHealth(), "Player health should be reset to max."); + Assertions.assertEquals(20, player.getFoodLevel(), "Player food level should be reset to max."); + Assertions.assertEquals(5.0f, player.getSaturation(), "Player saturation should be reset to max."); + Assertions.assertEquals(0, player.getFireTicks(), "Player fire ticks should be reset to 0."); + + } + + @Test + void test_heal_other_player() { + PlayerMock sender = server.addPlayer("CommandSender"); + sender.addAttachment(plugin, "stardust.command.heal.others", true); + PlayerMock target = server.addPlayer("TargetPlayer"); + + // Set initial health and food level for the target player + target.setHealth(10.0); + target.setFoodLevel(10); + target.setSaturation(2.0f); + target.setFireTicks(100); + + // Execute the heal command as the sender + healCommand.onCommand(sender, target); + + // Verify that the target player's health, food level, saturation, and fire ticks are reset + Assertions.assertEquals(20.0, target.getHealth(), "Target player health should be reset to max."); + Assertions.assertEquals(20, target.getFoodLevel(), "Target player food level should be reset to max."); + Assertions.assertEquals(5.0f, target.getSaturation(), "Target player saturation should be reset to max."); + Assertions.assertEquals(0, target.getFireTicks(), "Target player fire ticks should be reset to 0."); + } + + @Test + void test_heal_no_permission() { + PlayerMock sender = server.addPlayer("CommandSender"); + PlayerMock target = server.addPlayer("TargetPlayer"); + + // Set initial health and food level for the target player + target.setHealth(10.0); + target.setFoodLevel(10); + target.setSaturation(2.0f); + target.setFireTicks(100); + + // Execute the heal command as the sender without permission + healCommand.onCommand(sender, target); + + // Verify that the target player's health, food level, saturation, and fire ticks are not reset + Assertions.assertEquals(10.0, target.getHealth(), "Target player health should not be reset."); + Assertions.assertEquals(10, target.getFoodLevel(), "Target player food level should not be reset."); + Assertions.assertEquals(2.0f, target.getSaturation(), "Target player saturation should not be reset."); + Assertions.assertEquals(100, target.getFireTicks(), "Target player fire ticks should not be reset."); + } +} diff --git a/src/test/java/net/onelitefeather/stardust/command/commands/RenameCommandTest.java b/src/test/java/net/onelitefeather/stardust/command/commands/RenameCommandTest.java new file mode 100644 index 0000000..9c908cf --- /dev/null +++ b/src/test/java/net/onelitefeather/stardust/command/commands/RenameCommandTest.java @@ -0,0 +1,97 @@ +package net.onelitefeather.stardust.command.commands; + +import net.kyori.adventure.text.Component; +import net.onelitefeather.stardust.StardustPlugin; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +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.io.File; + +@SuppressWarnings("removal") +class RenameCommandTest { + + private @NotNull ServerMock server; + private StardustPlugin plugin; + private RenameCommand renameCommand; + + public static class MockStardustPlugin extends StardustPlugin { + + public MockStardustPlugin() { + } + + public MockStardustPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } + + @Override + public void onEnable() { + // Mock enable logic if needed + } + + @Override + public void onDisable() { + + } + + @Override + public Component getPrefix() { + return Component.text("[Stardust]"); + } + } + + @BeforeEach + void setUp() { + // Initialize MockBukkit + server = MockBukkit.mock(); + plugin = MockBukkit.load(MockStardustPlugin.class); + + // Create the command instance + renameCommand = new RenameCommand(plugin); + } + @AfterEach + void tearDown() { + // Unmock MockBukkit + MockBukkit.unmock(); + } + + @Test + void testHasPlayerAirInHand() { + + PlayerMock player = server.addPlayer(); + // Simulate the player not holding an item + player.setItemInHand(new ItemStack(Material.AIR)); + this.renameCommand.handleCommand(player, "Excalibur"); + + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.rename.invalid-item").arguments(plugin.getPrefix())); + + } + @Test + void testRenameItemInHand() { + PlayerMock player = server.addPlayer(); + ItemStack itemInHand = new ItemStack(Material.DIAMOND_SWORD); + player.setItemInHand(itemInHand); + + // Simulate the command execution + String newName = "Excalibur"; + this.renameCommand.handleCommand(player, newName); + + // Verify that the item name was changed + ItemStack updatedItem = player.getInventory().getItemInMainHand(); + Assertions.assertNotNull(updatedItem); + Assertions.assertEquals(Material.DIAMOND_SWORD, updatedItem.getType()); + Assertions.assertEquals(Component.text(newName), updatedItem.getItemMeta().displayName()); + + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.rename.success").arguments(plugin.getPrefix(), Component.text(newName))); + } + +} diff --git a/src/test/java/net/onelitefeather/stardust/command/commands/SkullCommandTest.java b/src/test/java/net/onelitefeather/stardust/command/commands/SkullCommandTest.java new file mode 100644 index 0000000..38eec6f --- /dev/null +++ b/src/test/java/net/onelitefeather/stardust/command/commands/SkullCommandTest.java @@ -0,0 +1,166 @@ +package net.onelitefeather.stardust.command.commands; + +import net.kyori.adventure.text.Component; +import net.onelitefeather.stardust.StardustPlugin; +import org.bukkit.Material; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +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.OfflinePlayerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; + +import java.io.File; + +@SuppressWarnings("removal") +class SkullCommandTest { + + private @NotNull ServerMock server; + private StardustPlugin plugin; + private SkullCommand skullCommand; + + public static class MockStardustPlugin extends StardustPlugin { + + public MockStardustPlugin() { + } + + public MockStardustPlugin(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + } + + @Override + public void onEnable() { + // Mock enable logic if needed + } + + @Override + public void onDisable() { + + } + + @Override + public Component getPrefix() { + return Component.text("[Stardust]"); + } + } + + @BeforeEach + void setUp() { + // Initialize MockBukkit + server = MockBukkit.mock(); + plugin = MockBukkit.load(net.onelitefeather.stardust.command.commands.RenameCommandTest.MockStardustPlugin.class); + + // Create the command instance + skullCommand = new SkullCommand(plugin); + } + + @AfterEach + void tearDown() { + // Unmock MockBukkit + MockBukkit.unmock(); + } + @Test + void testCommandWithOfflineSkull() { + PlayerMock player = server.addPlayer(); + skullCommand.handleCommand(player, "Seelenretterin"); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), + "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success") + .arguments(plugin.getPrefix(), Component.text("Seelenretterin"))); + } + @Test + void testCommandWithPlayerSkullSelf() { + PlayerMock player = server.addPlayer("Seelenretterin"); + skullCommand.handleCommand(player, player.getName()); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), + "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success") + .arguments(plugin.getPrefix(), Component.text(player.getName()))); + } + @Test + void testCommandWithPlayerSkullOther() { + PlayerMock player = server.addPlayer("Seelenretterin"); + PlayerMock otherPlayer = server.addPlayer("TheMeinerLP"); + skullCommand.handleCommand(player, otherPlayer.getName()); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), + "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success") + .arguments(plugin.getPrefix(), Component.text(otherPlayer.getName()))); + } + @Test + void testCommandWithPlayerSkullNull() { + PlayerMock player = server.addPlayer("Seelenretterin"); + skullCommand.handleCommand(player, null); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), + "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success") + .arguments(plugin.getPrefix(), Component.text(player.getName()))); + } + @Test + void testCommandWithPlayerSkullEmpty() { + PlayerMock player = server.addPlayer("Seelenretterin"); + skullCommand.handleCommand(player, ""); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), + "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success") + .arguments(plugin.getPrefix(), Component.text(""))); + } + + @Test + void testCommandWithInvalidPlayerName() { + PlayerMock player = server.addPlayer("Seelenretterin"); + skullCommand.handleCommand(player, null); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success").arguments(plugin.getPrefix(), Component.text(player.getName()))); + } + + + @Test + void testCommandWithOnlinePlayerName() { + server.setOnlineMode(true); + PlayerMock player = server.addPlayer("Seelenretterin"); + skullCommand.handleCommand(player, "Seelenretterin"); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success").arguments(plugin.getPrefix(), Component.text(player.getName()))); + } + + @Test + void testCommandWithOfflinePlayer() { + OfflinePlayerMock offlinePlayer = new OfflinePlayerMock("Seelenretterin"); + server.getPlayerList().addOfflinePlayer(offlinePlayer); + PlayerMock player = server.addPlayer("TestUser"); + skullCommand.handleCommand(player, "Seelenretterin"); + server.getScheduler().performOneTick(); + // Then assert the expected behavior, such as checking if the skull item was added to the player's inventory + Assertions.assertNotNull(skullCommand); + Assertions.assertTrue(player.getInventory().contains(Material.PLAYER_HEAD), "Player should have a player head in their inventory."); + Assertions.assertEquals(player.nextComponentMessage(), Component.translatable("commands.skull.success") + .arguments(plugin.getPrefix(), Component.text("Seelenretterin"))); + } +}