From f6bc6c64152188798bce399fee2927ab37bef9b6 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 3 Jun 2019 19:55:44 -0700 Subject: [PATCH] Adds check for players online for offline growth listener. Fixes https://github.com/BentoBoxWorld/BentoBox/issues/729 --- .../worldsettings/OfflineGrowthListener.java | 24 ++- .../OfflineRedstoneListener.java | 3 +- .../OfflineGrowthListenerTest.java | 185 ++++++++++++++++++ .../OfflineRedstoneListenerTest.java | 24 +-- 4 files changed, 215 insertions(+), 21 deletions(-) create mode 100644 src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListenerTest.java diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListener.java index 5a86d5caf..00737f864 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListener.java @@ -1,15 +1,19 @@ package world.bentobox.bentobox.listeners.flags.worldsettings; -import org.bukkit.block.data.Ageable; +import java.util.UUID; + +import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockGrowEvent; + import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.RanksManager; /** * Handles {@link Flags#OFFLINE_GROWTH} flag. - * @author Poslovitch + * @author Poslovitch, tastybento * @since 1.4.0 */ public class OfflineGrowthListener extends FlagListener { @@ -20,12 +24,14 @@ public class OfflineGrowthListener extends FlagListener { // We do not want to run any check if this is not the right world or if it is allowed. return; } - - if (!(e.getBlock() instanceof Ageable)) { - // Do nothing if the block is not "ageable" (and therefore not a crop). - return; - } - - e.setCancelled(true); + // Check if island exists and members are online + getIslands().getProtectedIslandAt(e.getBlock().getLocation()).ifPresent(i -> { + for (UUID uuid : i.getMemberSet(RanksManager.COOP_RANK)) { + if (Bukkit.getPlayer(uuid) != null) { + return; + } + } + e.setCancelled(true); + }); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListener.java index d52b5a543..291993578 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListener.java @@ -9,6 +9,7 @@ import org.bukkit.event.block.BlockRedstoneEvent; import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.RanksManager; /** * Handles {@link Flags#OFFLINE_REDSTONE} flag. @@ -25,7 +26,7 @@ public class OfflineRedstoneListener extends FlagListener { // Check if island exists and members are online getIslands().getProtectedIslandAt(e.getBlock().getLocation()).ifPresent(i -> { - for (UUID uuid : i.getMemberSet()) { + for (UUID uuid : i.getMemberSet(RanksManager.COOP_RANK)) { if (Bukkit.getPlayer(uuid) != null) { return; } diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListenerTest.java new file mode 100644 index 000000000..bdb2ef901 --- /dev/null +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListenerTest.java @@ -0,0 +1,185 @@ +package world.bentobox.bentobox.listeners.flags.worldsettings; + +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 static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockGrowEvent; +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 com.google.common.collect.ImmutableSet.Builder; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.configuration.WorldSettings; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.util.Util; +@RunWith(PowerMockRunner.class) +@PrepareForTest({BentoBox.class, Util.class, Bukkit.class }) +public class OfflineGrowthListenerTest { + + @Mock + private World world; + @Mock + private IslandsManager im; + @Mock + private Location inside; + @Mock + private Block block; + @Mock + private IslandWorldManager iwm; + @Mock + private BlockState blockState; + + @Before + public void setUp() throws Exception { + // Set up plugin + BentoBox plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + + // Owner + UUID uuid = UUID.randomUUID(); + + // Island initialization + Island island = mock(Island.class); + when(island.getOwner()).thenReturn(uuid); + // Add members + Builder set = new ImmutableSet.Builder<>(); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + when(island.getMemberSet(Mockito.anyInt())).thenReturn(set.build()); + + + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(any(), any(UUID.class))).thenReturn(island); + + Optional opIsland = Optional.ofNullable(island); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(opIsland); + + // Blocks + when(block.getWorld()).thenReturn(world); + when(block.getLocation()).thenReturn(inside); + + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(any())).thenReturn(world); + + // World Settings + when(iwm.inWorld(any(World.class))).thenReturn(true); + when(plugin.getIWM()).thenReturn(iwm); + WorldSettings ws = mock(WorldSettings.class); + when(iwm.getWorldSettings(any())).thenReturn(ws); + Map worldFlags = new HashMap<>(); + when(ws.getWorldFlags()).thenReturn(worldFlags); + + PowerMockito.mockStatic(Bukkit.class); + } + + /** + * Test method for {@link OfflineGrowthListener#OnCropGrow(BlockGrowEvent)}. + */ + @Test + public void testOnCropGrowDoNothing() { + // Make an event to give some current to block + BlockGrowEvent e = new BlockGrowEvent(block, blockState); + OfflineGrowthListener orl = new OfflineGrowthListener(); + Flags.OFFLINE_GROWTH.setSetting(world, true); + orl.onCropGrow(e); + // Allow growth + assertFalse(e.isCancelled()); + } + + /** + * Test method for {@link OfflineGrowthListener#OnCropGrow(BlockGrowEvent)}. + */ + @Test + public void testOnCropGrowMembersOnline() { + // Make an event to give some current to block + BlockGrowEvent e = new BlockGrowEvent(block, blockState); + OfflineGrowthListener orl = new OfflineGrowthListener(); + // Offline Growth not allowed + Flags.OFFLINE_GROWTH.setSetting(world, false); + // Members are online + when(Bukkit.getPlayer(any(UUID.class))).thenReturn(mock(Player.class)); + + orl.onCropGrow(e); + // Allow growth + assertFalse(e.isCancelled()); + } + + /** + * Test method for {@link OfflineGrowthListener#OnCropGrow(BlockGrowEvent)}. + */ + @Test + public void testOnCropGrowMembersOffline() { + // Make an event to give some current to block + BlockGrowEvent e = new BlockGrowEvent(block, blockState); + OfflineGrowthListener orl = new OfflineGrowthListener(); + // Offline Growth not allowed + Flags.OFFLINE_GROWTH.setSetting(world, false); + // Members are online + when(Bukkit.getPlayer(any(UUID.class))).thenReturn(null); + + orl.onCropGrow(e); + // Block growth + assertTrue(e.isCancelled()); + } + + /** + * Test method for {@link OfflineGrowthListener#OnCropGrow(BlockGrowEvent)}. + */ + @Test + public void testOnCropGrowNonIsland() { + // Make an event to give some current to block + BlockGrowEvent e = new BlockGrowEvent(block, blockState); + OfflineGrowthListener orl = new OfflineGrowthListener(); + Flags.OFFLINE_GROWTH.setSetting(world, false); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(Optional.empty()); + orl.onCropGrow(e); + // Allow growth + assertFalse(e.isCancelled()); + } + + /** + * Test method for {@link OfflineGrowthListener#OnCropGrow(BlockGrowEvent)}. + */ + @Test + public void testOnCropGrowNonBentoBoxWorldIsland() { + when(iwm.inWorld(any(World.class))).thenReturn(false); + // Make an event to give some current to block + BlockGrowEvent e = new BlockGrowEvent(block, blockState); + OfflineGrowthListener orl = new OfflineGrowthListener(); + Flags.OFFLINE_GROWTH.setSetting(world, false); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(Optional.empty()); + orl.onCropGrow(e); + // Allow growth + assertFalse(e.isCancelled()); + } + +} diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListenerTest.java index 744a029e6..63a9cf152 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineRedstoneListenerTest.java @@ -3,6 +3,8 @@ package world.bentobox.bentobox.listeners.flags.worldsettings; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; import java.util.HashMap; import java.util.Map; @@ -64,17 +66,17 @@ public class OfflineRedstoneListenerTest { set.add(UUID.randomUUID()); set.add(UUID.randomUUID()); set.add(UUID.randomUUID()); - when(island.getMemberSet()).thenReturn(set.build()); + when(island.getMemberSet(Mockito.anyInt())).thenReturn(set.build()); im = mock(IslandsManager.class); when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island); + when(im.getIsland(any(), any(UUID.class))).thenReturn(island); inside = mock(Location.class); Optional opIsland = Optional.ofNullable(island); - when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(opIsland); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(opIsland); // Blocks block = mock(Block.class); @@ -82,14 +84,14 @@ public class OfflineRedstoneListenerTest { when(block.getLocation()).thenReturn(inside); PowerMockito.mockStatic(Util.class); - when(Util.getWorld(Mockito.any())).thenReturn(world); + when(Util.getWorld(any())).thenReturn(world); // World Settings iwm = mock(IslandWorldManager.class); - when(iwm.inWorld(Mockito.any(World.class))).thenReturn(true); + when(iwm.inWorld(any(World.class))).thenReturn(true); when(plugin.getIWM()).thenReturn(iwm); WorldSettings ws = mock(WorldSettings.class); - when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws); + when(iwm.getWorldSettings(any())).thenReturn(ws); Map worldFlags = new HashMap<>(); when(ws.getWorldFlags()).thenReturn(worldFlags); @@ -121,7 +123,7 @@ public class OfflineRedstoneListenerTest { // Offline redstone not allowed Flags.OFFLINE_REDSTONE.setSetting(world, false); // Members are online - when(Bukkit.getPlayer(Mockito.any(UUID.class))).thenReturn(mock(Player.class)); + when(Bukkit.getPlayer(any(UUID.class))).thenReturn(mock(Player.class)); orl.onBlockRedstone(e); // Current remains 10 @@ -139,7 +141,7 @@ public class OfflineRedstoneListenerTest { // Offline redstone not allowed Flags.OFFLINE_REDSTONE.setSetting(world, false); // Members are online - when(Bukkit.getPlayer(Mockito.any(UUID.class))).thenReturn(null); + when(Bukkit.getPlayer(any(UUID.class))).thenReturn(null); orl.onBlockRedstone(e); // Current will be 0 @@ -155,7 +157,7 @@ public class OfflineRedstoneListenerTest { BlockRedstoneEvent e = new BlockRedstoneEvent(block, 0, 10); OfflineRedstoneListener orl = new OfflineRedstoneListener(); Flags.OFFLINE_REDSTONE.setSetting(world, false); - when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(Optional.empty()); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(Optional.empty()); orl.onBlockRedstone(e); // Current remains 10 assertEquals(10, e.getNewCurrent()); @@ -166,12 +168,12 @@ public class OfflineRedstoneListenerTest { */ @Test public void testOnBlockRedstoneNonBentoBoxWorldIsland() { - when(iwm.inWorld(Mockito.any(World.class))).thenReturn(false); + when(iwm.inWorld(any(World.class))).thenReturn(false); // Make an event to give some current to block BlockRedstoneEvent e = new BlockRedstoneEvent(block, 0, 10); OfflineRedstoneListener orl = new OfflineRedstoneListener(); Flags.OFFLINE_REDSTONE.setSetting(world, false); - when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(Optional.empty()); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(Optional.empty()); orl.onBlockRedstone(e); // Current remains 10 assertEquals(10, e.getNewCurrent());