From 9021df099aaa1da45b025d32bbfccc88d176d911 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 8 Jul 2018 16:45:17 -0700 Subject: [PATCH] Added permissions to settings. Added test for Inv Visitors. Default perms need to be added to plugin.yml or addon.yml for settings. --- .../api/flags/clicklisteners/CycleClick.java | 15 ++ .../IslandToggleClickListener.java | 25 +- .../WorldToggleClickListener.java | 7 +- .../tastybento/bskyblock/api/user/User.java | 8 + .../flags/InvincibleVisitorsListener.java | 36 ++- .../us/tastybento/bskyblock/lists/Flags.java | 10 +- .../flags/clicklisteners}/CycleClickTest.java | 49 +++- .../IslandToggleClickListenerTest.java | 134 ++++++++++ .../WorldToggleClickListenerTest.java} | 9 +- .../flags/InvincibleVisitorsListenerTest.java | 240 ++++++++++++++++++ 10 files changed, 497 insertions(+), 36 deletions(-) rename src/test/java/us/tastybento/bskyblock/{listeners/flags => api/flags/clicklisteners}/CycleClickTest.java (86%) create mode 100644 src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListenerTest.java rename src/test/java/us/tastybento/bskyblock/{listeners/flags/SettingsToggleClickListenerTest.java => api/flags/clicklisteners/WorldToggleClickListenerTest.java} (93%) create mode 100644 src/test/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListenerTest.java diff --git a/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClick.java b/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClick.java index 297a1514d..f2a260712 100644 --- a/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClick.java +++ b/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClick.java @@ -10,6 +10,7 @@ import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; import us.tastybento.bskyblock.managers.RanksManager; +import us.tastybento.bskyblock.util.Util; /** * Left Clicks increase rank, right clicks lower rank @@ -30,6 +31,18 @@ public class CycleClick implements PanelItem.ClickHandler { @Override public boolean onClick(Panel panel, User user, ClickType click, int slot) { + // Get the world + if (!plugin.getIWM().inWorld(user.getLocation())) { + user.sendMessage("general.errors.wrong-world"); + return true; + } + String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + ".settings." + id; + if (!user.hasPermission(reqPerm)) { + user.sendMessage("general.errors.no-permission"); + user.sendMessage("general.errors.you-need", "[permission]", reqPerm); + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); + return true; + } // Left clicking increases the rank required // Right clicking decreases the rank required // Get the user's island @@ -55,6 +68,8 @@ public class CycleClick implements PanelItem.ClickHandler { } // Apply change to panel panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem()); + } else { + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); } return true; } diff --git a/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListener.java b/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListener.java index 1fb727587..7aeb17f67 100644 --- a/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListener.java +++ b/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListener.java @@ -12,6 +12,7 @@ import us.tastybento.bskyblock.api.panels.Panel; import us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.util.Util; /** * Toggles a island setting on/off @@ -19,10 +20,10 @@ import us.tastybento.bskyblock.database.objects.Island; * */ public class IslandToggleClickListener implements ClickHandler { - + private BSkyBlock plugin = BSkyBlock.getInstance(); private String id; - + /** * @param id - the flag ID that this click listener is associated with */ @@ -36,17 +37,31 @@ public class IslandToggleClickListener implements ClickHandler { */ @Override public boolean onClick(Panel panel, User user, ClickType clickType, int slot) { + // Get the world + if (!plugin.getIWM().inWorld(user.getLocation())) { + user.sendMessage("general.errors.wrong-world"); + return true; + } + String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + ".settings." + id; + if (!user.hasPermission(reqPerm)) { + user.sendMessage("general.errors.no-permission"); + user.sendMessage("general.errors.you-need", "[permission]", reqPerm); + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); + return true; + } // Get the user's island - Island island = plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId()); + Island island = plugin.getIslands().getIsland(user.getWorld(), user); if (island != null && island.getOwner().equals(user.getUniqueId())) { Flag flag = plugin.getFlagsManager().getFlagByID(id); // Toggle flag island.toggleFlag(flag); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); // Apply change to panel - panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem()); + panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem()); + } else { + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); } - return true; + return true; } } diff --git a/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListener.java b/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListener.java index f7a25bd14..7221f0506 100644 --- a/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListener.java +++ b/src/main/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListener.java @@ -19,10 +19,10 @@ import us.tastybento.bskyblock.util.Util; * */ public class WorldToggleClickListener implements ClickHandler { - + private BSkyBlock plugin = BSkyBlock.getInstance(); private String id; - + /** * @param id - the flag ID that this click listener is associated with */ @@ -41,10 +41,11 @@ public class WorldToggleClickListener implements ClickHandler { user.sendMessage("general.errors.wrong-world"); return true; } - String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + ".settings." + id; + String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + ".admin.world.settings." + id; if (!user.hasPermission(reqPerm)) { user.sendMessage("general.errors.no-permission"); user.sendMessage("general.errors.you-need", "[permission]", reqPerm); + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); return true; } // Get flag diff --git a/src/main/java/us/tastybento/bskyblock/api/user/User.java b/src/main/java/us/tastybento/bskyblock/api/user/User.java index 954d220f8..308581cfb 100644 --- a/src/main/java/us/tastybento/bskyblock/api/user/User.java +++ b/src/main/java/us/tastybento/bskyblock/api/user/User.java @@ -364,4 +364,12 @@ public class User { return other.playerUUID == null; } else return playerUUID.equals(other.playerUUID); } + + /** + * Checks if a user is in one of the game worlds + * @return true if user is, false if not + */ + public boolean inWorld() { + return plugin.getIWM().inWorld(getLocation()); + } } diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListener.java index 756420cc4..087056c13 100644 --- a/src/main/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListener.java +++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListener.java @@ -7,6 +7,7 @@ import java.util.Arrays; import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -26,6 +27,7 @@ import us.tastybento.bskyblock.util.Util; import us.tastybento.bskyblock.util.teleport.SafeTeleportBuilder; /** + * Listener for invincible visitor settings. Handles click listening and damage events * @author tastybento * */ @@ -33,15 +35,28 @@ public class InvincibleVisitorsListener extends AbstractFlagListener implements @Override public boolean onClick(Panel panel, User user, ClickType clickType, int slot) { + // Get the world + if (!user.inWorld()) { + user.sendMessage("general.errors.wrong-world"); + return true; + } + String reqPerm = getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + ".admin.settings.INVINCIBLE_VISITORS"; + if (!user.hasPermission(reqPerm)) { + user.sendMessage("general.errors.no-permission"); + user.sendMessage("general.errors.you-need", "[permission]", reqPerm); + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); + return true; + } + String ivPanelName = user.getTranslation("protection.flags.INVINCIBLE_VISITORS.name"); if (panel.getName().equals(ivPanelName)) { // This is a click on the IV panel // Slot relates to the enum DamageCause c = Arrays.asList(EntityDamageEvent.DamageCause.values()).get(slot); - if (getPlugin().getSettings().getIvSettings().contains(c.name())) { - getPlugin().getSettings().getIvSettings().remove(c.name()); + if (getIWM().getIvSettings(user.getWorld()).contains(c.name())) { + getIWM().getIvSettings(user.getWorld()).remove(c.name()); } else { - getPlugin().getSettings().getIvSettings().add(c.name()); + getIWM().getIvSettings(user.getWorld()).add(c.name()); } // Apply change to panel panel.getInventory().setItem(slot, getPanelItem(c, user).getItem()); @@ -63,18 +78,18 @@ public class InvincibleVisitorsListener extends AbstractFlagListener implements pb.build(); } - + private PanelItem getPanelItem(DamageCause c, User user) { PanelItemBuilder pib = new PanelItemBuilder(); pib.name(Util.prettifyText(c.toString())); pib.clickHandler(this); - if (getPlugin().getSettings().getIvSettings().contains(c.name())) { + if (getIWM().getIvSettings(user.getWorld()).contains(c.name())) { pib.icon(Material.GREEN_SHULKER_BOX); pib.description(user.getTranslation("protection.panel.flag-item.setting-active")); } else { pib.icon(Material.RED_SHULKER_BOX); - pib.description(user.getTranslation("protection.panel.flag-item.setting-disabled")); - } + pib.description(user.getTranslation("protection.panel.flag-item.setting-disabled")); + } return pib.build(); } @@ -85,10 +100,9 @@ public class InvincibleVisitorsListener extends AbstractFlagListener implements @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onVisitorGetDamage(EntityDamageEvent e) { World world = e.getEntity().getWorld(); - if (!getPlugin().getIWM().inWorld(e.getEntity().getLocation()) - || !getPlugin().getIWM().getIvSettings(world).contains(e.getCause().name()) - || !(e.getEntity() instanceof Player) - || e.getCause().equals(DamageCause.ENTITY_ATTACK) + if (!(e.getEntity() instanceof Player) + || !getIWM().inWorld(e.getEntity().getLocation()) + || !getIWM().getIvSettings(world).contains(e.getCause().name()) || getIslands().userIsOnIsland(world, User.getInstance(e.getEntity()))) { return; } diff --git a/src/main/java/us/tastybento/bskyblock/lists/Flags.java b/src/main/java/us/tastybento/bskyblock/lists/Flags.java index 1fafdd89c..cb7ffa12e 100644 --- a/src/main/java/us/tastybento/bskyblock/lists/Flags.java +++ b/src/main/java/us/tastybento/bskyblock/lists/Flags.java @@ -28,6 +28,7 @@ import us.tastybento.bskyblock.listeners.flags.IslandRespawnListener; import us.tastybento.bskyblock.listeners.flags.ItemDropPickUpListener; import us.tastybento.bskyblock.listeners.flags.LeashListener; import us.tastybento.bskyblock.listeners.flags.LockAndBanListener; +import us.tastybento.bskyblock.listeners.flags.MobSpawnListener; import us.tastybento.bskyblock.listeners.flags.OfflineRedstoneListener; import us.tastybento.bskyblock.listeners.flags.PVPListener; import us.tastybento.bskyblock.listeners.flags.PhysicalInteractionListener; @@ -149,9 +150,12 @@ public class Flags { .defaultRank(DISABLED).onClick(new IslandToggleClickListener("PVP_END")).build(); // Others - public static final Flag ANIMAL_SPAWN = new FlagBuilder().id("ANIMAL_SPAWN").icon(Material.APPLE).allowedByDefault(true).type(Type.SETTING).build(); - public static final Flag MONSTER_SPAWN = new FlagBuilder().id("MONSTER_SPAWN").icon(Material.MOB_SPAWNER).allowedByDefault(true).type(Type.SETTING).build(); - public static final Flag FIRE_SPREAD = new FlagBuilder().id("FIRE_SPREAD").icon(Material.FIREWORK_CHARGE).type(Type.SETTING).build(); + public static final Flag ANIMAL_SPAWN = new FlagBuilder().id("ANIMAL_SPAWN").icon(Material.APPLE).allowedByDefault(true).type(Type.SETTING) + .listener(new MobSpawnListener()).onClick(new IslandToggleClickListener("MONSTER_SPAWN")).build(); + public static final Flag MONSTER_SPAWN = new FlagBuilder().id("MONSTER_SPAWN").icon(Material.MOB_SPAWNER).allowedByDefault(true).type(Type.SETTING) + .onClick(new IslandToggleClickListener("MONSTER_SPAWN")).build(); + public static final Flag FIRE_SPREAD = new FlagBuilder().id("FIRE_SPREAD").icon(Material.FIREWORK_CHARGE).allowedByDefault(true).type(Type.SETTING) + .onClick(new IslandToggleClickListener("FIRE_SPREAD")).build(); // World Settings - apply to every island in the game worlds public static final Flag ENDER_CHEST = new FlagBuilder().id("ENDER_CHEST").icon(Material.ENDER_CHEST) diff --git a/src/test/java/us/tastybento/bskyblock/listeners/flags/CycleClickTest.java b/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClickTest.java similarity index 86% rename from src/test/java/us/tastybento/bskyblock/listeners/flags/CycleClickTest.java rename to src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClickTest.java index 61c55e02c..286edd303 100644 --- a/src/test/java/us/tastybento/bskyblock/listeners/flags/CycleClickTest.java +++ b/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/CycleClickTest.java @@ -1,4 +1,4 @@ -package us.tastybento.bskyblock.listeners.flags; +package us.tastybento.bskyblock.api.flags.clicklisteners; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -38,13 +38,15 @@ import us.tastybento.bskyblock.api.user.Notifier; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; import us.tastybento.bskyblock.managers.FlagsManager; +import us.tastybento.bskyblock.managers.IslandWorldManager; import us.tastybento.bskyblock.managers.IslandsManager; import us.tastybento.bskyblock.managers.LocalesManager; import us.tastybento.bskyblock.managers.PlayersManager; import us.tastybento.bskyblock.managers.RanksManager; +import us.tastybento.bskyblock.util.Util; @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BSkyBlock.class, User.class }) +@PrepareForTest({Bukkit.class, BSkyBlock.class, User.class, Util.class }) public class CycleClickTest { private static final Integer PROTECTION_RANGE = 200; @@ -59,6 +61,7 @@ public class CycleClickTest { private Flag flag; private Panel panel; private Inventory inv; + private IslandWorldManager iwm; /** * @throws java.lang.Exception @@ -90,6 +93,7 @@ public class CycleClickTest { when(user.getPlayer()).thenReturn(p); when(user.getName()).thenReturn("tastybento"); when(user.getWorld()).thenReturn(world); + when(user.hasPermission(Mockito.anyString())).thenReturn(true); // No island for player to begin with (set it later in the tests) im = mock(IslandsManager.class); @@ -107,7 +111,7 @@ public class CycleClickTest { PowerMockito.mockStatic(Bukkit.class); when(Bukkit.getScheduler()).thenReturn(sch); - // Locales + // Locales LocalesManager lm = mock(LocalesManager.class); when(plugin.getLocalesManager()).thenReturn(lm); when(lm.get(any(), any())).thenReturn("mock translation"); @@ -180,6 +184,33 @@ public class CycleClickTest { inv = mock(Inventory.class); when(panel.getInventory()).thenReturn(inv); + // IslandWorldManager + iwm = mock(IslandWorldManager.class); + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.inWorld(Mockito.any())).thenReturn(true); + when(iwm.getPermissionPrefix(Mockito.any())).thenReturn("bskyblock"); + + // Util + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(Mockito.any())).thenReturn(world); + + } + + @Test + public void testNotInWorld() { + when(iwm.inWorld(Mockito.any())).thenReturn(false); + CycleClick udc = new CycleClick("LOCK"); + assertTrue(udc.onClick(panel, user, ClickType.LEFT, 5)); + Mockito.verify(user).sendMessage(Mockito.eq("general.errors.wrong-world")); + } + + @Test + public void testNoPremission() { + when(user.hasPermission(Mockito.anyString())).thenReturn(false); + CycleClick udc = new CycleClick("LOCK"); + assertTrue(udc.onClick(panel, user, ClickType.LEFT, 5)); + Mockito.verify(user).sendMessage(Mockito.eq("general.errors.no-permission")); + Mockito.verify(user).sendMessage(Mockito.eq("general.errors.you-need"), Mockito.eq("[permission]"), Mockito.eq("bskyblock.settings.LOCK")); } @Test @@ -225,30 +256,30 @@ public class CycleClickTest { Mockito.verify(flag, Mockito.times(2)).toPanelItem(Mockito.any(), Mockito.any()); Mockito.verify(inv, Mockito.times(2)).setItem(Mockito.eq(SLOT), Mockito.any()); } - + @Test public void testAllClicks() { // Test all possible click types CycleClick udc = new CycleClick("LOCK"); Arrays.asList(ClickType.values()).forEach(c -> assertTrue(udc.onClick(panel, user, c, 0))); } - + @Test public void testNotOwner() { UUID u; do { u = UUID.randomUUID(); } while(u.equals(uuid)); - + when(island.getOwner()).thenReturn(u); Mockito.verify(plugin, Mockito.never()).getRanksManager(); - + } - + @Test public void testNullIsland() { when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(null); - Mockito.verify(plugin, Mockito.never()).getRanksManager(); + Mockito.verify(plugin, Mockito.never()).getRanksManager(); } } diff --git a/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListenerTest.java b/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListenerTest.java new file mode 100644 index 000000000..f0f612793 --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/IslandToggleClickListenerTest.java @@ -0,0 +1,134 @@ +package us.tastybento.bskyblock.api.flags.clicklisteners; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.api.flags.Flag; +import us.tastybento.bskyblock.api.panels.Panel; +import us.tastybento.bskyblock.api.panels.PanelItem; +import us.tastybento.bskyblock.api.user.User; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.managers.FlagsManager; +import us.tastybento.bskyblock.managers.IslandWorldManager; +import us.tastybento.bskyblock.managers.IslandsManager; +import us.tastybento.bskyblock.util.Util; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({BSkyBlock.class, Util.class }) +public class IslandToggleClickListenerTest { + + private IslandWorldManager iwm; + private IslandToggleClickListener listener; + private Panel panel; + private User user; + private Flag flag; + private IslandsManager im; + private Island island; + private UUID uuid; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + + // Set up plugin + BSkyBlock plugin = mock(BSkyBlock.class); + Whitebox.setInternalState(BSkyBlock.class, "instance", plugin); + // Island World Manager + iwm = mock(IslandWorldManager.class); + when(iwm.inWorld(Mockito.any())).thenReturn(true); + when(iwm.getPermissionPrefix(Mockito.any())).thenReturn("bskyblock"); + when(plugin.getIWM()).thenReturn(iwm); + + listener = new IslandToggleClickListener("test"); + + panel = mock(Panel.class); + when(panel.getInventory()).thenReturn(mock(Inventory.class)); + // Sometimes use Mockito.withSettings().verboseLogging() + user = mock(User.class); + when(user.getWorld()).thenReturn(mock(World.class)); + when(user.getLocation()).thenReturn(mock(Location.class)); + when(user.getPlayer()).thenReturn(mock(Player.class)); + when(user.hasPermission(Mockito.anyString())).thenReturn(true); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class)); + + FlagsManager fm = mock(FlagsManager.class); + flag = mock(Flag.class); + when(flag.isSetForWorld(Mockito.any())).thenReturn(false); + PanelItem item = mock(PanelItem.class); + when(item.getItem()).thenReturn(mock(ItemStack.class)); + when(flag.toPanelItem(Mockito.any(), Mockito.eq(user))).thenReturn(item); + when(fm.getFlagByID(Mockito.anyString())).thenReturn(flag); + when(plugin.getFlagsManager()).thenReturn(fm); + + // Island Manager + im = mock(IslandsManager.class); + island = mock(Island.class); + when(island.getOwner()).thenReturn(uuid); + when(im.getIsland(Mockito.any(World.class), Mockito.any(User.class))).thenReturn(island); + when(plugin.getIslands()).thenReturn(im); + } + + @Test + public void testOnClickWrongWorld() { + when(iwm.inWorld(Mockito.any())).thenReturn(false); + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(user).sendMessage("general.errors.wrong-world"); + } + + @Test + public void testOnClickNoPermission() { + when(user.hasPermission(Mockito.anyString())).thenReturn(false); + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(user).sendMessage("general.errors.no-permission"); + Mockito.verify(user).sendMessage("general.errors.you-need", "[permission]", "bskyblock.settings.test"); + } + + @Test + public void testOnClick() { + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(island).toggleFlag(flag); + } + + @Test + public void testOnClickNoIsland() { + when(im.getIsland(Mockito.any(), Mockito.any(User.class))).thenReturn(null); + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(island, Mockito.never()).toggleFlag(flag); + } + + @Test + public void testOnClickNotOwner() { + // Pick a different UUID from owner + UUID u = UUID.randomUUID(); + while(u.equals(uuid)) { + u = UUID.randomUUID(); + } + when(island.getOwner()).thenReturn(u); + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(island, Mockito.never()).toggleFlag(flag); + } + +} diff --git a/src/test/java/us/tastybento/bskyblock/listeners/flags/SettingsToggleClickListenerTest.java b/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListenerTest.java similarity index 93% rename from src/test/java/us/tastybento/bskyblock/listeners/flags/SettingsToggleClickListenerTest.java rename to src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListenerTest.java index f2b741b3d..0398d49c1 100644 --- a/src/test/java/us/tastybento/bskyblock/listeners/flags/SettingsToggleClickListenerTest.java +++ b/src/test/java/us/tastybento/bskyblock/api/flags/clicklisteners/WorldToggleClickListenerTest.java @@ -1,4 +1,4 @@ -package us.tastybento.bskyblock.listeners.flags; +package us.tastybento.bskyblock.api.flags.clicklisteners; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -20,7 +20,6 @@ import org.powermock.reflect.Whitebox; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.flags.Flag; -import us.tastybento.bskyblock.api.flags.clicklisteners.WorldToggleClickListener; import us.tastybento.bskyblock.api.panels.Panel; import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.user.User; @@ -30,7 +29,7 @@ import us.tastybento.bskyblock.util.Util; @RunWith(PowerMockRunner.class) @PrepareForTest({BSkyBlock.class, Util.class }) -public class SettingsToggleClickListenerTest { +public class WorldToggleClickListenerTest { private IslandWorldManager iwm; private WorldToggleClickListener listener; @@ -64,7 +63,7 @@ public class SettingsToggleClickListenerTest { when(user.getPlayer()).thenReturn(mock(Player.class)); PowerMockito.mockStatic(Util.class); when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class)); - + FlagsManager fm = mock(FlagsManager.class); flag = mock(Flag.class); when(flag.isSetForWorld(Mockito.any())).thenReturn(false); @@ -88,7 +87,7 @@ public class SettingsToggleClickListenerTest { when(user.hasPermission(Mockito.anyString())).thenReturn(false); listener.onClick(panel, user, ClickType.LEFT, 0); Mockito.verify(user).sendMessage("general.errors.no-permission"); - Mockito.verify(user).sendMessage("general.errors.you-need", "[permission]", "bskyblock.settings.test"); + Mockito.verify(user).sendMessage("general.errors.you-need", "[permission]", "bskyblock.admin.world.settings.test"); } @Test diff --git a/src/test/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListenerTest.java b/src/test/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListenerTest.java new file mode 100644 index 000000000..189c62e3f --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/listeners/flags/InvincibleVisitorsListenerTest.java @@ -0,0 +1,240 @@ +package us.tastybento.bskyblock.listeners.flags; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.api.flags.Flag; +import us.tastybento.bskyblock.api.panels.Panel; +import us.tastybento.bskyblock.api.panels.PanelItem; +import us.tastybento.bskyblock.api.user.User; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.managers.FlagsManager; +import us.tastybento.bskyblock.managers.IslandWorldManager; +import us.tastybento.bskyblock.managers.IslandsManager; +import us.tastybento.bskyblock.util.Util; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({BSkyBlock.class, Util.class, Bukkit.class }) +public class InvincibleVisitorsListenerTest { + + private IslandWorldManager iwm; + private InvincibleVisitorsListener listener; + private Panel panel; + private User user; + private Flag flag; + private IslandsManager im; + private Island island; + private UUID uuid; + private List ivSettings; + private Player player; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + + // Set up plugin + BSkyBlock plugin = mock(BSkyBlock.class); + Whitebox.setInternalState(BSkyBlock.class, "instance", plugin); + // Island World Manager + iwm = mock(IslandWorldManager.class); + when(iwm.inWorld(Mockito.any())).thenReturn(true); + when(iwm.getPermissionPrefix(Mockito.any())).thenReturn("bskyblock"); + when(plugin.getIWM()).thenReturn(iwm); + + listener = new InvincibleVisitorsListener(); + + panel = mock(Panel.class); + when(panel.getInventory()).thenReturn(mock(Inventory.class)); + when(panel.getName()).thenReturn("panel"); + // Sometimes use Mockito.withSettings().verboseLogging() + user = mock(User.class); + when(user.inWorld()).thenReturn(true); + when(user.getWorld()).thenReturn(mock(World.class)); + when(user.getLocation()).thenReturn(mock(Location.class)); + player = mock(Player.class); + when(user.getPlayer()).thenReturn(player); + when(user.hasPermission(Mockito.anyString())).thenReturn(true); + when(user.getTranslation(Mockito.anyString())).thenReturn("panel"); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class)); + + FlagsManager fm = mock(FlagsManager.class); + flag = mock(Flag.class); + when(flag.isSetForWorld(Mockito.any())).thenReturn(false); + PanelItem item = mock(PanelItem.class); + when(item.getItem()).thenReturn(mock(ItemStack.class)); + when(flag.toPanelItem(Mockito.any(), Mockito.eq(user))).thenReturn(item); + when(fm.getFlagByID(Mockito.anyString())).thenReturn(flag); + when(plugin.getFlagsManager()).thenReturn(fm); + + // Island Manager + im = mock(IslandsManager.class); + island = mock(Island.class); + when(island.getOwner()).thenReturn(uuid); + when(im.getIsland(Mockito.any(World.class), Mockito.any(User.class))).thenReturn(island); + // Visitor + when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false); + when(plugin.getIslands()).thenReturn(im); + + // IV Settings + ivSettings = new ArrayList<>(); + ivSettings.add(EntityDamageEvent.DamageCause.CRAMMING.name()); + ivSettings.add(EntityDamageEvent.DamageCause.VOID.name()); + when(iwm.getIvSettings(Mockito.any())).thenReturn(ivSettings); + + PowerMockito.mockStatic(Bukkit.class); + ItemFactory itemF = mock(ItemFactory.class); + ItemMeta imeta = mock(ItemMeta.class); + when(itemF.getItemMeta(Mockito.any())).thenReturn(imeta); + when(Bukkit.getItemFactory()).thenReturn(itemF); + + Inventory top = mock(Inventory.class); + when(top.getSize()).thenReturn(9); + when(panel.getInventory()).thenReturn(top); + + when(Bukkit.createInventory(Mockito.any(), Mockito.anyInt(), Mockito.any())).thenReturn(top); + + } + + @Test + public void testOnClickWrongWorld() { + when(user.inWorld()).thenReturn(false); + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(user).sendMessage("general.errors.wrong-world"); + } + + @Test + public void testOnClickNoPermission() { + when(user.hasPermission(Mockito.anyString())).thenReturn(false); + listener.onClick(panel, user, ClickType.LEFT, 0); + Mockito.verify(user).sendMessage("general.errors.no-permission"); + Mockito.verify(user).sendMessage("general.errors.you-need", "[permission]", "bskyblock.admin.settings.INVINCIBLE_VISITORS"); + } + + @Test + public void testOnClickNotIVPanel() { + ClickType clickType = ClickType.LEFT; + int slot = 5; + when(panel.getName()).thenReturn("not_panel"); + listener.onClick(panel, user, clickType, slot ); + // Should open inv visitors + Mockito.verify(user).closeInventory(); + Mockito.verify(player).openInventory(Mockito.any(Inventory.class)); + } + + @Test + public void testOnClickIVPanel() { + ClickType clickType = ClickType.LEFT; + int slot = 5; // FALL damage + when(panel.getName()).thenReturn("panel"); + + // IV settings should be empty + assertFalse(ivSettings.contains("FALL")); + // Click on the FALL icon + listener.onClick(panel, user, clickType, slot ); + // Should keep panel open + Mockito.verify(user, Mockito.never()).closeInventory(); + // IV settings should now have FALL in it + assertTrue(ivSettings.contains("FALL")); + + // Click on it again + listener.onClick(panel, user, clickType, slot ); + // Should keep panel open + Mockito.verify(user, Mockito.never()).closeInventory(); + // IV settings should not have FALL in it anymore + assertFalse(ivSettings.contains("FALL")); + + + } + + @SuppressWarnings("deprecation") + @Test + public void testOnVisitorGetDamageNotPlayer() { + LivingEntity le = mock(LivingEntity.class); + EntityDamageEvent e = new EntityDamageEvent(le, EntityDamageEvent.DamageCause.CRAMMING, 0D); + listener.onVisitorGetDamage(e); + assertFalse(e.isCancelled()); + } + + @SuppressWarnings("deprecation") + @Test + public void testOnVisitorGetDamageNotInWorld() { + when(iwm.inWorld(Mockito.any())).thenReturn(false); + EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.CRAMMING, 0D); + listener.onVisitorGetDamage(e); + assertFalse(e.isCancelled()); + } + + @SuppressWarnings("deprecation") + @Test + public void testOnVisitorGetDamageNotInIvSettings() { + when(iwm.inWorld(Mockito.any())).thenReturn(false); + EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.BLOCK_EXPLOSION, 0D); + listener.onVisitorGetDamage(e); + assertFalse(e.isCancelled()); + } + + @SuppressWarnings("deprecation") + @Test + public void testOnVisitorGetDamageNotVisitor() { + EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.CRAMMING, 0D); + when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(true); + listener.onVisitorGetDamage(e); + assertFalse(e.isCancelled()); + } + + @SuppressWarnings("deprecation") + @Test + public void testOnVisitorGetDamageNotVoid() { + EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.CRAMMING, 0D); + listener.onVisitorGetDamage(e); + assertTrue(e.isCancelled()); + Mockito.verify(player, Mockito.never()).setGameMode(Mockito.eq(GameMode.SPECTATOR)); + } + + @SuppressWarnings("deprecation") + @Test + public void testOnVisitorGetDamageVoid() { + // For testing, have no island to teleport to + when(im.getIslandAt(Mockito.any())).thenReturn(Optional.empty()); + EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.VOID, 0D); + listener.onVisitorGetDamage(e); + assertTrue(e.isCancelled()); + Mockito.verify(player).setGameMode(Mockito.eq(GameMode.SPECTATOR)); + Mockito.verify(im).getIslandAt(Mockito.any()); + } + +}