diff --git a/pom.xml b/pom.xml
index 10d06d3..c814b6d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,7 +65,7 @@
-LOCAL
- 2.1.0
+ 2.1.1
BentoBoxWorld_Boxed
bentobox-world
diff --git a/src/main/java/world/bentobox/boxed/listeners/EnderPearlListener.java b/src/main/java/world/bentobox/boxed/listeners/EnderPearlListener.java
index 552e8d0..c90fd99 100644
--- a/src/main/java/world/bentobox/boxed/listeners/EnderPearlListener.java
+++ b/src/main/java/world/bentobox/boxed/listeners/EnderPearlListener.java
@@ -2,8 +2,10 @@ package world.bentobox.boxed.listeners;
import java.io.IOException;
+import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
+import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.EntityType;
@@ -12,8 +14,11 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
import world.bentobox.bentobox.api.user.User;
+import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.util.Util;
import world.bentobox.boxed.Boxed;
/**
@@ -32,34 +37,93 @@ public class EnderPearlListener implements Listener {
this.addon = addon;
}
-
+ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+ public void onPlayerTeleport(PlayerTeleportEvent e) {
+ if (!addon.inWorld(e.getFrom()) || !e.getPlayer().getGameMode().equals(GameMode.SURVIVAL)
+ || (e.getTo() != null && !addon.inWorld(e.getTo()))
+ || addon.getIslands().getSpawn(e.getFrom().getWorld()).map(spawn -> spawn.onIsland(e.getTo())).orElse(false)
+ ) {
+ return;
+ }
+
+ User u = User.getInstance(e.getPlayer());
+ // If the to is outside the box, cancel it
+ if (e.getTo() != null) {
+ Island i = addon.getIslands().getIsland(e.getFrom().getWorld(), u);
+ if (i == null || !i.onIsland(e.getTo())) {
+ u.sendMessage("boxed.general.errors.no-teleport-outside");
+ e.setCancelled(true);
+ return;
+ }
+ }
+ }
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onEnderPearlLand(ProjectileHitEvent e) {
if (!e.getEntityType().equals(EntityType.ENDER_PEARL)
|| e.getHitBlock() == null
- || !addon.inWorld(e.getHitBlock().getLocation())) {
+ || !addon.inWorld(e.getHitBlock().getLocation())
+ || !Boxed.ALLOW_MOVE_BOX.isSetForWorld(e.getHitBlock().getWorld())
+ ) {
return;
- }
+ }
+ // Moving box is allowed
Location l = e.getHitBlock().getRelative(BlockFace.UP).getLocation();
- EnderPearl ep = (EnderPearl)e.getEntity();
- if (ep.getShooter() instanceof Player player) {
+ World w = e.getHitBlock().getWorld();
+ if (e.getEntity() instanceof EnderPearl ep && ep.getShooter() instanceof Player player) {
User u = User.getInstance(player);
- addon.getIslands().getIslandAt(l).ifPresent(i -> {
- // Check flag
- if (i.isAllowed(u, Boxed.MOVE_BOX) && addon.getIslands().isSafeLocation(l)) {
- // Reset home locations
- i.getMemberSet().forEach(uuid -> addon.getIslands().setHomeLocation(uuid, l));
- try {
- i.setProtectionCenter(l);
- i.setSpawnPoint(l.getWorld().getEnvironment(), l);
- u.getPlayer().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 2F, 2F);
- } catch (IOException e1) {
- addon.logError("Could not move box " + e1.getMessage());
- }
+ // Check if enderpearl is inside or outside the box
+ // Get user's box
+ Island is = addon.getIslands().getIsland(w, u);
+ if (is == null) {
+ return; // Nothing to do
+ }
+
+ // Get the box that the player is in
+ addon.getIslands().getIslandAt(u.getLocation()).ifPresent(fromIsland -> {
+ // Check that it is their box
+ if (!is.getUniqueId().equals(fromIsland.getUniqueId())) {
+ return;
}
+ // Find where the pearl landed
+ addon.getIslands().getIslandAt(l).ifPresentOrElse(toIsland -> {
+ if (fromIsland.getUniqueId().equals(toIsland.getUniqueId())) {
+ if (!toIsland.onIsland(l)) {
+ // Moving is allowed
+ moveBox(u, fromIsland, l);
+ Util.teleportAsync(player, l);
+ return;
+ }
+ } else {
+ // Different box. This is never allowed. Cancel the throw
+ e.setCancelled(true);
+ u.sendMessage("boxed.general.errors.no-teleport-outside");
+ return;
+ }
+ }, () -> {
+ // No box. This is never allowed. Cancel the throw
+ e.setCancelled(true);
+ u.sendMessage("boxed.general.errors.no-teleport-outside");
+ return;
+ });
+
});
}
}
+
+
+ private void moveBox(User u, Island fromIsland, Location l) {
+ // Reset home locations
+ fromIsland.getMemberSet().forEach(uuid -> addon.getIslands().setHomeLocation(uuid, l));
+ try {
+ fromIsland.setProtectionCenter(l);
+ fromIsland.setSpawnPoint(l.getWorld().getEnvironment(), l);
+ u.getPlayer().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 2F, 2F);
+ } catch (IOException e1) {
+ addon.logError("Could not move box " + e1.getMessage());
+ }
+
+ }
+
}
diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml
index 4c603c4..05d1b92 100755
--- a/src/main/resources/locales/en-US.yml
+++ b/src/main/resources/locales/en-US.yml
@@ -15,6 +15,7 @@ boxed:
already-have-island: '&c You already have a box!'
no-safe-location: '&c No safe location found in box!'
not-owner: '&c You are not the owner of your team!'
+ no-teleport-outside: "&c You cannot teleport outside of your box"
commands:
boxed:
help:
@@ -305,6 +306,12 @@ boxed:
deleted-island: '&a Area at &e [xyz] &a has been successfully regenerated.'
protection:
flags:
+ ALLOW_MOVE_BOX:
+ name: Box moving
+ description: |-
+ &a Allow players to move
+ &a their box by throwing
+ &a enderpearls
ELYTRA:
description: Toggle use
ENDERMAN_GRIEFING:
diff --git a/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java b/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java
new file mode 100644
index 0000000..0522a4f
--- /dev/null
+++ b/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java
@@ -0,0 +1,400 @@
+package world.bentobox.boxed.listeners;
+
+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.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+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.Sound;
+import org.bukkit.World;
+import org.bukkit.World.Environment;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.entity.Creeper;
+import org.bukkit.entity.EnderPearl;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.entity.ProjectileHitEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
+import org.bukkit.util.BoundingBox;
+import org.bukkit.util.Vector;
+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 org.powermock.reflect.Whitebox;
+
+import com.google.common.collect.ImmutableSet;
+
+import world.bentobox.bentobox.BentoBox;
+import world.bentobox.bentobox.api.user.User;
+import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.managers.IslandWorldManager;
+import world.bentobox.bentobox.managers.IslandsManager;
+import world.bentobox.bentobox.util.Util;
+import world.bentobox.boxed.Boxed;
+import world.bentobox.boxed.Settings;
+
+/**
+ * @author tastybento
+ *
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Util.class })
+public class EnderPearlListenerTest {
+
+ @Mock
+ private BentoBox plugin;
+ @Mock
+ private Boxed addon;
+ @Mock
+ private Player player;
+ @Mock
+ private Location from;
+ @Mock
+ private Location to;
+ @Mock
+ private World world;
+ @Mock
+ private IslandsManager im;
+ @Mock
+ private Island island;
+ @Mock
+ private Island anotherIsland;
+ @Mock
+ private Island spawn;
+ @Mock
+ private User user;
+ @Mock
+ private EnderPearl projectile;
+ @Mock
+ private Block hitBlock;
+
+ private Settings settings;
+ private EnderPearlListener epl;
+ @Mock
+ private IslandWorldManager iwm;
+
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+
+ // Set up plugin
+ plugin = mock(BentoBox.class);
+ Whitebox.setInternalState(BentoBox.class, "instance", plugin);
+
+ when(plugin.getIWM()).thenReturn(iwm);
+
+
+
+ PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
+
+ PowerMockito.mockStatic(User.class, Mockito.RETURNS_MOCKS);
+ when(User.getInstance(any(Player.class))).thenReturn(user);
+ // Settings
+ settings = new Settings();
+ when(addon.getSettings()).thenReturn(settings);
+ when(iwm.getWorldSettings(world)).thenReturn(settings);
+ when(iwm.inWorld(world)).thenReturn(true);
+
+ // Locations
+ when(to.getWorld()).thenReturn(world);
+ when(from.getWorld()).thenReturn(world);
+ when(from.toVector()).thenReturn(new Vector(1,2,3));
+ when(to.toVector()).thenReturn(new Vector(6,7,8));
+ when(world.getEnvironment()).thenReturn(Environment.NORMAL);
+
+ // In game world
+ when(addon.inWorld(any(World.class))).thenReturn(true);
+ when(addon.inWorld(any(Location.class))).thenReturn(true);
+
+ // User
+ when(user.getPlayer()).thenReturn(player);
+ when(player.getGameMode()).thenReturn(GameMode.SURVIVAL);
+ when(player.getWorld()).thenReturn(world);
+ when(user.getMetaData(anyString())).thenReturn(Optional.empty()); // No meta data
+ when(player.getLocation()).thenReturn(from);
+ when(user.getLocation()).thenReturn(from);
+
+ // Islands
+ when(island.onIsland(any())).thenReturn(true); // Default on island
+ when(im.getIsland(world, user)).thenReturn(island);
+ when(im.getIslandAt(any())).thenReturn(Optional.of(island));
+ when(addon.getIslands()).thenReturn(im);
+ when(im.getProtectedIslandAt(any())).thenReturn(Optional.of(island));
+ when(island.getUniqueId()).thenReturn("uniqueID");
+ when(island.getProtectionCenter()).thenReturn(from);
+ when(island.getProtectionBoundingBox()).thenReturn(BoundingBox.of(new Vector(0,0,0), new Vector(50,50,50)));
+ when(island.getRange()).thenReturn(3);
+ when(im.isSafeLocation(any())).thenReturn(true); // safe for now
+ when(island.getPlayersOnIsland()).thenReturn(List.of(player));
+ when(im.getSpawn(any())).thenReturn(Optional.of(spawn));
+ when(island.onIsland(from)).thenReturn(true);
+ when(island.onIsland(to)).thenReturn(false);
+ when(island.getMemberSet()).thenReturn(ImmutableSet.of(UUID.randomUUID()));
+ // Another island
+ when(anotherIsland.getUniqueId()).thenReturn("another_uniqueID");
+
+ // Projectiles
+ when(projectile.getType()).thenReturn(EntityType.ENDER_PEARL);
+ when(projectile.getShooter()).thenReturn(player);
+ when(hitBlock.getLocation()).thenReturn(to);
+ when(hitBlock.getWorld()).thenReturn(world);
+ when(hitBlock.getRelative(BlockFace.UP)).thenReturn(hitBlock);
+ Boxed.ALLOW_MOVE_BOX.setSetting(world, true);
+
+ epl = new EnderPearlListener(addon);
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#EnderPearlListener(world.bentobox.boxed.Boxed)}.
+ */
+ @Test
+ public void testEnderPearlListener() {
+ assertNotNull(epl);
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onPlayerTeleport(org.bukkit.event.player.PlayerTeleportEvent)}.
+ */
+ @Test
+ public void testOnPlayerTeleportNotAllowed() {
+ PlayerTeleportEvent e = new PlayerTeleportEvent(player, from, to, TeleportCause.CHORUS_FRUIT);
+ epl.onPlayerTeleport(e);
+ assertTrue(e.isCancelled());
+ verify(user).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onPlayerTeleport(org.bukkit.event.player.PlayerTeleportEvent)}.
+ */
+ @Test
+ public void testOnPlayerTeleportNotSurvival() {
+ when(player.getGameMode()).thenReturn(GameMode.CREATIVE);
+ PlayerTeleportEvent e = new PlayerTeleportEvent(player, from, to, TeleportCause.CHORUS_FRUIT);
+ epl.onPlayerTeleport(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onPlayerTeleport(org.bukkit.event.player.PlayerTeleportEvent)}.
+ */
+ @Test
+ public void testOnPlayerTeleportNullTo() {
+ when(player.getGameMode()).thenReturn(GameMode.CREATIVE);
+ PlayerTeleportEvent e = new PlayerTeleportEvent(player, from, null, TeleportCause.CHORUS_FRUIT);
+ epl.onPlayerTeleport(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onPlayerTeleport(org.bukkit.event.player.PlayerTeleportEvent)}.
+ */
+ @Test
+ public void testOnPlayerTeleportToSpawn() {
+ when(spawn.onIsland(any())).thenReturn(true);
+ PlayerTeleportEvent e = new PlayerTeleportEvent(player, from, to, TeleportCause.CHORUS_FRUIT);
+ epl.onPlayerTeleport(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onPlayerTeleport(org.bukkit.event.player.PlayerTeleportEvent)}.
+ */
+ @Test
+ public void testOnPlayerTeleportNotInWorldAllowed() {
+ when(addon.inWorld(any(World.class))).thenReturn(false);
+ when(addon.inWorld(any(Location.class))).thenReturn(false);
+ PlayerTeleportEvent e = new PlayerTeleportEvent(player, from, to, TeleportCause.CHORUS_FRUIT);
+ epl.onPlayerTeleport(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandNotEnderPearl() throws IOException {
+ when(projectile.getType()).thenReturn(EntityType.ARROW);
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verifyFailure();
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandNullHitBlock() throws IOException {
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, null, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verifyFailure();
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandNotInWorld() throws IOException {
+ when(addon.inWorld(to)).thenReturn(false);
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verifyFailure();
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandNotMovingBox() throws IOException {
+ Boxed.ALLOW_MOVE_BOX.setSetting(world, false);
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verifyFailure();
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandNonHuman() throws IOException {
+ Creeper creeper = mock(Creeper.class);
+ when(projectile.getShooter()).thenReturn(creeper);
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verifyFailure();
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandUserHasNoIsland() throws IOException {
+ when(im.getIsland(world, user)).thenReturn(null);
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verifyFailure();
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlNotOnIslandWhenThrowing() throws IOException {
+ when(im.getIslandAt(any())).thenReturn(Optional.empty());
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verifyFailure();
+ }
+
+ private void verifyFailure() throws IOException {
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verify(im, never()).setHomeLocation(any(UUID.class), any());
+ verify(island, never()).setProtectionCenter(any());
+ verify(island, never()).setSpawnPoint(any(), any());
+ verify(player, never()).playSound(any(Location.class), any(Sound.class), anyFloat(), anyFloat());
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlLandHuman() throws IOException {
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(user, never()).sendMessage("boxed.general.errors.no-teleport-outside");
+ verify(im).setHomeLocation(any(UUID.class), eq(to));
+ verify(island).setProtectionCenter(to);
+ verify(island).setSpawnPoint(Environment.NORMAL, to);
+ verify(player).playSound(to, Sound.ENTITY_GENERIC_EXPLODE, 2F, 2F);
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlThrewToDifferentIsland() throws IOException {
+ when(im.getIslandAt(eq(to))).thenReturn(Optional.of(anotherIsland));
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertTrue(e.isCancelled());
+ verify(user).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlThrewToNonIsland() throws IOException {
+ when(im.getIslandAt(eq(to))).thenReturn(Optional.empty());
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertTrue(e.isCancelled());
+ verify(user).sendMessage("boxed.general.errors.no-teleport-outside");
+ }
+
+ /**
+ * Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#onEnderPearlLand(org.bukkit.event.entity.ProjectileHitEvent)}.
+ * @throws IOException
+ */
+ @Test
+ public void testOnEnderPearlCannotSetProtectionCenter() throws IOException {
+ doThrow(IOException.class).when(island).setProtectionCenter(to);
+ ProjectileHitEvent e = new ProjectileHitEvent(projectile, null, hitBlock, BlockFace.UP);
+ epl.onEnderPearlLand(e);
+ assertFalse(e.isCancelled());
+ verify(addon).logError("Could not move box null");
+ }
+}