diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestBackpackListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestBackpackListener.java index 7d799b6c1..8583f1b72 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestBackpackListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestBackpackListener.java @@ -6,21 +6,35 @@ import java.util.concurrent.atomic.AtomicReference; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.Mockito; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.mocks.TestUtilities; import me.mrCookieSlime.Slimefun.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.ItemState; public class TestBackpackListener { @@ -42,33 +56,6 @@ public class TestBackpackListener { MockBukkit.unmock(); } - @Test - public void testIllegalSetId() { - Player player = server.addPlayer(); - - Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(null, null, 1, 1)); - Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, null, 1, 1)); - Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, new ItemStack(Material.REDSTONE), 1, 1)); - Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, new CustomItem(Material.REDSTONE, "Hi", "lore"), 1, 1)); - Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, new CustomItem(Material.REDSTONE, "Hi", "lore", "no id"), 1, 1)); - } - - @Test - public void testSetId() throws InterruptedException { - Player player = server.addPlayer(); - ItemStack item = new CustomItem(Material.CHEST, "&4Mock Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: ", "", "&7&eRight Click&7 to open"); - - PlayerProfile profile = TestUtilities.awaitProfile(player); - int id = profile.createBackpack(BACKPACK_SIZE).getId(); - - listener.setBackpackId(player, item, 2, id); - Assertions.assertEquals(ChatColor.GRAY + "ID: " + player.getUniqueId() + "#" + id, item.getItemMeta().getLore().get(2)); - - PlayerBackpack backpack = awaitBackpack(item); - Assertions.assertEquals(player.getUniqueId(), backpack.getOwner().getUUID()); - Assertions.assertEquals(id, backpack.getId()); - } - private PlayerBackpack awaitBackpack(ItemStack item) throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); AtomicReference ref = new AtomicReference<>(); @@ -83,4 +70,116 @@ public class TestBackpackListener { return ref.get(); } + private PlayerBackpack openMockBackpack(Player player, int size) throws InterruptedException { + ItemStack item = new CustomItem(Material.CHEST, "&4Mock Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: ", "", "&7&eRight Click&7 to open"); + PlayerProfile profile = TestUtilities.awaitProfile(player); + + PlayerBackpack backpack = profile.createBackpack(size); + listener.setBackpackId(player, item, 2, backpack.getId()); + + SlimefunBackpack slimefunBackpack = Mockito.mock(SlimefunBackpack.class); + Mockito.when(slimefunBackpack.getSize()).thenReturn(size); + + // This will make hasUnlocked() immediately pass + Mockito.when(slimefunBackpack.getState()).thenReturn(ItemState.VANILLA_FALLBACK); + SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(slimefunBackpack); + + listener.openBackpack(player, item, slimefunBackpack); + return backpack; + } + + @Test + public void testIllegalSetId() { + Player player = server.addPlayer(); + + Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(null, null, 1, 1)); + Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, null, 1, 1)); + Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, new ItemStack(Material.REDSTONE), 1, 1)); + Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, new CustomItem(Material.REDSTONE, "Hi", "lore"), 1, 1)); + Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(player, new CustomItem(Material.REDSTONE, "Hi", "lore", "no id"), 1, 1)); + } + + @Test + public void testSetId() throws InterruptedException { + Player player = server.addPlayer(); + ItemStack item = new CustomItem(Material.CHEST, "&cA mocked Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: ", "", "&7&eRight Click&7 to open"); + + PlayerProfile profile = TestUtilities.awaitProfile(player); + int id = profile.createBackpack(BACKPACK_SIZE).getId(); + + listener.setBackpackId(player, item, 2, id); + Assertions.assertEquals(ChatColor.GRAY + "ID: " + player.getUniqueId() + "#" + id, item.getItemMeta().getLore().get(2)); + + PlayerBackpack backpack = awaitBackpack(item); + Assertions.assertEquals(player.getUniqueId(), backpack.getOwner().getUUID()); + Assertions.assertEquals(id, backpack.getId()); + } + + @Test + public void testOpenBackpack() throws InterruptedException { + Player player = server.addPlayer(); + PlayerBackpack backpack = openMockBackpack(player, 27); + InventoryView view = player.getOpenInventory(); + Assertions.assertEquals(backpack.getInventory(), view.getTopInventory()); + } + + @Test + public void testCloseBackpack() throws InterruptedException { + Player player = server.addPlayer(); + PlayerBackpack backpack = openMockBackpack(player, 27); + listener.onClose(new InventoryCloseEvent(player.getOpenInventory())); + + Assertions.assertTrue(backpack.getOwner().isDirty()); + } + + @Test + public void testBackpackDropNormalItem() throws InterruptedException { + Player player = server.addPlayer(); + openMockBackpack(player, 27); + + Item item = Mockito.mock(Item.class); + Mockito.when(item.getItemStack()).thenReturn(new ItemStack(Material.SUGAR_CANE)); + PlayerDropItemEvent event = new PlayerDropItemEvent(player, item); + listener.onItemDrop(event); + + Assertions.assertFalse(event.isCancelled()); + } + + private boolean isAllowed(ItemStack item) throws InterruptedException { + Player player = server.addPlayer(); + Inventory inv = openMockBackpack(player, 9).getInventory(); + + int slot = 7; + inv.setItem(slot, item); + InventoryClickEvent event = new InventoryClickEvent(player.getOpenInventory(), SlotType.CONTAINER, slot, ClickType.LEFT, InventoryAction.PICKUP_ONE); + listener.onClick(event); + return !event.isCancelled(); + } + + @ParameterizedTest + @EnumSource(value = Material.class, names = { "AIR", "DIAMOND", "STONE" }) + public void areItemsAllowed(Material type) throws InterruptedException { + Assertions.assertTrue(isAllowed(new ItemStack(type))); + } + + @ParameterizedTest + @EnumSource(value = Material.class, names = { "SHULKER_BOX", "RED_SHULKER_BOX", "BLUE_SHULKER_BOX", "BLACK_SHULKER_BOX" }) + public void areShulkerBoxesAllowed(Material type) throws InterruptedException { + Assertions.assertFalse(isAllowed(new ItemStack(type))); + } + + @ParameterizedTest + @EnumSource(value = Material.class, names = { "AIR", "SHULKER_BOX" }) + public void testHotbarKey(Material type) throws InterruptedException { + Player player = server.addPlayer(); + openMockBackpack(player, 9); + + int slot = 7; + player.getInventory().setItem(slot, new ItemStack(type)); + InventoryClickEvent event = new InventoryClickEvent(player.getOpenInventory(), SlotType.CONTAINER, slot, ClickType.NUMBER_KEY, InventoryAction.PICKUP_ONE, slot); + listener.onClick(event); + + Assertions.assertEquals(type != Material.AIR, event.isCancelled()); + } + } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestPlayerProfileListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestPlayerProfileListener.java new file mode 100644 index 000000000..0e1d9ffed --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestPlayerProfileListener.java @@ -0,0 +1,74 @@ +package io.github.thebusybiscuit.slimefun4.tests.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener; +import io.github.thebusybiscuit.slimefun4.mocks.TestUtilities; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; + +public class TestPlayerProfileListener { + + private static SlimefunPlugin plugin; + private static PlayerProfileListener listener; + private static ServerMock server; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + listener = new PlayerProfileListener(plugin); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @Test + public void testPlayerLeave() throws InterruptedException { + Player player = server.addPlayer(); + PlayerProfile profile = TestUtilities.awaitProfile(player); + PlayerQuitEvent event = new PlayerQuitEvent(player, "bye"); + listener.onDisconnect(event); + + Assertions.assertTrue(profile.isMarkedForDeletion()); + } + + @Test + public void testUnloadedPlayerLeave() { + Player player = server.addPlayer(); + PlayerQuitEvent event = new PlayerQuitEvent(player, "bye"); + listener.onDisconnect(event); + + Assertions.assertFalse(PlayerProfile.find(player).isPresent()); + } + + @Test + public void testPlayerKick() throws InterruptedException { + Player player = server.addPlayer(); + PlayerProfile profile = TestUtilities.awaitProfile(player); + PlayerKickEvent event = new PlayerKickEvent(player, "You're not welcome anymore", "bye"); + listener.onKick(event); + + Assertions.assertTrue(profile.isMarkedForDeletion()); + } + + @Test + public void testUnloadedPlayerKick() { + Player player = server.addPlayer(); + PlayerKickEvent event = new PlayerKickEvent(player, "You're not welcome anymore", "bye"); + listener.onKick(event); + + Assertions.assertFalse(PlayerProfile.find(player).isPresent()); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestSoulboundListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestSoulboundListener.java new file mode 100644 index 000000000..6b0c5526f --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/tests/listeners/TestSoulboundListener.java @@ -0,0 +1,66 @@ +package io.github.thebusybiscuit.slimefun4.tests.listeners; + +import org.bukkit.Material; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundListener; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; + +public class TestSoulboundListener { + + private static SlimefunPlugin plugin; + private static ServerMock server; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + new SoulboundListener(plugin); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + public void testItemDrop(boolean soulbound) { + PlayerMock player = server.addPlayer(); + ItemStack item = new CustomItem(Material.DIAMOND_SWORD, "&4Cool Sword"); + SlimefunUtils.setSoulbound(item, soulbound); + player.getInventory().setItem(6, item); + player.setHealth(0); + + server.getPluginManager().assertEventFired(EntityDeathEvent.class, event -> { + return soulbound != event.getDrops().contains(item); + }); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + public void testItemRecover(boolean soulbound) { + PlayerMock player = server.addPlayer(); + ItemStack item = new CustomItem(Material.DIAMOND_SWORD, "&4Cool Sword"); + SlimefunUtils.setSoulbound(item, soulbound); + player.getInventory().setItem(6, item); + player.setHealth(0); + player.respawn(); + + server.getPluginManager().assertEventFired(PlayerRespawnEvent.class, event -> { + return player.getInventory().getItem(6).isSimilar(item) == soulbound; + }); + } + +}