diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/AbstractFlagListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/AbstractFlagListener.java index 12b42d0ee..35a060e76 100644 --- a/src/main/java/us/tastybento/bskyblock/listeners/flags/AbstractFlagListener.java +++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/AbstractFlagListener.java @@ -111,9 +111,9 @@ public abstract class AbstractFlagListener implements Listener { * @return true if the location is in the island worlds */ public boolean inWorld(Location loc) { - return (loc.getWorld().equals(plugin.getIslandWorldManager().getIslandWorld()) + return (loc != null && (loc.getWorld().equals(plugin.getIslandWorldManager().getIslandWorld()) || loc.getWorld().equals(plugin.getIslandWorldManager().getNetherWorld()) - || loc.getWorld().equals(plugin.getIslandWorldManager().getEndWorld())) ? true : false; + || loc.getWorld().equals(plugin.getIslandWorldManager().getEndWorld()))) ? true : false; } /** diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListener.java index f0fab8275..c4bbe04d0 100644 --- a/src/main/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListener.java +++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListener.java @@ -27,12 +27,13 @@ public class MobSpawnListener extends AbstractFlagListener { * Prevents mobs spawning naturally * * @param e - event + * @return true if cancelled */ @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onNaturalMobSpawn(final CreatureSpawnEvent e) { + public boolean onNaturalMobSpawn(CreatureSpawnEvent e) { // If not in the right world, return if (!inWorld(e.getEntity())) { - return; + return false; } // Deal with natural spawning if (e.getSpawnReason().equals(SpawnReason.NATURAL) @@ -41,30 +42,24 @@ public class MobSpawnListener extends AbstractFlagListener { || e.getSpawnReason().equals(SpawnReason.DEFAULT) || e.getSpawnReason().equals(SpawnReason.MOUNT) || e.getSpawnReason().equals(SpawnReason.NETHER_PORTAL)) { + Optional island = getIslands().getIslandAt(e.getLocation()); - if (island.isPresent()) { - if ((e.getEntity() instanceof Monster || e.getEntity() instanceof Slime) - && !island.get().isAllowed(Flags.MOB_SPAWN)) { - // Mobs not allowed to spawn - e.setCancelled(true); - } else if (e.getEntity() instanceof Animals - && !island.get().isAllowed(Flags.MONSTER_SPAWN)) { - // Mobs not allowed to spawn - e.setCancelled(true); - } - } else { - // Outside of the island - if ((e.getEntity() instanceof Monster || e.getEntity() instanceof Slime) - && !Flags.MOB_SPAWN.isDefaultSetting()) { - // Mobs not allowed to spawn - e.setCancelled(true); - } else if (e.getEntity() instanceof Animals - && !Flags.MONSTER_SPAWN.isDefaultSetting()) { - // Mobs not allowed to spawn - e.setCancelled(true); - } + // Cancel the event if these are true + if ((e.getEntity() instanceof Monster || e.getEntity() instanceof Slime)) { + boolean cancel = island.map(i -> { + return !i.isAllowed(Flags.MOB_SPAWN); + }).orElse(!Flags.MOB_SPAWN.isDefaultSetting()); + e.setCancelled(cancel); + return cancel; + } else if (e.getEntity() instanceof Animals) { + boolean cancel = island.map(i -> { + return !i.isAllowed(Flags.MONSTER_SPAWN); + }).orElse(!Flags.MONSTER_SPAWN.isDefaultSetting()); + e.setCancelled(cancel); + return cancel; } } + return false; } } diff --git a/src/test/java/bskyblock/TestBSkyBlock.java b/src/test/java/bskyblock/TestBSkyBlock.java index 77343bf3e..5886a7ebf 100644 --- a/src/test/java/bskyblock/TestBSkyBlock.java +++ b/src/test/java/bskyblock/TestBSkyBlock.java @@ -35,7 +35,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemFactory; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.plugin.PluginManager; import org.junit.Assert; @@ -81,7 +80,6 @@ public class TestBSkyBlock { private static BSkyBlock plugin; private static FlagsManager flagsManager; private static Block block; - private static World world; private static Player ownerOfIsland; private static Player visitorToIsland; @@ -89,7 +87,6 @@ public class TestBSkyBlock { public static void setUp() { Server server = mock(Server.class); World world = mock(World.class); - world = mock(World.class); Mockito.when(server.getLogger()).thenReturn(Logger.getAnonymousLogger()); Mockito.when(server.getWorld("world")).thenReturn(world); Mockito.when(server.getVersion()).thenReturn("BSB_Mocking"); @@ -103,7 +100,6 @@ public class TestBSkyBlock { Bukkit.setServer(server); SkullMeta skullMeta = mock(SkullMeta.class); - ItemMeta itemMeta = mock(ItemMeta.class); when(itemFactory.getItemMeta(any())).thenReturn(skullMeta); OfflinePlayer offlinePlayer = mock(OfflinePlayer.class); @@ -137,13 +133,6 @@ public class TestBSkyBlock { Mockito.when(ownerOfIsland.getUniqueId()).thenReturn(OWNER_UUID); Mockito.when(visitorToIsland.getUniqueId()).thenReturn(VISITOR_UUID); - // Mock itemFactory for ItemStack - /* - ItemFactory itemFactory = PowerMockito.mock(ItemFactory.class); - PowerMockito.when(Bukkit.getItemFactory()).thenReturn(itemFactory); - ItemMeta itemMeta = PowerMockito.mock(ItemMeta.class); - PowerMockito.when(itemFactory.getItemMeta(Matchers.any())).thenReturn(itemMeta); - */ PowerMockito.mockStatic(Flags.class); plugin = Mockito.mock(BSkyBlock.class); diff --git a/src/test/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListenerTest.java b/src/test/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListenerTest.java new file mode 100644 index 000000000..0c72480ac --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/listeners/flags/MobSpawnListenerTest.java @@ -0,0 +1,273 @@ +package us.tastybento.bskyblock.listeners.flags; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Optional; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Zombie; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.PluginManager; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.database.managers.island.IslandsManager; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.generators.IslandWorld; +import us.tastybento.bskyblock.lists.Flags; +import us.tastybento.bskyblock.managers.FlagsManager; + +@RunWith(PowerMockRunner.class) +@PrepareForTest( { Flags.class }) +public class MobSpawnListenerTest { + + private static Location location; + private static BSkyBlock plugin; + private static FlagsManager flagsManager; + private static Zombie zombie; + private static Slime slime; + private static Cow cow; + + @BeforeClass + public static void setUp() { + Server server = mock(Server.class); + World world = mock(World.class); + when(server.getLogger()).thenReturn(Logger.getAnonymousLogger()); + when(server.getWorld("world")).thenReturn(world); + when(server.getVersion()).thenReturn("BSB_Mocking"); + + PluginManager pluginManager = mock(PluginManager.class); + when(server.getPluginManager()).thenReturn(pluginManager); + + ItemFactory itemFactory = mock(ItemFactory.class); + when(server.getItemFactory()).thenReturn(itemFactory); + + Bukkit.setServer(server); + + SkullMeta skullMeta = mock(SkullMeta.class); + when(itemFactory.getItemMeta(any())).thenReturn(skullMeta); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); + when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); + location = mock(Location.class); + when(location.getWorld()).thenReturn(world); + when(location.getBlockX()).thenReturn(0); + when(location.getBlockY()).thenReturn(0); + when(location.getBlockZ()).thenReturn(0); + PowerMockito.mockStatic(Flags.class); + + plugin = Mockito.mock(BSkyBlock.class); + flagsManager = new FlagsManager(plugin); + when(plugin.getFlagsManager()).thenReturn(flagsManager); + + + // Worlds + IslandWorld iwm = mock(IslandWorld.class); + when(plugin.getIslandWorldManager()).thenReturn(iwm); + when(iwm.getIslandWorld()).thenReturn(world); + when(iwm.getNetherWorld()).thenReturn(world); + when(iwm.getEndWorld()).thenReturn(world); + + MobSpawnListener listener = mock(MobSpawnListener.class); + when(listener.inWorld(any(Location.class))).thenReturn(true); + when(listener.inWorld(any(Entity.class))).thenReturn(true); + + // Monsters and animals + zombie = mock(Zombie.class); + when(zombie.getLocation()).thenReturn(location); + slime = mock(Slime.class); + when(slime.getLocation()).thenReturn(location); + cow = mock(Cow.class); + when(cow.getLocation()).thenReturn(location); + + } + + + @Test + public void testNotInWorld() { + IslandsManager im = mock(IslandsManager.class); + when(plugin.getIslands()).thenReturn(im); + Island island = mock(Island.class); + when(im.getIslandAt(Matchers.any())).thenReturn(Optional.of(island)); + + // Set up entity + LivingEntity entity = mock(LivingEntity.class); + when(entity.getLocation()).thenReturn(null); + + // Setup event + CreatureSpawnEvent e = mock(CreatureSpawnEvent.class); + when(e.getLocation()).thenReturn(location); + + // Setup the listener + MobSpawnListener l = new MobSpawnListener(); + l.setPlugin(plugin); + + // Check monsters + when(e.getEntity()).thenReturn(entity); + + // Should not be canceled + assertFalse(l.onNaturalMobSpawn(e)); + } + + @Test + public void testOnNaturalMonsterSpawnBlocked() { + IslandsManager im = mock(IslandsManager.class); + when(plugin.getIslands()).thenReturn(im); + Island island = mock(Island.class); + when(im.getIslandAt(Matchers.any())).thenReturn(Optional.of(island)); + + // Block mobs + when(island.isAllowed(Mockito.any())).thenReturn(false); + + // Setup event + CreatureSpawnEvent e = mock(CreatureSpawnEvent.class); + when(e.getLocation()).thenReturn(location); + + // Setup the listener + MobSpawnListener l = new MobSpawnListener(); + l.setPlugin(plugin); + + // Check monsters + when(e.getEntity()).thenReturn(zombie); + checkBlocked(e,l); + when(e.getEntity()).thenReturn(slime); + checkBlocked(e,l); + // Check animal + when(e.getEntity()).thenReturn(cow); + checkBlocked(e,l); + + } + + private void checkBlocked(CreatureSpawnEvent e, MobSpawnListener l) { + for (SpawnReason reason: SpawnReason.values()) { + when(e.getSpawnReason()).thenReturn(reason); + if (reason.equals(SpawnReason.NATURAL) + || reason.equals(SpawnReason.JOCKEY) + || reason.equals(SpawnReason.CHUNK_GEN) + || reason.equals(SpawnReason.DEFAULT) + || reason.equals(SpawnReason.MOUNT) + || reason.equals(SpawnReason.NETHER_PORTAL)) { + assertTrue(l.onNaturalMobSpawn(e)); + } else { + assertFalse(l.onNaturalMobSpawn(e)); + } + } + + } + + @Test + public void testOnNaturalMobSpawnUnBlocked() { + IslandsManager im = mock(IslandsManager.class); + when(plugin.getIslands()).thenReturn(im); + Island island = mock(Island.class); + when(im.getIslandAt(Matchers.any())).thenReturn(Optional.of(island)); + + // Allow mobs + when(island.isAllowed(Mockito.any())).thenReturn(true); + + // Setup event + CreatureSpawnEvent e = mock(CreatureSpawnEvent.class); + when(e.getLocation()).thenReturn(location); + + // Setup the listener + MobSpawnListener l = new MobSpawnListener(); + l.setPlugin(plugin); + + // Check monsters + when(e.getEntity()).thenReturn(zombie); + checkUnBlocked(e,l); + when(e.getEntity()).thenReturn(slime); + checkUnBlocked(e,l); + // Check animal + when(e.getEntity()).thenReturn(cow); + checkUnBlocked(e,l); + + } + + private void checkUnBlocked(CreatureSpawnEvent e, MobSpawnListener l) { + for (SpawnReason reason: SpawnReason.values()) { + when(e.getSpawnReason()).thenReturn(reason); + assertFalse(l.onNaturalMobSpawn(e)); + } + + } + + @Test + public void testOnNaturalMonsterSpawnBlockedNoIsland() { + IslandsManager im = mock(IslandsManager.class); + when(plugin.getIslands()).thenReturn(im); + when(im.getIslandAt(Matchers.any())).thenReturn(Optional.empty()); + + // Block mobs + Flags.MONSTER_SPAWN.setDefaultSetting(false); + Flags.MOB_SPAWN.setDefaultSetting(false); + // Setup event + CreatureSpawnEvent e = mock(CreatureSpawnEvent.class); + when(e.getLocation()).thenReturn(location); + + // Setup the listener + MobSpawnListener l = new MobSpawnListener(); + l.setPlugin(plugin); + + // Check monsters + when(e.getEntity()).thenReturn(zombie); + checkBlocked(e,l); + when(e.getEntity()).thenReturn(slime); + checkBlocked(e,l); + // Check animal + when(e.getEntity()).thenReturn(cow); + checkBlocked(e,l); + + } + + @Test + public void testOnNaturalMobSpawnUnBlockedNoIsland() { + IslandsManager im = mock(IslandsManager.class); + when(plugin.getIslands()).thenReturn(im); + when(im.getIslandAt(Matchers.any())).thenReturn(Optional.empty()); + + // Block mobs + Flags.MONSTER_SPAWN.setDefaultSetting(true); + Flags.MOB_SPAWN.setDefaultSetting(true); + + // Setup event + CreatureSpawnEvent e = mock(CreatureSpawnEvent.class); + when(e.getLocation()).thenReturn(location); + + // Setup the listener + MobSpawnListener l = new MobSpawnListener(); + l.setPlugin(plugin); + + // Check monsters + when(e.getEntity()).thenReturn(zombie); + checkUnBlocked(e,l); + when(e.getEntity()).thenReturn(slime); + checkUnBlocked(e,l); + // Check animal + when(e.getEntity()).thenReturn(cow); + checkUnBlocked(e,l); + + } + +} diff --git a/src/test/java/us/tastybento/bskyblock/util/PairTest.java b/src/test/java/us/tastybento/bskyblock/util/PairTest.java index 3ed831f90..b363001a7 100644 --- a/src/test/java/us/tastybento/bskyblock/util/PairTest.java +++ b/src/test/java/us/tastybento/bskyblock/util/PairTest.java @@ -1,6 +1,8 @@ package us.tastybento.bskyblock.util; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test;