From bbb8207cf0c3f01e45e33a2024bea90ef973a744 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 28 Jan 2023 16:04:52 -0800 Subject: [PATCH] Teleportation was processed for entities even if it was switched off Addresses #2078 Added test class to cover some of the logic in the teleportation class. More tests can be written to cover the various outcomes. --- .../teleports/EntityTeleportListener.java | 20 +- .../listeners/flags/AbstractCommonSetup.java | 2 + .../teleports/EntityTeleportListenerTest.java | 220 ++++++++++++++++++ 3 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 src/test/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListenerTest.java diff --git a/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java b/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java index b9b4f04cf..5e188f2b7 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java @@ -75,8 +75,8 @@ public class EntityTeleportListener extends AbstractTeleportListener implements { // Teleportation is disabled. Cancel event. event.setCancelled(true); + return; } - // Trigger event processor. this.portalProcess(event, event.getTo().getWorld().getEnvironment()); } @@ -204,26 +204,24 @@ public class EntityTeleportListener extends AbstractTeleportListener implements event.setCancelled(true); return; } - + if (!this.isAllowedInConfig(overWorld, environment)) { // World is disabled in config. Do not teleport player. event.setCancelled(true); return; } - + if (!this.isAllowedOnServer(environment)) { - // World is disabled in bukkit. Event is not triggered, but cancel by chance. + // World is disabled in bukkit. Event is not triggered, but cancel just in case. event.setCancelled(true); } - if (this.inTeleport.contains(event.getEntity().getUniqueId())) { // Entity is already in teleportation. return; } - this.inTeleport.add(event.getEntity().getUniqueId()); // Get target world. @@ -244,7 +242,7 @@ public class EntityTeleportListener extends AbstractTeleportListener implements this.handleToStandardNetherOrEnd(event, overWorld, toWorld); return; } - + if (!overWorld.equals(fromWorld) && !this.isIslandWorld(overWorld, environment)) { // If entering a portal in the other world, teleport to a portal in overworld if @@ -252,7 +250,7 @@ public class EntityTeleportListener extends AbstractTeleportListener implements this.handleFromStandardNetherOrEnd(event, overWorld, toWorld.getEnvironment()); return; } - + // Set the destination location // If portals cannot be created, then destination is the spawn point, otherwise it's the vector event.setTo(this.calculateLocation(event.getFrom(), @@ -282,20 +280,20 @@ public class EntityTeleportListener extends AbstractTeleportListener implements // visit that dimension. return; } - + if (!event.isCancelled()) { // Let the server teleport return; } - + if (environment.equals(World.Environment.THE_END)) { // Prevent death from hitting the ground while calculating location. event.getEntity().setVelocity(new Vector(0,0,0)); event.getEntity().setFallDistance(0); } - + // If we do not generate portals, teleportation should happen manually with safe spot builder. // Otherwise, we could end up with situations when player is placed in mid air, if teleportation // is done instantly. diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java b/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java index 3140a989a..cd57498d1 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java @@ -19,6 +19,7 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.PluginManager; +import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.Nullable; import org.junit.After; import org.junit.runner.RunWith; @@ -103,6 +104,7 @@ public abstract class AbstractCommonSetup { when(location.getBlockX()).thenReturn(0); when(location.getBlockY()).thenReturn(0); when(location.getBlockZ()).thenReturn(0); + when(location.toVector()).thenReturn(new Vector(0,0,0)); // Players Manager and meta data PlayersManager pm = mock(PlayersManager.class); diff --git a/src/test/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListenerTest.java new file mode 100644 index 000000000..fac45889f --- /dev/null +++ b/src/test/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListenerTest.java @@ -0,0 +1,220 @@ +package world.bentobox.bentobox.listeners.teleports; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.event.entity.EntityPortalEvent; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.listeners.flags.AbstractCommonSetup; +import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.util.Util; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({BentoBox.class, Util.class, Bukkit.class }) +public class EntityTeleportListenerTest extends AbstractCommonSetup { + + private EntityTeleportListener etl; + @Mock + private IslandsManager im; + + + /** + * @throws java.lang.Exception + */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + + when(plugin.getIslands()).thenReturn(im); + when(plugin.getIslandsManager()).thenReturn(im); + + when(im.getProtectedIslandAt(any())).thenReturn(Optional.of(island)); + + etl = new EntityTeleportListener(plugin); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#EntityTeleportListener(world.bentobox.bentobox.BentoBox)}. + */ + @Test + public void testEntityTeleportListener() { + assertNotNull(etl); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalWrongWorld() { + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.getWorld(any())).thenReturn(null); + EntityPortalEvent event = new EntityPortalEvent(player, location, location, 10); + etl.onEntityPortal(event); + assertFalse(event.isCancelled()); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalWrongWorld2() { + when(iwm.inWorld(any(World.class))).thenReturn(false); + EntityPortalEvent event = new EntityPortalEvent(player, location, location, 10); + etl.onEntityPortal(event); + assertFalse(event.isCancelled()); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalNullTo() { + EntityPortalEvent event = new EntityPortalEvent(player, location, null, 10); + etl.onEntityPortal(event); + assertFalse(event.isCancelled()); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalTeleportDisabled() { + EntityPortalEvent event = new EntityPortalEvent(player, location, location, 10); + etl.onEntityPortal(event); + assertTrue(event.isCancelled()); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalTeleportEnabled() { + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.getWorld(any())).thenReturn(world); + when(world.getEnvironment()).thenReturn(Environment.NORMAL); + + Flags.ENTITY_PORTAL_TELEPORT.setSetting(world, true); + EntityPortalEvent event = new EntityPortalEvent(player, location, location, 10); + etl.onEntityPortal(event); + assertFalse(event.isCancelled()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalTeleportEnabledMissingWorld() { + when(iwm.isNetherGenerate(any())).thenReturn(false); + + Location location2 = mock(Location.class); + World world2 = mock(World.class); + when(location2.getWorld()).thenReturn(world2); + when(world2.getEnvironment()).thenReturn(Environment.NETHER); + + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.getWorld(any())).thenReturn(world2); + + when(location.getWorld()).thenReturn(null); + Flags.ENTITY_PORTAL_TELEPORT.setSetting(world, true); + EntityPortalEvent event = new EntityPortalEvent(player, location, location2, 10); + etl.onEntityPortal(event); + assertTrue(event.isCancelled()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalTeleportEnabledIsNotAllowedInConfig() { + when(iwm.isNetherGenerate(any())).thenReturn(false); + + Location location2 = mock(Location.class); + World world2 = mock(World.class); + when(location2.getWorld()).thenReturn(world2); + when(world2.getEnvironment()).thenReturn(Environment.NETHER); + + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.getWorld(any())).thenReturn(world2); + + Flags.ENTITY_PORTAL_TELEPORT.setSetting(world2, true); + EntityPortalEvent event = new EntityPortalEvent(player, location, location2, 10); + etl.onEntityPortal(event); + assertTrue(event.isCancelled()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityPortal(org.bukkit.event.entity.EntityPortalEvent)}. + */ + @Test + public void testOnEntityPortalTeleportEnabledIsAllowedInConfig() { + when(iwm.isNetherGenerate(any())).thenReturn(true); + when(iwm.isNetherIslands(any())).thenReturn(true); + + Location location2 = mock(Location.class); + World world2 = mock(World.class); + when(location2.getWorld()).thenReturn(world2); + when(world2.getEnvironment()).thenReturn(Environment.NETHER); + + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.getWorld(any())).thenReturn(world2); + + Flags.ENTITY_PORTAL_TELEPORT.setSetting(world2, true); + EntityPortalEvent event = new EntityPortalEvent(player, location, location2, 10); + etl.onEntityPortal(event); + assertTrue(event.isCancelled()); + + } + + /** + * TODO: Lots more tests can be written here. + */ + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityEnterPortal(org.bukkit.event.entity.EntityPortalEnterEvent)}. + */ + @Test + public void testOnEntityEnterPortal() { + /** + * TODO: Lots more tests can be written here. + */ + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.teleports.EntityTeleportListener#onEntityExitPortal(org.bukkit.event.entity.EntityPortalExitEvent)}. + */ + @Test + public void testOnEntityExitPortal() { + /** + * TODO: Lots more tests can be written here. + */ + } + +}