From 421e5a51ea9aa08adb9ac79b0c11fa01b69052c4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 4 Aug 2023 21:35:13 -0700 Subject: [PATCH 01/13] Version 1.3.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 79dc81a..21b9452 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ -LOCAL - 1.3.0 + 1.3.1 bentobox-world https://sonarcloud.io From 1724823bb3a34436d40a47d82b04590192932bdf Mon Sep 17 00:00:00 2001 From: The456 Date: Fri, 11 Aug 2023 00:46:59 +0100 Subject: [PATCH 02/13] fix repeated checkpoint setting + bypass teleport check for back-to-checkpoint teleports + fix replacing checkpoints with the pressure plate (#14) * add currentlyTeleporting field to the run manager * update listeners use currentlyTeleporting to ensure only players teleported by the plugin (for respawning at checkpoint) will be allowed to continue their run refactor uuid use more descriptive names for locations change checkpoint store to use block locations, so comparisons can more accurately be made * increase location mock to make tests pass * stop adding 0.5x ?y 0.5z on teleport to warpspot. also correctly replace exisitng warps on placement of further pressure plates instead, the conversion from block location (on pressure plate place) to player location (on teleport) is done just for that one path * make teleport async --- .../java/world/bentobox/parkour/Parkour.java | 3 +- .../bentobox/parkour/ParkourRunRecord.java | 4 +- .../parkour/commands/WarpCommand.java | 10 +-- .../bentobox/parkour/gui/CoursesTab.java | 29 ++++---- .../listeners/CourseRunnerListener.java | 66 +++++++++++-------- .../parkour/listeners/MakeCourseListener.java | 3 +- .../parkour/commands/QuitCommandTest.java | 3 +- .../parkour/commands/WarpCommandTest.java | 2 - .../listeners/CourseRunnerListenerTest.java | 29 +++----- 9 files changed, 78 insertions(+), 71 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/Parkour.java b/src/main/java/world/bentobox/parkour/Parkour.java index f8ba2b8..4c8e943 100644 --- a/src/main/java/world/bentobox/parkour/Parkour.java +++ b/src/main/java/world/bentobox/parkour/Parkour.java @@ -1,5 +1,6 @@ package world.bentobox.parkour; +import java.util.ArrayList; import java.util.HashMap; import org.bukkit.Material; @@ -91,7 +92,7 @@ public void setup() { adminCommand = new DefaultAdminCommand(this) { }; - parkourRunRecord = new ParkourRunRecord(new HashMap<>(), new HashMap<>()); + parkourRunRecord = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); registerFlag(PARKOUR_CREATIVE); diff --git a/src/main/java/world/bentobox/parkour/ParkourRunRecord.java b/src/main/java/world/bentobox/parkour/ParkourRunRecord.java index 82240f9..797ddac 100644 --- a/src/main/java/world/bentobox/parkour/ParkourRunRecord.java +++ b/src/main/java/world/bentobox/parkour/ParkourRunRecord.java @@ -1,11 +1,12 @@ package world.bentobox.parkour; +import java.util.List; import java.util.Map; import java.util.UUID; import org.bukkit.Location; -public record ParkourRunRecord(Map checkpoints, Map timers) { +public record ParkourRunRecord(Map checkpoints, Map timers, List currentlyTeleporting) { /** * Clears any current times or checkpoints * @param uuid UUID of runner @@ -13,6 +14,7 @@ public record ParkourRunRecord(Map checkpoints, Map public void clear(UUID uuid) { checkpoints.remove(uuid); timers.remove(uuid); + currentlyTeleporting.remove(uuid); } } diff --git a/src/main/java/world/bentobox/parkour/commands/WarpCommand.java b/src/main/java/world/bentobox/parkour/commands/WarpCommand.java index f318815..ff03b9c 100644 --- a/src/main/java/world/bentobox/parkour/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/parkour/commands/WarpCommand.java @@ -19,8 +19,8 @@ /** * Warps to a - * @author tastybento * + * @author tastybento */ public class WarpCommand extends CompositeCommand { @@ -48,7 +48,7 @@ public boolean canExecute(User user, String label, List args) { } if (args.isEmpty()) { Optional island = getIslands().getIslandAt(user.getLocation()); - if (island.isEmpty() || !((Parkour)getAddon()).inWorld(user.getWorld())) { + if (island.isEmpty() || !((Parkour) getAddon()).inWorld(user.getWorld())) { user.sendMessage("parkour.errors.not-on-island"); this.showHelp(this, user); return false; @@ -81,18 +81,18 @@ public boolean execute(User user, String label, List args) { // Teleport user user.getPlayer().playSound(user.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 1F, 1F); user.getPlayer().playSound(warpSpot, Sound.ENTITY_BAT_TAKEOFF, 1F, 1F); - Util.teleportAsync(user.getPlayer(), warpSpot.clone().add(new Vector(0.5, 0.5, 0.5)), TeleportCause.COMMAND); + Util.teleportAsync(user.getPlayer(), warpSpot, TeleportCause.COMMAND); return true; } @Override public Optional> tabComplete(User user, String alias, List args) { - ArrayList options = new ArrayList<>(((Parkour)getAddon()).getParkourManager().getWarps().keySet()); + ArrayList options = new ArrayList<>(((Parkour) getAddon()).getParkourManager().getWarps().keySet()); if (options.size() < 10) { return Optional.of(options); } // List is too long; require at least the first letter - String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; + String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : ""; if (args.isEmpty()) { return Optional.empty(); } diff --git a/src/main/java/world/bentobox/parkour/gui/CoursesTab.java b/src/main/java/world/bentobox/parkour/gui/CoursesTab.java index 63b5d2e..38c46e6 100644 --- a/src/main/java/world/bentobox/parkour/gui/CoursesTab.java +++ b/src/main/java/world/bentobox/parkour/gui/CoursesTab.java @@ -10,7 +10,6 @@ import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; -import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -25,9 +24,9 @@ /** * Implements a {@link Tab} that shows course rankings + * * @author tastybento * @since 1.0.0 - * */ public class CoursesTab implements Tab { @@ -36,8 +35,9 @@ public class CoursesTab implements Tab { /** * Show a tab of settings + * * @param addon - addon - * @param user - user who is viewing the tab + * @param user - user who is viewing the tab */ public CoursesTab(Parkour addon, User user) { super(); @@ -47,6 +47,7 @@ public CoursesTab(Parkour addon, User user) { /** * Get the icon for this tab + * * @return panel item */ @Override @@ -69,6 +70,7 @@ public String getName() { /** * Get all the flags as panel items + * * @return list of all the panel items for this flag type */ @Override @@ -78,20 +80,21 @@ public String getName() { List heads = new ArrayList<>(); // Sort the courses by runs addon.getParkourManager().getParkourData().stream() - .sorted() - .filter(hs -> Objects.nonNull(hs.getWarpSpot())) - .forEach(hs -> { - UUID owner = addon.getIslands().getIslandById(hs.getUniqueId()).map(Island::getOwner).orElse(null); - if (owner != null) { - heads.add(getHead(hs, owner)); - } - }); + .sorted() + .filter(hs -> Objects.nonNull(hs.getWarpSpot())) + .forEach(hs -> { + UUID owner = addon.getIslands().getIslandById(hs.getUniqueId()).map(Island::getOwner).orElse(null); + if (owner != null) { + heads.add(getHead(hs, owner)); + } + }); return heads; } /** * Get the head panel item - * @param pd - parkour data + * + * @param pd - parkour data * @param playerUUID - the UUID of the owner * @return PanelItem */ @@ -115,7 +118,7 @@ private PanelItem getHead(ParkourData pd, UUID playerUUID) { .clickHandler((panel, user, clickType, slot) -> { user.sendMessage("parkour.warp.warping"); // Teleport user - Util.teleportAsync(user.getPlayer(), pd.getWarpSpot().clone().add(new Vector(0.5, 1, 0.5)), TeleportCause.COMMAND); + Util.teleportAsync(user.getPlayer(), pd.getWarpSpot(), TeleportCause.COMMAND); return true; }) .description(description); diff --git a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java index 645162d..8f3b3ad 100644 --- a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java +++ b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.UUID; import org.bukkit.EntityEffect; import org.bukkit.GameMode; @@ -28,6 +29,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.util.Util; import world.bentobox.parkour.Parkour; import world.bentobox.parkour.ParkourRunRecord; @@ -113,27 +115,31 @@ public void onVisitorFall(EntityDamageEvent e) { player.playEffect(EntityEffect.ENTITY_POOF); player.setVelocity(new Vector(0, 0, 0)); player.setFallDistance(0); - player.teleport(parkourRunManager.checkpoints().get(player.getUniqueId())); - + Location checkpointLocation = parkourRunManager.checkpoints().get(player.getUniqueId()); + checkpointLocation = checkpointLocation.clone().add(0.5, 0, 0.5); + parkourRunManager.currentlyTeleporting().add(player.getUniqueId()); + Util.teleportAsync(player, checkpointLocation, PlayerTeleportEvent.TeleportCause.PLUGIN) + .thenAccept(b -> parkourRunManager.currentlyTeleporting().remove(player.getUniqueId())); } @EventHandler public void onTeleport(PlayerTeleportEvent e) { boolean shouldStopRun = switch (e.getCause()) { - case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED -> false; - case COMMAND, PLUGIN, NETHER_PORTAL, END_PORTAL, SPECTATE, END_GATEWAY, UNKNOWN -> true; + case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED -> false; + case COMMAND, PLUGIN, NETHER_PORTAL, END_PORTAL, SPECTATE, END_GATEWAY, UNKNOWN -> true; }; - if (shouldStopRun && parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) { - User user = User.getInstance(e.getPlayer().getUniqueId()); - if (parkourRunManager.checkpoints().containsKey(e.getPlayer().getUniqueId()) && user.isOnline()) { + UUID playerUUID = e.getPlayer().getUniqueId(); + if (!parkourRunManager.currentlyTeleporting().contains(playerUUID) && shouldStopRun && parkourRunManager.timers().containsKey(playerUUID)) { + User user = User.getInstance(playerUUID); + if (parkourRunManager.checkpoints().containsKey(playerUUID) && user.isOnline()) { user.notify("parkour.session-ended"); } - parkourRunManager.clear(e.getPlayer().getUniqueId()); + parkourRunManager.clear(playerUUID); } // Check world - only apply flag actions to Parkour world and only if player is not actively running the course if (e.getTo() == null // To can sometimes be null... || !addon.inWorld(e.getTo()) - || parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) { + || parkourRunManager.timers().containsKey(playerUUID)) { return; } // Handle flag action for players who are not running @@ -205,14 +211,14 @@ public void onStartEndSet(PlayerInteractEvent e) { return; } - Location l = e.getClickedBlock().getLocation(); + Location blockLocation = e.getClickedBlock().getLocation(); User user = User.getInstance(e.getPlayer()); - addon.getIslands().getProtectedIslandAt(l).ifPresent(island -> { + addon.getIslands().getProtectedIslandAt(blockLocation).ifPresent(island -> { Optional start = addon.getParkourManager().getStart(island); Optional end = addon.getParkourManager().getEnd(island); // Check if start and end is set - if (start.filter(startLoc -> isLocEquals(l, startLoc)).isPresent()) { + if (start.filter(startLoc -> isLocEquals(blockLocation, startLoc)).isPresent()) { // End is not set if (end.isEmpty()) { user.sendMessage("parkour.set-the-end"); @@ -220,29 +226,29 @@ public void onStartEndSet(PlayerInteractEvent e) { } // Start the race! if (!parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) { - parkourStart(user, l); + parkourStart(user, blockLocation); } - } else if (end.filter(endLoc -> isLocEquals(l, endLoc)).isPresent() + } else if (end.filter(endLoc -> isLocEquals(blockLocation, endLoc)).isPresent() && parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) { // End the race! - parkourEnd(user, island, l); + parkourEnd(user, island, blockLocation); } }); } - void parkourStart(User user, Location l) { + void parkourStart(User user, Location blockLocation) { user.sendMessage("parkour.start"); - user.getPlayer().playSound(l, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); + user.getPlayer().playSound(blockLocation, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); parkourRunManager.timers().put(user.getUniqueId(), System.currentTimeMillis()); - parkourRunManager.checkpoints().put(user.getUniqueId(), user.getLocation()); + parkourRunManager.checkpoints().put(user.getUniqueId(), blockLocation); user.setGameMode(GameMode.SURVIVAL); } - void parkourEnd(User user, Island island, Location l) { + void parkourEnd(User user, Island island, Location blockLocation) { long duration = (System.currentTimeMillis() - Objects.requireNonNull(parkourRunManager.timers().get(user.getUniqueId()))); user.notify("parkour.end"); - user.getPlayer().playSound(l, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); + user.getPlayer().playSound(blockLocation, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); user.notify("parkour.you-took", TextVariables.NUMBER, getDuration(user, duration)); parkourRunManager.clear(user.getUniqueId()); @@ -279,14 +285,18 @@ public void onCheckpoint(PlayerInteractEvent e) { || !parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) { return; } - Location l = e.getClickedBlock().getLocation(); - User user = User.getInstance(e.getPlayer()); - Vector checkPoint = parkourRunManager.checkpoints().get(e.getPlayer().getUniqueId()).toVector(); - - if (addon.getIslands().getProtectedIslandAt(l).isPresent() && !l.toVector().equals(checkPoint)) { - user.notify("parkour.checkpoint"); - e.getPlayer().playSound(l, Sound.BLOCK_BELL_USE, 1F, 1F); - parkourRunManager.checkpoints().put(user.getUniqueId(), e.getPlayer().getLocation()); + Location newCheckpointBlockLocation = e.getClickedBlock().getLocation(); + if (addon.getIslands().getProtectedIslandAt(newCheckpointBlockLocation).isPresent()) { + // pressure plate should be a checkpoint + Location currentCheckpointBlockLocation = parkourRunManager.checkpoints().get(e.getPlayer().getUniqueId()); + if (!isLocEquals(newCheckpointBlockLocation, currentCheckpointBlockLocation)) { + // new location is different + User user = User.getInstance(e.getPlayer()); + user.sendMessage("parkour.checkpoint"); + e.getPlayer().playSound(newCheckpointBlockLocation, Sound.BLOCK_BELL_USE, 1F, 1F); + parkourRunManager.checkpoints().put(user.getUniqueId(), newCheckpointBlockLocation); + } } } + } diff --git a/src/main/java/world/bentobox/parkour/listeners/MakeCourseListener.java b/src/main/java/world/bentobox/parkour/listeners/MakeCourseListener.java index fbe2c99..c86cba9 100644 --- a/src/main/java/world/bentobox/parkour/listeners/MakeCourseListener.java +++ b/src/main/java/world/bentobox/parkour/listeners/MakeCourseListener.java @@ -50,10 +50,11 @@ public void onWarpSet(BlockPlaceEvent e) { Optional warpSpot = addon.getParkourManager().getWarpSpot(island); if (warpSpot.isEmpty()) { user.notify("parkour.warp.set"); - addon.getParkourManager().setWarpSpot(island, l); } else { user.notify("parkour.warp.replaced"); } + // shift from block to player location + addon.getParkourManager().setWarpSpot(island, l.add(0.5,0,0.5)); } } diff --git a/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java b/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java index 2c953dc..b3141ae 100644 --- a/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java @@ -11,6 +11,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Optional; @@ -109,7 +110,7 @@ public void setUp() throws Exception { when(ac.getWorld()).thenReturn(world); when(ac.getAddon()).thenReturn(addon); - prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>()); + prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); prm.timers().put(uuid, 20L); when(addon.getParkourRunRecord()).thenReturn(prm); diff --git a/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java b/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java index a70afc4..5a63f97 100644 --- a/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java @@ -142,7 +142,6 @@ public void setUp() throws Exception { // Location when(location.clone()).thenReturn(location); - when(location.add(any(Vector.class))).thenReturn(location); // Settings Settings settings = new Settings(); @@ -267,7 +266,6 @@ public void testExecuteUserStringListOfString() { verify(user).sendMessage("parkour.warp.warping"); // Teleport user verify(p, times(2)).playSound(location, Sound.ENTITY_BAT_TAKEOFF, 1F, 1F); - verify(location).add(any(Vector.class)); PowerMockito.verifyStatic(Util.class); Util.teleportAsync(p, location, TeleportCause.COMMAND); diff --git a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java index c486435..2685c85 100644 --- a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java +++ b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java @@ -1,19 +1,5 @@ package world.bentobox.parkour.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.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.contains; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -72,12 +58,15 @@ import world.bentobox.parkour.ParkourRunRecord; import world.bentobox.parkour.Settings; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + /** * @author tastybento - * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) +@PrepareForTest({Bukkit.class, BentoBox.class, User.class}) public class CourseRunnerListenerTest { @Mock @@ -190,10 +179,12 @@ public void setUp() throws Exception { // Location when(location.getWorld()).thenReturn(world); - when(location.toVector()).thenReturn(new Vector(0,0,0)); + when(location.toVector()).thenReturn(new Vector(0, 0, 0)); + when(location.clone()).thenReturn(location); + when(location.add(0.5, 0, 0.5)).thenReturn(location); // Run Manager and ParkourManager - prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>()); + prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); when(addon.getParkourRunRecord()).thenReturn(prm); when(addon.inWorld(location)).thenReturn(true); when(addon.inWorld(world)).thenReturn(true); @@ -523,7 +514,7 @@ public void testOnCheckpointNotPhysical() { @Test public void testOnCheckpointInitialChecks() { Location l = mock(Location.class); - when(l.toVector()).thenReturn(new Vector(100,0,20)); // Different to location + when(l.toVector()).thenReturn(new Vector(100, 0, 20)); // Different to location prm.checkpoints().put(uuid, l); when(block.getType()).thenReturn(Material.STONE); From e89df1d7ea563246822eb47f0eb45b640d66c55c Mon Sep 17 00:00:00 2001 From: The456 Date: Fri, 11 Aug 2023 04:27:10 +0100 Subject: [PATCH 03/13] add changeworld listener (#16) * add changeworld listener * simplify logic, add notification for run exit on death remove portals from canceling run, ensure gamemode is only changed in certain teleport events make it more explicit that IslandEnterEvent checks source world before changing gamemode non-parkour -> parkour: PlayerChangedWorldEvent set gm non-parkour -> non-parkour: none parkour -> parkour: same island: PlayerTeleportEvent set gm if not running between islands: IslandEnterEvent set gm parkour -> non-parkour: none --------- Co-authored-by: tastybento --- .../listeners/CourseRunnerListener.java | 53 ++++++++++++++++--- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java index 8f3b3ad..e7e126b 100644 --- a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java +++ b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java @@ -17,6 +17,7 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -73,10 +74,40 @@ public void onVisitorArrive(IslandEnterEvent e) { } else if (!parkourRunManager.timers().containsKey(e.getPlayerUUID())) { user.notify("parkour.to-start"); } - if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { - user.setGameMode(GameMode.CREATIVE); - } else { - user.setGameMode(GameMode.SURVIVAL); + + // the location that the player teleports from + Location fromLocation = user.getLocation(); + + if (addon.inWorld(fromLocation)) { + // if the player is staying in a parkour managed world they can have their gamemode changed + // this occurs when their island changes, so wont risk affecting players that are currently running + // since exit would trigger first + // cross (unmanaged) world teleportation is handled in onPlayerChangeWorld + + if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { + user.setGameMode(GameMode.CREATIVE); + } else { + user.setGameMode(GameMode.SURVIVAL); + } + } + } + + @EventHandler + public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { + User user = User.getInstance(event.getPlayer()); + Location currentLocation = user.getLocation(); + boolean fromParkour = addon.inWorld(event.getFrom()); + boolean toParkour = addon.inWorld(currentLocation); + + if (toParkour && !fromParkour) { + // switching from non-parkour world to parkour world + addon.getIslandsManager().getIslandAt(currentLocation).ifPresent(island -> { + if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { + user.setGameMode(GameMode.CREATIVE); + } else { + user.setGameMode(GameMode.SURVIVAL); + } + }); } } @@ -93,6 +124,10 @@ public void onVisitorLeave(IslandExitEvent e) { @EventHandler(priority = EventPriority.NORMAL) public void onPlayerDeath(PlayerDeathEvent e) { // Game over + User user = User.getInstance(e.getEntity().getUniqueId()); + if (parkourRunManager.checkpoints().containsKey(e.getEntity().getUniqueId()) && user.isOnline()) { + user.notify("parkour.session-ended"); + } parkourRunManager.clear(e.getEntity().getUniqueId()); } @@ -125,8 +160,8 @@ public void onVisitorFall(EntityDamageEvent e) { @EventHandler public void onTeleport(PlayerTeleportEvent e) { boolean shouldStopRun = switch (e.getCause()) { - case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED -> false; - case COMMAND, PLUGIN, NETHER_PORTAL, END_PORTAL, SPECTATE, END_GATEWAY, UNKNOWN -> true; + case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED, NETHER_PORTAL, END_PORTAL -> false; + case COMMAND, PLUGIN, SPECTATE, END_GATEWAY, UNKNOWN -> true; }; UUID playerUUID = e.getPlayer().getUniqueId(); if (!parkourRunManager.currentlyTeleporting().contains(playerUUID) && shouldStopRun && parkourRunManager.timers().containsKey(playerUUID)) { @@ -146,7 +181,11 @@ public void onTeleport(PlayerTeleportEvent e) { Optional fromIsland = addon.getIslands().getIslandAt(e.getFrom()); Optional toIsland = addon.getIslands().getIslandAt(e.getTo()); - if (fromIsland.isPresent() && toIsland.isPresent() && fromIsland.get().equals(toIsland.get())) { + boolean shouldAlterGamemode = switch (e.getCause()) { + case COMMAND, PLUGIN, UNKNOWN -> true; + default -> false; + }; + if (shouldAlterGamemode && fromIsland.isPresent() && toIsland.isPresent() && fromIsland.get().equals(toIsland.get())) { // same island teleport Island island = fromIsland.get(); User user = User.getInstance(e.getPlayer()); From 936695d7fa365f083aff89ca69071a6720485775 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 10 Aug 2023 20:42:02 -0700 Subject: [PATCH 04/13] Fix tests, add a test to CourseRunnerListener --- .../listeners/CourseRunnerListener.java | 6 +-- .../listeners/CourseRunnerListenerTest.java | 40 +++++++++++++++---- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java index e7e126b..658a9cd 100644 --- a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java +++ b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java @@ -154,7 +154,7 @@ public void onVisitorFall(EntityDamageEvent e) { checkpointLocation = checkpointLocation.clone().add(0.5, 0, 0.5); parkourRunManager.currentlyTeleporting().add(player.getUniqueId()); Util.teleportAsync(player, checkpointLocation, PlayerTeleportEvent.TeleportCause.PLUGIN) - .thenAccept(b -> parkourRunManager.currentlyTeleporting().remove(player.getUniqueId())); + .thenAccept(b -> parkourRunManager.currentlyTeleporting().remove(player.getUniqueId())); } @EventHandler @@ -182,8 +182,8 @@ public void onTeleport(PlayerTeleportEvent e) { Optional toIsland = addon.getIslands().getIslandAt(e.getTo()); boolean shouldAlterGamemode = switch (e.getCause()) { - case COMMAND, PLUGIN, UNKNOWN -> true; - default -> false; + case COMMAND, PLUGIN, UNKNOWN -> true; + default -> false; }; if (shouldAlterGamemode && fromIsland.isPresent() && toIsland.isPresent() && fromIsland.get().equals(toIsland.get())) { // same island teleport diff --git a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java index 2685c85..f6d8e89 100644 --- a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java +++ b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java @@ -36,6 +36,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.stubbing.Answer; +import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; @@ -53,6 +54,7 @@ import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.Util; import world.bentobox.parkour.Parkour; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.ParkourRunRecord; @@ -66,7 +68,7 @@ * @author tastybento */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class}) +@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Util.class}) public class CourseRunnerListenerTest { @Mock @@ -199,6 +201,7 @@ public void setUp() throws Exception { // Block when(block.getType()).thenReturn(Material.LIGHT_WEIGHTED_PRESSURE_PLATE); when(block.getLocation()).thenReturn(location); + // DUT crl = new CourseRunnerListener(addon); } @@ -311,6 +314,7 @@ public void testOnPlayerQuit() { */ @Test public void testOnVisitorFall() { + PowerMockito.mockStatic(Util.class, RETURNS_MOCKS); prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago prm.checkpoints().put(uuid, location); EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); @@ -318,7 +322,8 @@ public void testOnVisitorFall() { verify(player).playEffect(EntityEffect.ENTITY_POOF); verify(player).setVelocity(new Vector(0, 0, 0)); verify(player).setFallDistance(0); - verify(player).teleport(location); + PowerMockito.verifyStatic(Util.class); + Util.teleportAsync(player, location, PlayerTeleportEvent.TeleportCause.PLUGIN); } /** @@ -560,9 +565,10 @@ public void testOnTeleport() { // Fire event crl.onTeleport(e); } - // Should fire 7 times: COMMAND, PLUGIN, NETHER_PORTAL, END_PORTAL, SPECTATE, END_GATEWAY, UNKNOWN - verify(notifier, times(7)).notify(any(), eq("parkour.session-ended")); - verify(player, times(7)).setGameMode(GameMode.CREATIVE); + // Should fire 5 times: COMMAND, PLUGIN, SPECTATE, END_GATEWAY, UNKNOWN + verify(notifier, times(5)).notify(any(), eq("parkour.session-ended")); + // Should happen just 3 times: COMMAND, PLUGIN, UNKNOWN + verify(player, times(3)).setGameMode(GameMode.CREATIVE); verify(player, never()).setGameMode(GameMode.SURVIVAL); } @@ -587,7 +593,7 @@ public void testOnTeleportToNoFlagActionNotInParkourWorld() { // Make the event Location l = mock(Location.class); when(l.getWorld()).thenReturn(mock(World.class)); - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.CHORUS_FRUIT); + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.PLUGIN); // Fire event crl.onTeleport(e); verify(player, never()).setGameMode(GameMode.CREATIVE); @@ -604,7 +610,7 @@ public void testOnTeleportToNoFlagActionDifferentIsland() { when(l.getWorld()).thenReturn(world); Island i = mock(Island.class); when(im.getIslandAt(l)).thenReturn(Optional.of(i)); - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.CHORUS_FRUIT); + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.PLUGIN); // Fire event crl.onTeleport(e); verify(player, never()).setGameMode(GameMode.CREATIVE); @@ -618,8 +624,9 @@ public void testOnTeleportToNoFlagActionDifferentIsland() { public void testOnTeleportToFlagActionVisitors() { when(island.getFlag(any())).thenReturn(RanksManager.MEMBER_RANK); when(island.getRank(any(User.class))).thenReturn(RanksManager.VISITOR_RANK); + // Make the event - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, location, TeleportCause.CHORUS_FRUIT); + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, location, TeleportCause.PLUGIN); // Fire event crl.onTeleport(e); verify(player, never()).setGameMode(GameMode.CREATIVE); @@ -627,5 +634,22 @@ public void testOnTeleportToFlagActionVisitors() { verify(player).setGameMode(GameMode.SURVIVAL); } + /** + * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. + */ + @Test + public void testOnTeleportToFlagActionVisitorsChorusFruit() { + when(island.getFlag(any())).thenReturn(RanksManager.MEMBER_RANK); + when(island.getRank(any(User.class))).thenReturn(RanksManager.VISITOR_RANK); + + // Make the event + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, location, TeleportCause.CHORUS_FRUIT); + // Fire event + crl.onTeleport(e); + // Never alter the game mode + verify(player, never()).setGameMode(GameMode.CREATIVE); + verify(player, never()).setGameMode(GameMode.SURVIVAL); + } + } From 812bd1d6f033a0b132f51f6fbd0dc6f1557e3a6b Mon Sep 17 00:00:00 2001 From: The456 Date: Sun, 20 Aug 2023 01:37:22 +0100 Subject: [PATCH 05/13] fix mv compat (#17) * refactor, add join listener + delay changing gamemode by 2 ticks when changing work and joining. * add run-tests intellij configuration * Delete run-tests.run.xml --------- Co-authored-by: tastybento --- .../listeners/CourseRunnerListener.java | 74 +++++++++++++------ 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java index 658a9cd..22d6b80 100644 --- a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java +++ b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java @@ -5,11 +5,13 @@ import java.util.Optional; import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.EntityEffect; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -20,6 +22,7 @@ import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.util.Vector; @@ -84,33 +87,54 @@ public void onVisitorArrive(IslandEnterEvent e) { // since exit would trigger first // cross (unmanaged) world teleportation is handled in onPlayerChangeWorld - if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { - user.setGameMode(GameMode.CREATIVE); - } else { - user.setGameMode(GameMode.SURVIVAL); - } + updateGamemode(island, user); } } @EventHandler public void onPlayerChangeWorld(PlayerChangedWorldEvent event) { User user = User.getInstance(event.getPlayer()); - Location currentLocation = user.getLocation(); boolean fromParkour = addon.inWorld(event.getFrom()); - boolean toParkour = addon.inWorld(currentLocation); + World newWorld = user.getWorld(); + boolean toParkour = addon.inWorld(newWorld); if (toParkour && !fromParkour) { // switching from non-parkour world to parkour world - addon.getIslandsManager().getIslandAt(currentLocation).ifPresent(island -> { - if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { - user.setGameMode(GameMode.CREATIVE); - } else { - user.setGameMode(GameMode.SURVIVAL); + Bukkit.getServer().getScheduler().runTaskLater(addon.getPlugin(), () -> { + Location currentLocation = user.getLocation(); + + // world has changed in the 2 ticks delay, dont set gamemode + if (currentLocation.getWorld() != newWorld) { + return; } - }); + + addon.getIslandsManager().getIslandAt(currentLocation).ifPresent(island -> updateGamemode(island, user)); + }, 2); // 2 ticks since multiverse overrides gamemode after 1 tick } } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + User user = User.getInstance(event.getPlayer()); + World world = user.getWorld(); + if (!addon.inWorld(world)) { + return; + } + + Bukkit.getServer().getScheduler().runTaskLater(addon.getPlugin(), () -> { + Location currentLocation = user.getLocation(); + + // world has changed in the 2 ticks delay, dont set gamemode + if (currentLocation.getWorld() != world) { + return; + } + + addon.getIslandsManager().getIslandAt(currentLocation).ifPresent(island -> updateGamemode(island, user)); + }, 2); + } + + @EventHandler(priority = EventPriority.NORMAL) public void onVisitorLeave(IslandExitEvent e) { // If the user leaves any island, end and clear the session. @@ -154,14 +178,14 @@ public void onVisitorFall(EntityDamageEvent e) { checkpointLocation = checkpointLocation.clone().add(0.5, 0, 0.5); parkourRunManager.currentlyTeleporting().add(player.getUniqueId()); Util.teleportAsync(player, checkpointLocation, PlayerTeleportEvent.TeleportCause.PLUGIN) - .thenAccept(b -> parkourRunManager.currentlyTeleporting().remove(player.getUniqueId())); + .thenAccept(b -> parkourRunManager.currentlyTeleporting().remove(player.getUniqueId())); } @EventHandler public void onTeleport(PlayerTeleportEvent e) { boolean shouldStopRun = switch (e.getCause()) { - case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED, NETHER_PORTAL, END_PORTAL -> false; - case COMMAND, PLUGIN, SPECTATE, END_GATEWAY, UNKNOWN -> true; + case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED, NETHER_PORTAL, END_PORTAL -> false; + case COMMAND, PLUGIN, SPECTATE, END_GATEWAY, UNKNOWN -> true; }; UUID playerUUID = e.getPlayer().getUniqueId(); if (!parkourRunManager.currentlyTeleporting().contains(playerUUID) && shouldStopRun && parkourRunManager.timers().containsKey(playerUUID)) { @@ -182,20 +206,22 @@ public void onTeleport(PlayerTeleportEvent e) { Optional toIsland = addon.getIslands().getIslandAt(e.getTo()); boolean shouldAlterGamemode = switch (e.getCause()) { - case COMMAND, PLUGIN, UNKNOWN -> true; - default -> false; + case COMMAND, PLUGIN, UNKNOWN -> true; + default -> false; }; if (shouldAlterGamemode && fromIsland.isPresent() && toIsland.isPresent() && fromIsland.get().equals(toIsland.get())) { // same island teleport - Island island = fromIsland.get(); User user = User.getInstance(e.getPlayer()); - if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { - user.setGameMode(GameMode.CREATIVE); - } else { - user.setGameMode(GameMode.SURVIVAL); - } + updateGamemode(fromIsland.get(), user); } + } + private void updateGamemode(Island island, User user) { + if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { + user.setGameMode(GameMode.CREATIVE); + } else { + user.setGameMode(GameMode.SURVIVAL); + } } From ec63231f7dc7a933ac8754cc587f4cda979a71ee Mon Sep 17 00:00:00 2001 From: The456 Date: Wed, 6 Sep 2023 03:33:18 +0100 Subject: [PATCH 06/13] add permission check for changing gamemode (#18) still excludes actually playing the course not given by default to avoid op perms including it --- .../listeners/CourseRunnerListener.java | 4 ++++ src/main/resources/addon.yml | 21 +++---------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java index 22d6b80..1503d3c 100644 --- a/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java +++ b/src/main/java/world/bentobox/parkour/listeners/CourseRunnerListener.java @@ -217,6 +217,10 @@ public void onTeleport(PlayerTeleportEvent e) { } private void updateGamemode(Island island, User user) { + if (user.hasPermission("parkour.mod.bypassgamemodechange")) { + return; + } + if (island.getFlag(addon.PARKOUR_CREATIVE) <= island.getRank(user)) { user.setGameMode(GameMode.CREATIVE); } else { diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index e287f7c..225b32e 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -40,6 +40,9 @@ permissions: parkour.mod.bypasslock: description: Bypasses an course lock default: op + parkour.mod.bypassgamemodechange: + description: Bypasses the changing of your gamemode when entering your island. + default: false parkour.mod.bypassban: description: Bypasses course ban default: op @@ -89,18 +92,6 @@ permissions: parkour.mod.team.setowner: description: Allow use of '/pkadmin team setowner' command - transfers course ownership to the player default: op - parkour.mod.team.add: - description: Allow use of '/pkadmin add' command - add player to owner's team - default: op - parkour.mod.team.kick: - description: Allow use of '/pkadmin kick' command - kick a player from a team - default: op - parkour.mod.team.disband: - description: Allow use of '/pkadmin disband' command - disband owner's team - default: op - parkour.mod.team.setowner: - description: Allow use of '/pkadmin setowner' command - transfers course ownership to the player - default: op parkour.admin.blueprint: description: Allow use of '/pkadmin blueprint' command - manipulate blueprints default: op @@ -170,9 +161,6 @@ permissions: parkour.admin.resets.add: description: Allow use of '/pkadmin resets add' command - adds this player's course reset count default: op - parkour.admin.resets.remove: - description: Allow use of '/pkadmin resets remove' command - reduces the player's course reset count - default: op parkour.admin.delete: description: Allow use of '/pkadmin delete' command - deletes a player and regenerates their course default: op @@ -296,9 +284,6 @@ permissions: parkour.island.team.coop: description: Allow use of '/parkour team coop' command - make a player coop rank on your course default: true - parkour.island.team.coop: - description: Allow use of '/parkour team uncoop' command - remove a coop rank from player - default: true parkour.island.team.trust: description: Allow use of '/parkour team trust', '/parkour team untrust' command - remove trusted player rank from player default: true From ad552370c98b34da67ab5166380b9635dbd0c37e Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 12 Nov 2023 14:30:47 -0800 Subject: [PATCH 07/13] BentoBox 2.0.0 API and tests --- pom.xml | 2 +- .../bentobox/parkour/AbstractParkourTest.java | 178 +++ .../world/bentobox/parkour/ParkourTest.java | 354 ++---- .../parkour/commands/QuitCommandTest.java | 289 +++-- .../commands/RemoveWarpCommandTest.java | 277 +++-- .../parkour/commands/SetWarpCommandTest.java | 284 +++-- .../parkour/commands/TopCommandTest.java | 258 ++--- .../parkour/commands/WarpCommandTest.java | 435 ++++--- .../listeners/CourseRunnerListenerTest.java | 1023 +++++++++-------- 9 files changed, 1535 insertions(+), 1565 deletions(-) create mode 100644 src/test/java/world/bentobox/parkour/AbstractParkourTest.java diff --git a/pom.xml b/pom.xml index 21b9452..c858c0e 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ 1.20.1-R0.1-SNAPSHOT - 1.24.1-SNAPSHOT + 2.0.0-SNAPSHOT ${build.version}-SNAPSHOT diff --git a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java new file mode 100644 index 0000000..06ef296 --- /dev/null +++ b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java @@ -0,0 +1,178 @@ +package world.bentobox.parkour; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.beans.IntrospectionException; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Comparator; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; +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 world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.Settings; +import world.bentobox.bentobox.api.configuration.Config; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.database.DatabaseSetup; +import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.AddonsManager; +import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.bentobox.managers.FlagsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.managers.PlaceholdersManager; +import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.Util; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Config.class, DatabaseSetup.class, Util.class }) +public abstract class AbstractParkourTest { + + @Mock + protected User user; + @Mock + protected IslandsManager im; + @Mock + protected Island island; + @Mock + protected BentoBox plugin; + @Mock + protected FlagsManager fm; + @Mock + protected Settings settings; + @Mock + protected PlaceholdersManager phm; + @Mock + protected IslandWorldManager iwm; + @Mock + protected Parkour addon; + protected static AbstractDatabaseHandler h; + + @SuppressWarnings("unchecked") + @BeforeClass + public static void beforeClass() throws IllegalAccessException, InvocationTargetException, IntrospectionException { + // This has to be done beforeClass otherwise the tests will interfere with each + // other + h = mock(AbstractDatabaseHandler.class); + // Database + PowerMockito.mockStatic(DatabaseSetup.class); + DatabaseSetup dbSetup = mock(DatabaseSetup.class); + when(DatabaseSetup.getDatabase()).thenReturn(dbSetup); + when(dbSetup.getHandler(any())).thenReturn(h); + when(h.saveObject(any())).thenReturn(CompletableFuture.completedFuture(true)); + } + + @After + public void tearDown() throws IOException { + User.clearUsers(); + Mockito.framework().clearInlineMocks(); + deleteAll(new File("database")); + deleteAll(new File("database_backup")); + deleteAll(new File("addon.jar")); + deleteAll(new File("config.yml")); + deleteAll(new File("addons")); + } + + protected void deleteAll(File file) throws IOException { + if (file.exists()) { + Files.walk(file.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } + + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // Set up plugin + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger()); + + // The database type has to be created one line before the thenReturn() to work! + DatabaseType value = DatabaseType.JSON; + when(plugin.getSettings()).thenReturn(settings); + when(settings.getDatabaseType()).thenReturn(value); + when(plugin.getPlaceholdersManager()).thenReturn(phm); + // Placeholders + when(phm.replacePlaceholders(any(), anyString())).thenAnswer(a -> (String) a.getArgument(1, String.class)); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + UUID uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + User.setPlugin(plugin); + + // Island World Manager + when(plugin.getIWM()).thenReturn(iwm); + + // Player has island to begin with + island = mock(Island.class); + when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island); + when(plugin.getIslands()).thenReturn(im); + + // Locales + // Return the reference (USE THIS IN THE FUTURE) + when(user.getTranslation(Mockito.anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + + // Server + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); + Server server = mock(Server.class); + when(Bukkit.getServer()).thenReturn(server); + when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); + when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class)); + + // Addons manager + AddonsManager am = mock(AddonsManager.class); + when(plugin.getAddonsManager()).thenReturn(am); + + // Flags manager + when(plugin.getFlagsManager()).thenReturn(fm); + when(fm.getFlags()).thenReturn(Collections.emptyList()); + + // RanksManager + RanksManager rm = new RanksManager(); + when(plugin.getRanksManager()).thenReturn(rm); + + } + +} diff --git a/src/test/java/world/bentobox/parkour/ParkourTest.java b/src/test/java/world/bentobox/parkour/ParkourTest.java index d9b11d4..4feb606 100644 --- a/src/test/java/world/bentobox/parkour/ParkourTest.java +++ b/src/test/java/world/bentobox/parkour/ParkourTest.java @@ -4,12 +4,9 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -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.File; import java.io.FileInputStream; @@ -19,254 +16,137 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; -import java.util.Comparator; -import java.util.UUID; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; -import java.util.logging.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Server; -import org.bukkit.entity.Player; -import org.bukkit.plugin.PluginManager; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.stubbing.Answer; -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 world.bentobox.bentobox.BentoBox; -import world.bentobox.bentobox.Settings; import world.bentobox.bentobox.api.addons.Addon.State; import world.bentobox.bentobox.api.addons.AddonDescription; -import world.bentobox.bentobox.api.configuration.Config; -import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; -import world.bentobox.bentobox.database.objects.Island; -import world.bentobox.bentobox.managers.AddonsManager; -import world.bentobox.bentobox.managers.CommandsManager; -import world.bentobox.bentobox.managers.FlagsManager; -import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; -import world.bentobox.bentobox.managers.PlaceholdersManager; /** * @author tastybento * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Config.class }) -public class ParkourTest { - - @Mock - private User user; - @Mock - private IslandsManager im; - @Mock - private Island island; - - private Parkour addon; - @Mock - private BentoBox plugin; - @Mock - private FlagsManager fm; - @Mock - private Settings settings; - @Mock - private PlaceholdersManager phm; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger()); - - // The database type has to be created one line before the thenReturn() to work! - DatabaseType value = DatabaseType.JSON; - when(plugin.getSettings()).thenReturn(settings); - when(settings.getDatabaseType()).thenReturn(value); - when(plugin.getPlaceholdersManager()).thenReturn(phm); - // Placeholders - when(phm.replacePlaceholders(any(), anyString())).thenAnswer(a -> (String)a.getArgument(1, String.class)); - - - // Command manager - CommandsManager cm = mock(CommandsManager.class); - when(plugin.getCommandsManager()).thenReturn(cm); - - // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - when(user.isOp()).thenReturn(false); - UUID uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - User.setPlugin(plugin); - - // Island World Manager - IslandWorldManager iwm = mock(IslandWorldManager.class); - when(plugin.getIWM()).thenReturn(iwm); - - - // Player has island to begin with - island = mock(Island.class); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island); - when(plugin.getIslands()).thenReturn(im); - - // Locales - // Return the reference (USE THIS IN THE FUTURE) - when(user.getTranslation(Mockito.anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - - // Server - PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); - Server server = mock(Server.class); - when(Bukkit.getServer()).thenReturn(server); - when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); - when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class)); - - // Create an Addon - addon = new Parkour(); - File jFile = new File("addon.jar"); - try (JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(jFile))) { - - // Copy over config file from src folder - Path fromPath = Paths.get("src/main/resources/config.yml"); - Path path = Paths.get("config.yml"); - Files.copy(fromPath, path); - - //Add the new files to the jar. - add(path, tempJarOutputStream); - - } - - File dataFolder = new File("addons/Parkour"); - addon.setDataFolder(dataFolder); - addon.setFile(jFile); - AddonDescription desc = new AddonDescription.Builder("bentobox", "parkour", "1.3").description("test").authors("tasty").build(); - addon.setDescription(desc); - // Addons manager - AddonsManager am = mock(AddonsManager.class); - when(plugin.getAddonsManager()).thenReturn(am); - - // Flags manager - when(plugin.getFlagsManager()).thenReturn(fm); - when(fm.getFlags()).thenReturn(Collections.emptyList()); - - } - - private void add(Path path, JarOutputStream tempJarOutputStream) throws FileNotFoundException, IOException { - try (FileInputStream fis = new FileInputStream(path.toFile())) { - byte[] buffer = new byte[1024]; - int bytesRead = 0; - JarEntry entry = new JarEntry(path.toString()); - tempJarOutputStream.putNextEntry(entry); - while((bytesRead = fis.read(buffer)) != -1) { - tempJarOutputStream.write(buffer, 0, bytesRead); - } - } - - } - - /** - * @throws java.lang.Exception - */ - @After - public void tearDown() throws Exception { - new File("addon.jar").delete(); - new File("config.yml").delete(); - deleteAll(new File("addons")); - deleteAll(new File("database")); - } - - private void deleteAll(File file) throws IOException { - if (file.exists()) { - Files.walk(file.toPath()) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); - } - - } - - - /** - * Test method for {@link world.bentobox.aoneblock.AOneBlock#onEnable()}. - */ - @Test - public void testOnEnable() { - testOnLoad(); - addon.setState(State.ENABLED); - addon.onEnable(); - verify(plugin, never()).logError(anyString()); - assertNotEquals(State.DISABLED, addon.getState()); - } - - /** - * Test method for {@link world.bentobox.aoneblock.AOneBlock#onLoad()}. - */ - @Test - public void testOnLoad() { - addon.onLoad(); - // Check that config.yml file has been saved - File check = new File("addons/Parkour","config.yml"); - assertTrue(check.exists()); - assertTrue(addon.getPlayerCommand().isPresent()); - assertTrue(addon.getAdminCommand().isPresent()); - - } - - /** - * Test method for {@link world.bentobox.aoneblock.AOneBlock#onReload()}. - */ - @Test - public void testOnReload() { - addon.onEnable(); - addon.onReload(); - // Check that config.yml file has been saved - File check = new File("addons/Parkour","config.yml"); - assertTrue(check.exists()); - } - - /** - * Test method for {@link world.bentobox.aoneblock.AOneBlock#createWorlds()}. - */ - @Test - public void testCreateWorlds() { - addon.onLoad(); - addon.createWorlds(); - verify(plugin).log("[parkour] Creating Parkour world ..."); - verify(plugin).log("[parkour] Creating Parkour's Nether..."); - verify(plugin).log("[parkour] Creating Parkour's End World..."); - - } - - /** - * Test method for {@link world.bentobox.aoneblock.AOneBlock#getSettings()}. - */ - @Test - public void testGetSettings() { - addon.onLoad(); - assertNotNull(addon.getSettings()); - - } - - /** - * Test method for {@link world.bentobox.aoneblock.AOneBlock#getWorldSettings()}. - */ - @Test - public void testGetWorldSettings() { - addon.onLoad(); - assertEquals(addon.getSettings(), addon.getWorldSettings()); - } +public class ParkourTest extends AbstractParkourTest { + + protected Parkour addonJar; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + // Create an Addon + addonJar = new Parkour(); + File jFile = new File("addon.jar"); + try (JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(jFile))) { + + // Copy over config file from src folder + Path fromPath = Paths.get("src/main/resources/config.yml"); + Path path = Paths.get("config.yml"); + Files.copy(fromPath, path); + + // Add the new files to the jar. + add(path, tempJarOutputStream); + + } + + File dataFolder = new File("addons/Parkour"); + addonJar.setDataFolder(dataFolder); + addonJar.setFile(jFile); + AddonDescription desc = new AddonDescription.Builder("bentobox", "parkour", "1.3").description("test") + .authors("tasty").build(); + addonJar.setDescription(desc); + + } + + private void add(Path path, JarOutputStream tempJarOutputStream) throws FileNotFoundException, IOException { + try (FileInputStream fis = new FileInputStream(path.toFile())) { + byte[] buffer = new byte[1024]; + int bytesRead = 0; + JarEntry entry = new JarEntry(path.toString()); + tempJarOutputStream.putNextEntry(entry); + while ((bytesRead = fis.read(buffer)) != -1) { + tempJarOutputStream.write(buffer, 0, bytesRead); + } + } + + } + + /** + * Test method for {@link world.bentobox.aoneblock.AOneBlock#onEnable()}. + */ + @Test + public void testOnEnable() { + testOnLoad(); + addonJar.setState(State.ENABLED); + addonJar.onEnable(); + verify(plugin, never()).logError(anyString()); + assertNotEquals(State.DISABLED, addonJar.getState()); + } + + /** + * Test method for {@link world.bentobox.aoneblock.AOneBlock#onLoad()}. + */ + @Test + public void testOnLoad() { + addonJar.onLoad(); + // Check that config.yml file has been saved + File check = new File("addons/Parkour", "config.yml"); + assertTrue(check.exists()); + assertTrue(addonJar.getPlayerCommand().isPresent()); + assertTrue(addonJar.getAdminCommand().isPresent()); + + } + + /** + * Test method for {@link world.bentobox.aoneblock.AOneBlock#onReload()}. + */ + @Test + public void testOnReload() { + addonJar.onEnable(); + addonJar.onReload(); + // Check that config.yml file has been saved + File check = new File("addons/Parkour", "config.yml"); + assertTrue(check.exists()); + } + + /** + * Test method for {@link world.bentobox.aoneblock.AOneBlock#createWorlds()}. + */ + @Test + public void testCreateWorlds() { + addonJar.onLoad(); + addonJar.createWorlds(); + verify(plugin).log("[parkour] Creating Parkour world ..."); + verify(plugin).log("[parkour] Creating Parkour's Nether..."); + verify(plugin).log("[parkour] Creating Parkour's End World..."); + + } + + /** + * Test method for {@link world.bentobox.aoneblock.AOneBlock#getSettings()}. + */ + @Test + public void testGetSettings() { + addonJar.onLoad(); + assertNotNull(addonJar.getSettings()); + + } + + /** + * Test method for + * {@link world.bentobox.aoneblock.AOneBlock#getWorldSettings()}. + */ + @Test + public void testGetWorldSettings() { + addonJar.onLoad(); + assertEquals(addonJar.getSettings(), addonJar.getWorldSettings()); + } } diff --git a/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java b/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java index b3141ae..d2c8bf7 100644 --- a/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/QuitCommandTest.java @@ -17,30 +17,22 @@ import java.util.Optional; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; -import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.RanksManager; -import world.bentobox.parkour.Parkour; +import world.bentobox.parkour.AbstractParkourTest; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.ParkourRunRecord; import world.bentobox.parkour.Settings; @@ -50,122 +42,108 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) -public class QuitCommandTest { - @Mock - private BentoBox plugin; - @Mock - private CompositeCommand ac; - @Mock - private User user; - @Mock - private LocalesManager lm; - @Mock - private Parkour addon; - private UUID uuid; - @Mock - private World world; - @Mock - private IslandsManager im; - @Mock - private @Nullable Island island; - @Mock - private IslandWorldManager iwm; - @Mock - private ParkourManager parkourManager; - - private QuitCommand cmd; - @Mock - private @NonNull Location location; - // No mock - private ParkourRunRecord prm; - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - - // Command manager - CommandsManager cm = mock(CommandsManager.class); - when(plugin.getCommandsManager()).thenReturn(cm); - - // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - when(user.isOp()).thenReturn(false); - when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); - when(user.getWorld()).thenReturn(world); - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - when(user.getLocation()).thenReturn(location); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); - User.setPlugin(plugin); - - // Parent command has no aliases - when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); - when(ac.getWorld()).thenReturn(world); - when(ac.getAddon()).thenReturn(addon); - - prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); - prm.timers().put(uuid, 20L); - when(addon.getParkourRunRecord()).thenReturn(prm); - - // Islands - when(addon.getIslands()).thenReturn(im); - when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(world, user)).thenReturn(island); - when(im.getIslandAt(location)).thenReturn(Optional.of(island)); - when(im.hasIsland(world, user)).thenReturn(true); - when(im.inTeam(world, uuid)).thenReturn(true); - when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); - when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); - when(im.userIsOnIsland(any(), any())).thenReturn(true); - - // Parkour Manager - // No warp spot - when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); - when(addon.getParkourManager()).thenReturn(parkourManager); - - // IWM - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); - when(iwm.inWorld(world)).thenReturn(true); - - // Settings - Settings settings = new Settings(); - when(addon.getSettings()).thenReturn(settings); - - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // DUT - cmd = new QuitCommand(ac); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.QuitCommand#QuitCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testQuitCommand() { - assertNotNull(cmd); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.QuitCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("quit", cmd.getPermission()); - assertEquals("parkour.commands.parkour.quit.description", cmd.getDescription()); - assertTrue(cmd.isOnlyPlayer()); - } - - /** +public class QuitCommandTest extends AbstractParkourTest { + @Mock + private CompositeCommand ac; + @Mock + private User user; + @Mock + private LocalesManager lm; + private UUID uuid; + @Mock + private World world; + @Mock + private ParkourManager parkourManager; + + private QuitCommand cmd; + @Mock + private @NonNull Location location; + // No mock + private ParkourRunRecord prm; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); + when(user.getWorld()).thenReturn(world); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + when(user.getLocation()).thenReturn(location); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + User.setPlugin(plugin); + + // Parent command has no aliases + when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); + when(ac.getWorld()).thenReturn(world); + when(ac.getAddon()).thenReturn(addon); + + prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); + prm.timers().put(uuid, 20L); + when(addon.getParkourRunRecord()).thenReturn(prm); + + // Islands + when(addon.getIslands()).thenReturn(im); + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(world, user)).thenReturn(island); + when(im.getIslandAt(location)).thenReturn(Optional.of(island)); + when(im.hasIsland(world, user)).thenReturn(true); + when(im.inTeam(world, uuid)).thenReturn(true); + when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); + when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); + when(im.userIsOnIsland(any(), any())).thenReturn(true); + + // Parkour Manager + // No warp spot + when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); + when(addon.getParkourManager()).thenReturn(parkourManager); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); + when(iwm.inWorld(world)).thenReturn(true); + + // Settings + Settings settings = new Settings(); + when(addon.getSettings()).thenReturn(settings); + + // DUT + cmd = new QuitCommand(ac); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.QuitCommand#QuitCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testQuitCommand() { + assertNotNull(cmd); + } + + /** + * Test method for {@link world.bentobox.parkour.commands.QuitCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("quit", cmd.getPermission()); + assertEquals("parkour.commands.parkour.quit.description", cmd.getDescription()); + assertTrue(cmd.isOnlyPlayer()); + } + + /** * Test method for {@link world.bentobox.parkour.commands.QuitCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -175,7 +153,7 @@ public void testCanExecuteWrongWorld() { verify(user).sendMessage("general.errors.wrong-world"); } - /** + /** * Test method for {@link world.bentobox.parkour.commands.QuitCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -186,33 +164,36 @@ public void testCanExecuteNotOnIsland() { verify(user).sendMessage("parkour.errors.not-on-island"); } - /** - * Test method for {@link world.bentobox.parkour.commands.QuitCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteNotInRun() { - prm.timers().clear(); - assertFalse(cmd.canExecute(user, "", List.of())); - verify(user).sendMessage("parkour.errors.not-in-run"); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.QuitCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteSuccess() { - assertTrue(cmd.canExecute(user, "", List.of())); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.QuitCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - assertTrue(cmd.execute(user, "", List.of())); - verify(user).sendMessage("parkour.quit.success"); - assertTrue(prm.timers().isEmpty()); - assertTrue(prm.checkpoints().isEmpty()); - } + /** + * Test method for + * {@link world.bentobox.parkour.commands.QuitCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteNotInRun() { + prm.timers().clear(); + assertFalse(cmd.canExecute(user, "", List.of())); + verify(user).sendMessage("parkour.errors.not-in-run"); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.QuitCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteSuccess() { + assertTrue(cmd.canExecute(user, "", List.of())); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.QuitCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + assertTrue(cmd.execute(user, "", List.of())); + verify(user).sendMessage("parkour.quit.success"); + assertTrue(prm.timers().isEmpty()); + assertTrue(prm.checkpoints().isEmpty()); + } } diff --git a/src/test/java/world/bentobox/parkour/commands/RemoveWarpCommandTest.java b/src/test/java/world/bentobox/parkour/commands/RemoveWarpCommandTest.java index 2eab589..d7e7a4d 100644 --- a/src/test/java/world/bentobox/parkour/commands/RemoveWarpCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/RemoveWarpCommandTest.java @@ -1,6 +1,9 @@ package world.bentobox.parkour.commands; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +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.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -14,30 +17,22 @@ import java.util.Optional; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; -import org.eclipse.jdt.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; -import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.RanksManager; -import world.bentobox.parkour.Parkour; +import world.bentobox.parkour.AbstractParkourTest; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.Settings; @@ -46,133 +41,118 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) -public class RemoveWarpCommandTest { - @Mock - private BentoBox plugin; - @Mock - private CompositeCommand ac; - @Mock - private User user; - @Mock - private LocalesManager lm; - @Mock - private Parkour addon; - private UUID uuid; - @Mock - private World world; - @Mock - private IslandsManager im; - @Mock - private @Nullable Island island; - @Mock - private IslandWorldManager iwm; - private RemoveWarpCommand cmd; - @Mock - private ParkourManager parkourManager; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - BentoBox plugin = mock(BentoBox.class); - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - - // Command manager - CommandsManager cm = mock(CommandsManager.class); - when(plugin.getCommandsManager()).thenReturn(cm); - - // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - when(user.isOp()).thenReturn(false); - when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); - when(user.getWorld()).thenReturn(world); - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); - User.setPlugin(plugin); - - // Parent command has no aliases - when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); - when(ac.getWorld()).thenReturn(world); - when(ac.getAddon()).thenReturn(addon); - - // Islands - when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(world, user)).thenReturn(island); - when(im.hasIsland(world, user)).thenReturn(true); - when(im.inTeam(world, uuid)).thenReturn(true); - when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); - when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); - when(im.userIsOnIsland(any(), any())).thenReturn(true); - - // Parkour Manager - // Warp spot available by default - when(parkourManager.getWarpSpot(island)).thenReturn(Optional.of(mock(Location.class))); - when(addon.getParkourManager()).thenReturn(parkourManager); - - // IWM - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock."); - - // Settings - Settings settings = new Settings(); - when(addon.getSettings()).thenReturn(settings); - - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // DUT - cmd = new RemoveWarpCommand(ac); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#RemoveWarpCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testRemoveWarpCommand() { - assertNotNull(cmd); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("removewarp", cmd.getPermission()); - assertEquals("parkour.commands.parkour.removewarp.description", cmd.getDescription()); - assertTrue(cmd.isConfigurableRankCommand()); - assertTrue(cmd.isOnlyPlayer()); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteFailHelp() { - // Help - assertFalse(cmd.canExecute(user, "", List.of("something"))); - verify(user).sendMessage("commands.help.header","[label]",null); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteFailNoRank() { - // Insufficient rank - assertFalse(cmd.canExecute(user, "", List.of())); - verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, RanksManager.MEMBER_RANK_REF); - - } - - /** +public class RemoveWarpCommandTest extends AbstractParkourTest { + @Mock + private CompositeCommand ac; + @Mock + private LocalesManager lm; + private UUID uuid; + @Mock + private World world; + private RemoveWarpCommand cmd; + @Mock + private ParkourManager parkourManager; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); + when(user.getWorld()).thenReturn(world); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + User.setPlugin(plugin); + + // Parent command has no aliases + when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); + when(ac.getWorld()).thenReturn(world); + when(ac.getAddon()).thenReturn(addon); + + // Islands + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(world, user)).thenReturn(island); + when(im.hasIsland(world, user)).thenReturn(true); + when(im.inTeam(world, uuid)).thenReturn(true); + when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); + when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); + when(im.userIsOnIsland(any(), any())).thenReturn(true); + + // Parkour Manager + // Warp spot available by default + when(parkourManager.getWarpSpot(island)).thenReturn(Optional.of(mock(Location.class))); + when(addon.getParkourManager()).thenReturn(parkourManager); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock."); + + // Settings + Settings settings = new Settings(); + when(addon.getSettings()).thenReturn(settings); + + // DUT + cmd = new RemoveWarpCommand(ac); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.RemoveWarpCommand#RemoveWarpCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testRemoveWarpCommand() { + assertNotNull(cmd); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.RemoveWarpCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("removewarp", cmd.getPermission()); + assertEquals("parkour.commands.parkour.removewarp.description", cmd.getDescription()); + assertTrue(cmd.isConfigurableRankCommand()); + assertTrue(cmd.isOnlyPlayer()); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.RemoveWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteFailHelp() { + // Help + assertFalse(cmd.canExecute(user, "", List.of("something"))); + verify(user).sendMessage("commands.help.header", "[label]", null); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.RemoveWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteFailNoRank() { + // Insufficient rank + assertFalse(cmd.canExecute(user, "", List.of())); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, RanksManager.MEMBER_RANK_REF); + + } + + /** * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -185,7 +165,7 @@ public void testCanExecuteFailNoWarpSpot() { } - /** + /** * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -196,18 +176,19 @@ public void testCanExecutePass() { verify(user, never()).sendMessage(any()); } - /** - * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - assertTrue(cmd.execute(user, "", List.of())); - verify(user).sendMessage("parkour.warp.removed"); - verify(parkourManager).setWarpSpot(island, null); + /** + * Test method for + * {@link world.bentobox.parkour.commands.RemoveWarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + assertTrue(cmd.execute(user, "", List.of())); + verify(user).sendMessage("parkour.warp.removed"); + verify(parkourManager).setWarpSpot(island, null); - } + } - /** + /** * Test method for {@link world.bentobox.parkour.commands.RemoveWarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test diff --git a/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java b/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java index 74e3f69..fb5b102 100644 --- a/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java @@ -17,159 +17,141 @@ import java.util.Optional; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; -import org.eclipse.jdt.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; -import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.RanksManager; -import world.bentobox.parkour.Parkour; +import world.bentobox.parkour.AbstractParkourTest; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.Settings; /** * Set warp command testd + * * @author tastybento * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) -public class SetWarpCommandTest { - @Mock - private BentoBox plugin; - @Mock - private CompositeCommand ac; - @Mock - private User user; - @Mock - private LocalesManager lm; - @Mock - private Parkour addon; - private UUID uuid; - @Mock - private World world; - @Mock - private IslandsManager im; - @Mock - private @Nullable Island island; - @Mock - private IslandWorldManager iwm; - private SetWarpCommand cmd; - @Mock - private ParkourManager parkourManager; - @Mock - private Location location; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - - // Command manager - CommandsManager cm = mock(CommandsManager.class); - when(plugin.getCommandsManager()).thenReturn(cm); - - // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - when(user.isOp()).thenReturn(false); - when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); - when(user.getWorld()).thenReturn(world); - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); - User.setPlugin(plugin); - - // Parent command has no aliases - when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); - when(ac.getWorld()).thenReturn(world); - when(ac.getAddon()).thenReturn(addon); - - // Islands - when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(world, user)).thenReturn(island); - when(im.hasIsland(world, user)).thenReturn(true); - when(im.inTeam(world, uuid)).thenReturn(true); - when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); - when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); - when(im.userIsOnIsland(any(), any())).thenReturn(true); - - // Parkour Manager - // No warp spot - when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); - // Start and end plates are set - when(parkourManager.getStart(island)).thenReturn(Optional.of(location)); - when(parkourManager.getEnd(island)).thenReturn(Optional.of(location)); - when(addon.getParkourManager()).thenReturn(parkourManager); - - // IWM - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); - - // Settings - Settings settings = new Settings(); - when(addon.getSettings()).thenReturn(settings); - - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // DUT - cmd = new SetWarpCommand(ac); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#SetWarpCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testSetWarpCommand() { - assertNotNull(cmd); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("setwarp", cmd.getPermission()); - assertEquals("parkour.commands.parkour.setwarp.description", cmd.getDescription()); - assertTrue(cmd.isConfigurableRankCommand()); - assertTrue(cmd.isOnlyPlayer()); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteFailHelp() { - // Help - assertFalse(cmd.canExecute(user, "", List.of("something"))); - verify(user).sendMessage("commands.help.header","[label]",null); - } - - /** +public class SetWarpCommandTest extends AbstractParkourTest { + @Mock + private LocalesManager lm; + private UUID uuid; + @Mock + private World world; + private SetWarpCommand cmd; + @Mock + private ParkourManager parkourManager; + @Mock + private Location location; + @Mock + private CompositeCommand ac; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); + when(user.getWorld()).thenReturn(world); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + User.setPlugin(plugin); + + // Parent command has no aliases + when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); + when(ac.getWorld()).thenReturn(world); + when(ac.getAddon()).thenReturn(addon); + + // Islands + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(world, user)).thenReturn(island); + when(im.hasIsland(world, user)).thenReturn(true); + when(im.inTeam(world, uuid)).thenReturn(true); + when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); + when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); + when(im.userIsOnIsland(any(), any())).thenReturn(true); + + // Parkour Manager + // No warp spot + when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); + // Start and end plates are set + when(parkourManager.getStart(island)).thenReturn(Optional.of(location)); + when(parkourManager.getEnd(island)).thenReturn(Optional.of(location)); + when(addon.getParkourManager()).thenReturn(parkourManager); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); + + // Settings + Settings settings = new Settings(); + when(addon.getSettings()).thenReturn(settings); + + // RanksManager + RanksManager rm = new RanksManager(); + when(plugin.getRanksManager()).thenReturn(rm); + + // DUT + cmd = new SetWarpCommand(ac); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.SetWarpCommand#SetWarpCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testSetWarpCommand() { + assertNotNull(cmd); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.SetWarpCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("setwarp", cmd.getPermission()); + assertEquals("parkour.commands.parkour.setwarp.description", cmd.getDescription()); + assertTrue(cmd.isConfigurableRankCommand()); + assertTrue(cmd.isOnlyPlayer()); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteFailHelp() { + // Help + assertFalse(cmd.canExecute(user, "", List.of("something"))); + verify(user).sendMessage("commands.help.header", "[label]", null); + } + + /** * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -180,18 +162,19 @@ public void testCanExecuteFailNoIsland() { verify(user).sendMessage("parkour.errors.not-on-island"); } - /** - * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteFailNoRank() { - // Insufficient rank - assertFalse(cmd.canExecute(user, "", List.of())); - verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, RanksManager.MEMBER_RANK_REF); + /** + * Test method for + * {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteFailNoRank() { + // Insufficient rank + assertFalse(cmd.canExecute(user, "", List.of())); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, RanksManager.MEMBER_RANK_REF); - } + } - /** + /** * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -209,7 +192,7 @@ public void testCanExecuteNoStartEndPlates() { verify(user).notify("parkour.no-end-yet"); } - /** + /** * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -220,18 +203,19 @@ public void testCanExecutePass() { verify(user, never()).sendMessage(any()); } - /** - * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - assertTrue(cmd.execute(user, "", List.of())); - verify(user).sendMessage("parkour.warp.set"); - verify(parkourManager).setWarpSpot(island, null); + /** + * Test method for + * {@link world.bentobox.parkour.commands.SetWarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + assertTrue(cmd.execute(user, "", List.of())); + verify(user).sendMessage("parkour.warp.set"); + verify(parkourManager).setWarpSpot(island, null); - } + } - /** + /** * Test method for {@link world.bentobox.parkour.commands.SetWarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test diff --git a/src/test/java/world/bentobox/parkour/commands/TopCommandTest.java b/src/test/java/world/bentobox/parkour/commands/TopCommandTest.java index 3c97e7a..bf7a032 100644 --- a/src/test/java/world/bentobox/parkour/commands/TopCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/TopCommandTest.java @@ -16,30 +16,22 @@ import java.util.Optional; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; -import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.RanksManager; -import world.bentobox.parkour.Parkour; +import world.bentobox.parkour.AbstractParkourTest; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.Settings; import world.bentobox.parkour.gui.RankingsUI; @@ -49,119 +41,102 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) -public class TopCommandTest { - @Mock - private BentoBox plugin; - @Mock - private CompositeCommand ac; - @Mock - private User user; - @Mock - private LocalesManager lm; - @Mock - private Parkour addon; - private UUID uuid; - @Mock - private World world; - @Mock - private IslandsManager im; - @Mock - private @Nullable Island island; - @Mock - private IslandWorldManager iwm; - @Mock - private ParkourManager parkourManager; - - private TopCommand cmd; - @Mock - private @NonNull Location location; - @Mock - private RankingsUI rankings; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - - // Command manager - CommandsManager cm = mock(CommandsManager.class); - when(plugin.getCommandsManager()).thenReturn(cm); - - // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - when(user.isOp()).thenReturn(false); - when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); - when(user.getWorld()).thenReturn(world); - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - when(user.getLocation()).thenReturn(location); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); - User.setPlugin(plugin); - - // Parent command has no aliases - when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); - when(ac.getWorld()).thenReturn(world); - when(ac.getAddon()).thenReturn(addon); - when(addon.getRankings()).thenReturn(rankings); - - // Islands - when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(world, user)).thenReturn(island); - when(im.getIslandAt(location)).thenReturn(Optional.of(island)); - when(im.hasIsland(world, user)).thenReturn(true); - when(im.inTeam(world, uuid)).thenReturn(true); - when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); - when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); - when(im.userIsOnIsland(any(), any())).thenReturn(true); - - // Parkour Manager - // No warp spot - when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); - when(addon.getParkourManager()).thenReturn(parkourManager); - - // IWM - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); - when(iwm.inWorld(world)).thenReturn(true); - - // Settings - Settings settings = new Settings(); - when(addon.getSettings()).thenReturn(settings); - - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // DUT - cmd = new TopCommand(ac); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.TopCommand#TopCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testTopCommand() { - assertNotNull(cmd); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.TopCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("top", cmd.getPermission()); - assertEquals("parkour.commands.parkour.top.description", cmd.getDescription()); - assertTrue(cmd.isOnlyPlayer()); - } - - /** +public class TopCommandTest extends AbstractParkourTest { + @Mock + private CompositeCommand ac; + @Mock + private LocalesManager lm; + private UUID uuid; + @Mock + private World world; + @Mock + private ParkourManager parkourManager; + + private TopCommand cmd; + @Mock + private @NonNull Location location; + @Mock + private RankingsUI rankings; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); + when(user.getWorld()).thenReturn(world); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + when(user.getLocation()).thenReturn(location); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + User.setPlugin(plugin); + + // Parent command has no aliases + when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); + when(ac.getWorld()).thenReturn(world); + when(ac.getAddon()).thenReturn(addon); + when(addon.getRankings()).thenReturn(rankings); + + // Islands + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(world, user)).thenReturn(island); + when(im.getIslandAt(location)).thenReturn(Optional.of(island)); + when(im.hasIsland(world, user)).thenReturn(true); + when(im.inTeam(world, uuid)).thenReturn(true); + when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); + when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); + when(im.userIsOnIsland(any(), any())).thenReturn(true); + + // Parkour Manager + // No warp spot + when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); + when(addon.getParkourManager()).thenReturn(parkourManager); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); + when(iwm.inWorld(world)).thenReturn(true); + + // Settings + Settings settings = new Settings(); + when(addon.getSettings()).thenReturn(settings); + + // DUT + cmd = new TopCommand(ac); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.TopCommand#TopCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testTopCommand() { + assertNotNull(cmd); + } + + /** + * Test method for {@link world.bentobox.parkour.commands.TopCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("top", cmd.getPermission()); + assertEquals("parkour.commands.parkour.top.description", cmd.getDescription()); + assertTrue(cmd.isOnlyPlayer()); + } + + /** * Test method for {@link world.bentobox.parkour.commands.TopCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -172,8 +147,7 @@ public void testCanExecuteFailNotOnIsland() { verify(user).sendMessage("parkour.errors.not-on-island"); } - - /** + /** * Test method for {@link world.bentobox.parkour.commands.TopCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -183,22 +157,24 @@ public void testCanExecuteFailWrongWorld() { verify(user).sendMessage("general.errors.wrong-world"); } - /** - * Test method for {@link world.bentobox.parkour.commands.TopCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecutePass() { - assertTrue(cmd.canExecute(user, "", List.of())); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.TopCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - testCanExecutePass(); - assertTrue(cmd.execute(user, "", List.of())); - verify(rankings).getGUI(island, user); - } + /** + * Test method for + * {@link world.bentobox.parkour.commands.TopCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecutePass() { + assertTrue(cmd.canExecute(user, "", List.of())); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.TopCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + testCanExecutePass(); + assertTrue(cmd.execute(user, "", List.of())); + verify(rankings).getGUI(island, user); + } } diff --git a/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java b/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java index 5a63f97..45a5ed5 100644 --- a/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/WarpCommandTest.java @@ -25,30 +25,22 @@ import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; -import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; 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 world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; -import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; -import world.bentobox.parkour.Parkour; +import world.bentobox.parkour.AbstractParkourTest; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.Settings; @@ -57,151 +49,140 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Util.class}) -public class WarpCommandTest { - - @Mock - private BentoBox plugin; - @Mock - private CompositeCommand ac; - @Mock - private User user; - @Mock - private LocalesManager lm; - @Mock - private Parkour addon; - private UUID uuid; - @Mock - private World world; - @Mock - private IslandsManager im; - @Mock - private @Nullable Island island; - @Mock - private IslandWorldManager iwm; - private WarpCommand cmd; - @Mock - private ParkourManager parkourManager; - @Mock - private Location location; - @Mock - private @NonNull Player p; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - - // Command manager - CommandsManager cm = mock(CommandsManager.class); - when(plugin.getCommandsManager()).thenReturn(cm); - - // User - when(user.isOp()).thenReturn(false); - when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); - when(user.getWorld()).thenReturn(world); - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); - when(user.getLocation()).thenReturn(location); - User.setPlugin(plugin); - - // Parent command has no aliases - when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); - when(ac.getWorld()).thenReturn(world); - when(ac.getAddon()).thenReturn(addon); - - // Islands - when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(world, user)).thenReturn(island); - when(im.hasIsland(world, user)).thenReturn(true); - when(im.inTeam(world, uuid)).thenReturn(true); - when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); - when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); - when(im.userIsOnIsland(any(), any())).thenReturn(true); - - // Parkour Manager - // No warp spot - when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); - // Start and end plates are set - when(parkourManager.getStart(island)).thenReturn(Optional.of(location)); - when(parkourManager.getEnd(island)).thenReturn(Optional.of(location)); - when(addon.getParkourManager()).thenReturn(parkourManager); - - // IWM - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); - - // World - when(addon.inWorld(world)).thenReturn(true); - - // Location - when(location.clone()).thenReturn(location); - - // Settings - Settings settings = new Settings(); - when(addon.getSettings()).thenReturn(settings); - - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // Static classes : Bukkit, Util - PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); - PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); - when(Util.tabLimit(any(), any())).thenCallRealMethod(); - // DUT - cmd = new WarpCommand(ac); - } - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#WarpCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testWarpCommand() { - assertNotNull(cmd); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("warp", cmd.getPermission()); - assertEquals("parkour.commands.parkour.warp.description", cmd.getDescription()); - assertEquals("parkour.commands.parkour.warp.parameters", cmd.getParameters()); - assertTrue(cmd.isOnlyPlayer()); - - } - - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteHelp() { - assertFalse(cmd.canExecute(user, "", List.of("more","than","one"))); - verify(user).sendMessage("commands.help.header","[label]",null); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteNoArgNotOnParkourIsland() { - assertFalse(cmd.canExecute(user, "", List.of())); - // On island, but not in world - when(im.getIslandAt(location)).thenReturn(Optional.of(island)); - when(addon.inWorld(world)).thenReturn(false); - assertFalse(cmd.canExecute(user, "", List.of())); - verify(user, times(2)).sendMessage("parkour.errors.not-on-island"); - verify(user, times(2)).sendMessage("commands.help.header","[label]",null); - } - - /** +public class WarpCommandTest extends AbstractParkourTest { + + @Mock + private CompositeCommand ac; + @Mock + private User user; + @Mock + private LocalesManager lm; + private UUID uuid; + @Mock + private World world; + @Mock + private WarpCommand cmd; + @Mock + private ParkourManager parkourManager; + @Mock + private Location location; + @Mock + private @NonNull Player p; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // User + when(user.isOp()).thenReturn(false); + when(user.getPermissionValue(anyString(), anyInt())).thenReturn(4); + when(user.getWorld()).thenReturn(world); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + when(user.getLocation()).thenReturn(location); + User.setPlugin(plugin); + + // Parent command has no aliases + when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); + when(ac.getWorld()).thenReturn(world); + when(ac.getAddon()).thenReturn(addon); + + // Islands + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(world, user)).thenReturn(island); + when(im.hasIsland(world, user)).thenReturn(true); + when(im.inTeam(world, uuid)).thenReturn(true); + when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); + when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); + when(im.userIsOnIsland(any(), any())).thenReturn(true); + + // Parkour Manager + // No warp spot + when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); + // Start and end plates are set + when(parkourManager.getStart(island)).thenReturn(Optional.of(location)); + when(parkourManager.getEnd(island)).thenReturn(Optional.of(location)); + when(addon.getParkourManager()).thenReturn(parkourManager); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); + + // World + when(addon.inWorld(world)).thenReturn(true); + + // Location + when(location.clone()).thenReturn(location); + + // Settings + Settings settings = new Settings(); + when(addon.getSettings()).thenReturn(settings); + + // Static classes : Bukkit, Util + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); + PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); + when(Util.tabLimit(any(), any())).thenCallRealMethod(); + // DUT + cmd = new WarpCommand(ac); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#WarpCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testWarpCommand() { + assertNotNull(cmd); + } + + /** + * Test method for {@link world.bentobox.parkour.commands.WarpCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("warp", cmd.getPermission()); + assertEquals("parkour.commands.parkour.warp.description", cmd.getDescription()); + assertEquals("parkour.commands.parkour.warp.parameters", cmd.getParameters()); + assertTrue(cmd.isOnlyPlayer()); + + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteHelp() { + assertFalse(cmd.canExecute(user, "", List.of("more", "than", "one"))); + verify(user).sendMessage("commands.help.header", "[label]", null); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteNoArgNotOnParkourIsland() { + assertFalse(cmd.canExecute(user, "", List.of())); + // On island, but not in world + when(im.getIslandAt(location)).thenReturn(Optional.of(island)); + when(addon.inWorld(world)).thenReturn(false); + assertFalse(cmd.canExecute(user, "", List.of())); + verify(user, times(2)).sendMessage("parkour.errors.not-on-island"); + verify(user, times(2)).sendMessage("commands.help.header", "[label]", null); + } + + /** * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -213,7 +194,7 @@ public void testCanExecuteNoArgOnIslandNoWarp() { verify(user, never()).sendMessage("commands.help.header","[label]",null); } - /** + /** * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -224,7 +205,7 @@ public void testCanExecuteNoArgSuccess() { verify(user, never()).sendMessage(any()); } - /** + /** * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -234,7 +215,7 @@ public void testCanExecuteArgNoWarps() { verify(user).sendMessage("parkour.warp.unknown-course"); } - /** + /** * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -244,7 +225,7 @@ public void testCanExecuteArgDifferentPlayer() { verify(user).sendMessage("parkour.warp.unknown-course"); } - /** + /** * Test method for {@link world.bentobox.parkour.commands.WarpCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -254,72 +235,76 @@ public void testCanExecuteArgMixedCase() { verify(user, never()).sendMessage(any()); } - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - // Set warpspot - testCanExecuteArgMixedCase(); - // Run test - assertTrue(cmd.execute(user, "", List.of())); - verify(user).sendMessage("parkour.warp.warping"); - // Teleport user - verify(p, times(2)).playSound(location, Sound.ENTITY_BAT_TAKEOFF, 1F, 1F); - PowerMockito.verifyStatic(Util.class); - Util.teleportAsync(p, location, TeleportCause.COMMAND); - - } - - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testTabCompleteUserStringListOfString() { - assertTrue(cmd.tabComplete(user, "", List.of("ta")).get().isEmpty()); - when(parkourManager.getWarps()).thenReturn(Map.of("tAsTyBeNtO", location)); - List list = cmd.tabComplete(user, "", List.of("ta")).get(); - assertEquals("tAsTyBeNtO", list.get(0)); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testTabCompleteUserStringListOfStringEmpty() { - assertTrue(cmd.tabComplete(user, "", List.of()).get().isEmpty()); - when(parkourManager.getWarps()).thenReturn(Map.of("tAsTyBeNtO", location)); - List list = cmd.tabComplete(user, "", List.of("ta")).get(); - assertEquals("tAsTyBeNtO", list.get(0)); - } - - /** - * Test method for {@link world.bentobox.parkour.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testTabCompleteUserStringListOfString10OptionsEmpty() { - assertTrue(cmd.tabComplete(user, "", List.of("ta")).get().isEmpty()); - Map map = new HashMap<>(); - map.put("tAsTyBeNtO1", location); - map.put("tAsTyBeNtO2", location); - map.put("tAsTyBeNtO3", location); - map.put("tAsTyBeNtO4", location); - map.put("tAsTyBeNtO5", location); - map.put("tAsTyBeNtO6", location); - map.put("tAsTyBeNtO7", location); - map.put("tAsTyBeNtO8", location); - map.put("tAsTyBeNtO9", location); - map.put("tAsTyBeNtO10", location); - when(parkourManager.getWarps()).thenReturn(map); - Optional> list = cmd.tabComplete(user, "", List.of()); - assertTrue(list.isEmpty()); - // Try again - list = cmd.tabComplete(user, "", List.of("tA")); - assertEquals(10, list.get().size()); - // Try again - list = cmd.tabComplete(user, "", List.of("p")); - assertTrue(list.get().isEmpty()); // Zero length list - - } + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + // Set warpspot + testCanExecuteArgMixedCase(); + // Run test + assertTrue(cmd.execute(user, "", List.of())); + verify(user).sendMessage("parkour.warp.warping"); + // Teleport user + verify(p, times(2)).playSound(location, Sound.ENTITY_BAT_TAKEOFF, 1F, 1F); + PowerMockito.verifyStatic(Util.class); + Util.teleportAsync(p, location, TeleportCause.COMMAND); + + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfString() { + assertTrue(cmd.tabComplete(user, "", List.of("ta")).get().isEmpty()); + when(parkourManager.getWarps()).thenReturn(Map.of("tAsTyBeNtO", location)); + List list = cmd.tabComplete(user, "", List.of("ta")).get(); + assertEquals("tAsTyBeNtO", list.get(0)); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfStringEmpty() { + assertTrue(cmd.tabComplete(user, "", List.of()).get().isEmpty()); + when(parkourManager.getWarps()).thenReturn(Map.of("tAsTyBeNtO", location)); + List list = cmd.tabComplete(user, "", List.of("ta")).get(); + assertEquals("tAsTyBeNtO", list.get(0)); + } + + /** + * Test method for + * {@link world.bentobox.parkour.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfString10OptionsEmpty() { + assertTrue(cmd.tabComplete(user, "", List.of("ta")).get().isEmpty()); + Map map = new HashMap<>(); + map.put("tAsTyBeNtO1", location); + map.put("tAsTyBeNtO2", location); + map.put("tAsTyBeNtO3", location); + map.put("tAsTyBeNtO4", location); + map.put("tAsTyBeNtO5", location); + map.put("tAsTyBeNtO6", location); + map.put("tAsTyBeNtO7", location); + map.put("tAsTyBeNtO8", location); + map.put("tAsTyBeNtO9", location); + map.put("tAsTyBeNtO10", location); + when(parkourManager.getWarps()).thenReturn(map); + Optional> list = cmd.tabComplete(user, "", List.of()); + assertTrue(list.isEmpty()); + // Try again + list = cmd.tabComplete(user, "", List.of("tA")); + assertEquals(10, list.get().size()); + // Try again + list = cmd.tabComplete(user, "", List.of("p")); + assertTrue(list.get().isEmpty()); // Zero length list + + } } diff --git a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java index f6d8e89..2241681 100644 --- a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java +++ b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java @@ -1,12 +1,26 @@ package world.bentobox.parkour.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.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.RETURNS_MOCKS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Optional; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.EntityEffect; import org.bukkit.GameMode; import org.bukkit.Location; @@ -29,19 +43,14 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.stubbing.Answer; 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 world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.events.island.IslandEnterEvent; import world.bentobox.bentobox.api.events.island.IslandExitEvent; @@ -49,188 +58,164 @@ import world.bentobox.bentobox.api.user.Notifier; 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.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; -import world.bentobox.parkour.Parkour; +import world.bentobox.parkour.AbstractParkourTest; import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.ParkourRunRecord; import world.bentobox.parkour.Settings; -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - /** * @author tastybento */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Util.class}) -public class CourseRunnerListenerTest { - - @Mock - private BentoBox plugin; - private User user; - @Mock - private LocalesManager lm; - @Mock - private Parkour addon; - private UUID uuid; - @Mock - private World world; - @Mock - private IslandsManager im; - @Mock - private @Nullable Island island; - @Mock - private IslandWorldManager iwm; - @Mock - private ParkourManager parkourManager; - - private CourseRunnerListener crl; - @Mock - private @NonNull Location location; - // Not mock - private ParkourRunRecord prm; - @Mock - private Player player; - @Mock - private PlaceholdersManager phm; - @Mock - private Notifier notifier; - @Mock - private Server server; - @Mock - private CompositeCommand cc; - @Mock - private Block block; - @Mock - private User u; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - // Set up plugin - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - - // Player - when(player.getWorld()).thenReturn(world); - uuid = UUID.randomUUID(); - when(player.getUniqueId()).thenReturn(uuid); - when(player.getName()).thenReturn("tastybento"); - when(player.getLocation()).thenReturn(location); - when(player.isOnline()).thenReturn(true); - when(player.hasPermission(anyString())).thenReturn(false); - when(player.getGameMode()).thenReturn(GameMode.SURVIVAL); - when(player.getServer()).thenReturn(server); - User.setPlugin(plugin); - user = User.getInstance(player); - - // Mock user u - when(u.getUniqueId()).thenReturn(uuid); - when(u.getPlayer()).thenReturn(player); - when(u.getTranslationOrNothing(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - - // Islands - when(plugin.getIslands()).thenReturn(im); - when(addon.getIslands()).thenReturn(im); - when(im.getIsland(world, user)).thenReturn(island); - when(im.getIslandAt(location)).thenReturn(Optional.of(island)); - when(im.getProtectedIslandAt(location)).thenReturn(Optional.of(island)); - when(im.hasIsland(world, user)).thenReturn(true); - when(im.inTeam(world, uuid)).thenReturn(true); - when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); - when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); - when(island.getWorld()).thenReturn(world); - when(im.userIsOnIsland(any(), any())).thenReturn(true); - - // Parkour Manager - // No warp spot - when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); - when(addon.getParkourManager()).thenReturn(parkourManager); - - // Notifier - when(plugin.getNotifier()).thenReturn(notifier); - - // Locales Manager - when(plugin.getLocalesManager()).thenReturn(lm); - when(lm.get(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); - when(plugin.getPlaceholdersManager()).thenReturn(phm); - - // Command - List al = new ArrayList<>(); - al.add("parkour"); - al.add("pk"); - when(cc.getAliases()).thenReturn(al); - when(addon.getPlayerCommand()).thenReturn(Optional.of(cc)); - - // IWM - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); - when(iwm.inWorld(world)).thenReturn(true); // Always in world - - // Settings - Settings settings = new Settings(); - when(addon.getSettings()).thenReturn(settings); - - // Location - when(location.getWorld()).thenReturn(world); - when(location.toVector()).thenReturn(new Vector(0, 0, 0)); - when(location.clone()).thenReturn(location); - when(location.add(0.5, 0, 0.5)).thenReturn(location); - - // Run Manager and ParkourManager - prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); - when(addon.getParkourRunRecord()).thenReturn(prm); - when(addon.inWorld(location)).thenReturn(true); - when(addon.inWorld(world)).thenReturn(true); - when(addon.getParkourManager()).thenReturn(parkourManager); - when(parkourManager.getStart(island)).thenReturn(Optional.of(location)); - when(parkourManager.getEnd(island)).thenReturn(Optional.of(location)); - - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // Block - when(block.getType()).thenReturn(Material.LIGHT_WEIGHTED_PRESSURE_PLATE); - when(block.getLocation()).thenReturn(location); - - // DUT - crl = new CourseRunnerListener(addon); - } - - @After - public void tearDown() { - User.clearUsers(); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#CourseRunnerListener(world.bentobox.parkour.Parkour)}. - */ - @Test - public void testCourseRunnerListener() { - assertNotNull(crl); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorArrive(world.bentobox.bentobox.api.events.island.IslandEnterEvent)}. - */ - @Test - public void testOnVisitorArrive() { - IslandEnterEvent e = new IslandEnterEvent(island, uuid, false, location, island, null); - crl.onVisitorArrive(e); - verify(notifier).notify(any(), eq("parkour.to-start")); - verify(player).setGameMode(GameMode.CREATIVE); - } - - /** +public class CourseRunnerListenerTest extends AbstractParkourTest { + private User user; + @Mock + private LocalesManager lm; + private UUID uuid; + @Mock + private World world; + @Mock + private ParkourManager parkourManager; + + private CourseRunnerListener crl; + @Mock + private @NonNull Location location; + // Not mock + private ParkourRunRecord prm; + @Mock + private Player player; + @Mock + private PlaceholdersManager phm; + @Mock + private Notifier notifier; + @Mock + private Server server; + @Mock + private CompositeCommand cc; + @Mock + private Block block; + @Mock + private User u; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + super.setUp(); + + // Player + when(player.getWorld()).thenReturn(world); + uuid = UUID.randomUUID(); + when(player.getUniqueId()).thenReturn(uuid); + when(player.getName()).thenReturn("tastybento"); + when(player.getLocation()).thenReturn(location); + when(player.isOnline()).thenReturn(true); + when(player.hasPermission(anyString())).thenReturn(false); + when(player.getGameMode()).thenReturn(GameMode.SURVIVAL); + when(player.getServer()).thenReturn(server); + User.setPlugin(plugin); + user = User.getInstance(player); + + // Mock user u + when(u.getUniqueId()).thenReturn(uuid); + when(u.getPlayer()).thenReturn(player); + when(u.getTranslationOrNothing(anyString())) + .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + + // Islands + when(plugin.getIslands()).thenReturn(im); + when(addon.getIslands()).thenReturn(im); + when(im.getIsland(world, user)).thenReturn(island); + when(im.getIslandAt(location)).thenReturn(Optional.of(island)); + when(im.getProtectedIslandAt(location)).thenReturn(Optional.of(island)); + when(im.hasIsland(world, user)).thenReturn(true); + when(im.inTeam(world, uuid)).thenReturn(true); + when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); + when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); + when(island.getWorld()).thenReturn(world); + when(im.userIsOnIsland(any(), any())).thenReturn(true); + + // Parkour Manager + // No warp spot + when(parkourManager.getWarpSpot(island)).thenReturn(Optional.empty()); + when(addon.getParkourManager()).thenReturn(parkourManager); + + // Notifier + when(plugin.getNotifier()).thenReturn(notifier); + + // Locales Manager + when(plugin.getLocalesManager()).thenReturn(lm); + when(lm.get(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + when(phm.replacePlaceholders(any(), any())) + .thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + when(plugin.getPlaceholdersManager()).thenReturn(phm); + + // Command + List al = new ArrayList<>(); + al.add("parkour"); + al.add("pk"); + when(cc.getAliases()).thenReturn(al); + when(addon.getPlayerCommand()).thenReturn(Optional.of(cc)); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("parkour."); + when(iwm.inWorld(world)).thenReturn(true); // Always in world + + // Settings + Settings settings = new Settings(); + when(addon.getSettings()).thenReturn(settings); + + // Location + when(location.getWorld()).thenReturn(world); + when(location.toVector()).thenReturn(new Vector(0, 0, 0)); + when(location.clone()).thenReturn(location); + when(location.add(0.5, 0, 0.5)).thenReturn(location); + + // Run Manager and ParkourManager + prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>()); + when(addon.getParkourRunRecord()).thenReturn(prm); + when(addon.inWorld(location)).thenReturn(true); + when(addon.inWorld(world)).thenReturn(true); + when(addon.getParkourManager()).thenReturn(parkourManager); + when(parkourManager.getStart(island)).thenReturn(Optional.of(location)); + when(parkourManager.getEnd(island)).thenReturn(Optional.of(location)); + + // Block + when(block.getType()).thenReturn(Material.LIGHT_WEIGHTED_PRESSURE_PLATE); + when(block.getLocation()).thenReturn(location); + + // DUT + crl = new CourseRunnerListener(addon); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#CourseRunnerListener(world.bentobox.parkour.Parkour)}. + */ + @Test + public void testCourseRunnerListener() { + assertNotNull(crl); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorArrive(world.bentobox.bentobox.api.events.island.IslandEnterEvent)}. + */ + @Test + public void testOnVisitorArrive() { + IslandEnterEvent e = new IslandEnterEvent(island, uuid, false, location, island, null); + crl.onVisitorArrive(e); + verify(notifier).notify(any(), eq("parkour.to-start")); + verify(player).setGameMode(GameMode.CREATIVE); + } + + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorArrive(world.bentobox.bentobox.api.events.island.IslandEnterEvent)}. */ @Test @@ -242,30 +227,32 @@ public void testOnVisitorArriveOtherGame() { verify(player, never()).setGameMode(GameMode.CREATIVE); } - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorArrive(world.bentobox.bentobox.api.events.island.IslandEnterEvent)}. - */ - @Test - public void testOnVisitorArriveInRace() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - prm.checkpoints().put(uuid, location); - IslandEnterEvent e = new IslandEnterEvent(island, uuid, false, location, island, null); - crl.onVisitorArrive(e); - verify(notifier, never()).notify(any(), eq("parkour.to-start")); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorLeave(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. - */ - @Test - public void testOnVisitorLeave() { - prm.checkpoints().put(uuid, location); - IslandExitEvent e = new IslandExitEvent(island, uuid, false, location, island, null); - crl.onVisitorLeave(e); - verify(notifier).notify(any(), eq("parkour.session-ended")); - } - - /** + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorArrive(world.bentobox.bentobox.api.events.island.IslandEnterEvent)}. + */ + @Test + public void testOnVisitorArriveInRace() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + prm.checkpoints().put(uuid, location); + IslandEnterEvent e = new IslandEnterEvent(island, uuid, false, location, island, null); + crl.onVisitorArrive(e); + verify(notifier, never()).notify(any(), eq("parkour.to-start")); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorLeave(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. + */ + @Test + public void testOnVisitorLeave() { + prm.checkpoints().put(uuid, location); + IslandExitEvent e = new IslandExitEvent(island, uuid, false, location, island, null); + crl.onVisitorLeave(e); + verify(notifier).notify(any(), eq("parkour.session-ended")); + } + + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorLeave(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test @@ -277,148 +264,160 @@ public void testOnVisitorLeaveOffline() { verify(notifier, never()).notify(any(), eq("parkour.session-ended")); } - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorLeave(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. - */ - @Test - public void testOnVisitorLeaveNotRuning() { - IslandExitEvent e = new IslandExitEvent(island, uuid, false, location, island, null); - crl.onVisitorLeave(e); - verify(notifier, never()).notify(any(), eq("parkour.session-ended")); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onPlayerDeath(org.bukkit.event.entity.PlayerDeathEvent)}. - */ - @Test - public void testOnPlayerDeath() { - PlayerDeathEvent e = new PlayerDeathEvent(player, new ArrayList<>(), 0, 0, 0, 0, ""); - crl.onPlayerDeath(e); - assertFalse(prm.timers().containsKey(uuid)); - assertFalse(prm.checkpoints().containsKey(uuid)); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. - */ - @Test - public void testOnPlayerQuit() { - PlayerQuitEvent e = new PlayerQuitEvent(player, ""); - crl.onPlayerQuit(e); - assertFalse(prm.timers().containsKey(uuid)); - assertFalse(prm.checkpoints().containsKey(uuid)); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. - */ - @Test - public void testOnVisitorFall() { - PowerMockito.mockStatic(Util.class, RETURNS_MOCKS); - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - prm.checkpoints().put(uuid, location); - EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); - crl.onVisitorFall(e); - verify(player).playEffect(EntityEffect.ENTITY_POOF); - verify(player).setVelocity(new Vector(0, 0, 0)); - verify(player).setFallDistance(0); - PowerMockito.verifyStatic(Util.class); - Util.teleportAsync(player, location, PlayerTeleportEvent.TeleportCause.PLUGIN); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. - */ - @Test - public void testOnVisitorFallNotVoid() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - prm.checkpoints().put(uuid, location); - EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.BLOCK_EXPLOSION, 1D); - crl.onVisitorFall(e); - verify(player, never()).playEffect(EntityEffect.ENTITY_POOF); - verify(player, never()).setVelocity(new Vector(0, 0, 0)); - verify(player, never()).setFallDistance(0); - verify(player, never()).teleport(location); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. - */ - @Test - public void testOnVisitorFallNotRunning() { - EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); - crl.onVisitorFall(e); - verify(player, never()).playEffect(EntityEffect.ENTITY_POOF); - verify(player, never()).setVelocity(new Vector(0, 0, 0)); - verify(player, never()).setFallDistance(0); - verify(player, never()).teleport(location); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. - */ - @Test - public void testOnVisitorFallNotPlayer() { - Creeper creeper = mock(Creeper.class); - EntityDamageEvent e = new EntityDamageEvent(creeper, DamageCause.VOID, 1D); - crl.onVisitorFall(e); - verify(creeper, never()).playEffect(EntityEffect.ENTITY_POOF); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. - */ - @Test - public void testOnVisitorCommand() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/island"); - crl.onVisitorCommand(e); - assertTrue(e.isCancelled()); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. - */ - @Test - public void testOnVisitorCommandNotRunning() { - PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/island"); - crl.onVisitorCommand(e); - assertFalse(e.isCancelled()); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. - */ - @Test - public void testOnVisitorCommandQuitting() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/pk quit"); - crl.onVisitorCommand(e); - assertFalse(e.isCancelled()); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. - */ - @Test - public void testOnVisitorCommandQuittingParkour() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/parkour quit"); - crl.onVisitorCommand(e); - assertFalse(e.isCancelled()); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onStartEndSet(org.bukkit.event.player.PlayerInteractEvent)}. - */ - @Test - public void testOnStartEndSet() { - PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); - crl.onStartEndSet(e); - verify(player).sendMessage("parkour.start"); - } - - /** + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorLeave(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. + */ + @Test + public void testOnVisitorLeaveNotRuning() { + IslandExitEvent e = new IslandExitEvent(island, uuid, false, location, island, null); + crl.onVisitorLeave(e); + verify(notifier, never()).notify(any(), eq("parkour.session-ended")); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onPlayerDeath(org.bukkit.event.entity.PlayerDeathEvent)}. + */ + @Test + public void testOnPlayerDeath() { + PlayerDeathEvent e = new PlayerDeathEvent(player, new ArrayList<>(), 0, 0, 0, 0, ""); + crl.onPlayerDeath(e); + assertFalse(prm.timers().containsKey(uuid)); + assertFalse(prm.checkpoints().containsKey(uuid)); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. + */ + @Test + public void testOnPlayerQuit() { + PlayerQuitEvent e = new PlayerQuitEvent(player, ""); + crl.onPlayerQuit(e); + assertFalse(prm.timers().containsKey(uuid)); + assertFalse(prm.checkpoints().containsKey(uuid)); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. + */ + @Test + public void testOnVisitorFall() { + PowerMockito.mockStatic(Util.class, RETURNS_MOCKS); + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + prm.checkpoints().put(uuid, location); + EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); + crl.onVisitorFall(e); + verify(player).playEffect(EntityEffect.ENTITY_POOF); + verify(player).setVelocity(new Vector(0, 0, 0)); + verify(player).setFallDistance(0); + PowerMockito.verifyStatic(Util.class); + Util.teleportAsync(player, location, PlayerTeleportEvent.TeleportCause.PLUGIN); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. + */ + @Test + public void testOnVisitorFallNotVoid() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + prm.checkpoints().put(uuid, location); + EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.BLOCK_EXPLOSION, 1D); + crl.onVisitorFall(e); + verify(player, never()).playEffect(EntityEffect.ENTITY_POOF); + verify(player, never()).setVelocity(new Vector(0, 0, 0)); + verify(player, never()).setFallDistance(0); + verify(player, never()).teleport(location); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. + */ + @Test + public void testOnVisitorFallNotRunning() { + EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); + crl.onVisitorFall(e); + verify(player, never()).playEffect(EntityEffect.ENTITY_POOF); + verify(player, never()).setVelocity(new Vector(0, 0, 0)); + verify(player, never()).setFallDistance(0); + verify(player, never()).teleport(location); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorFall(org.bukkit.event.entity.EntityDamageEvent)}. + */ + @Test + public void testOnVisitorFallNotPlayer() { + Creeper creeper = mock(Creeper.class); + EntityDamageEvent e = new EntityDamageEvent(creeper, DamageCause.VOID, 1D); + crl.onVisitorFall(e); + verify(creeper, never()).playEffect(EntityEffect.ENTITY_POOF); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. + */ + @Test + public void testOnVisitorCommand() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/island"); + crl.onVisitorCommand(e); + assertTrue(e.isCancelled()); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. + */ + @Test + public void testOnVisitorCommandNotRunning() { + PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/island"); + crl.onVisitorCommand(e); + assertFalse(e.isCancelled()); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. + */ + @Test + public void testOnVisitorCommandQuitting() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/pk quit"); + crl.onVisitorCommand(e); + assertFalse(e.isCancelled()); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onVisitorCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent)}. + */ + @Test + public void testOnVisitorCommandQuittingParkour() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent(player, "/parkour quit"); + crl.onVisitorCommand(e); + assertFalse(e.isCancelled()); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onStartEndSet(org.bukkit.event.player.PlayerInteractEvent)}. + */ + @Test + public void testOnStartEndSet() { + PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); + crl.onStartEndSet(e); + verify(player).sendMessage("parkour.start"); + } + + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onStartEndSet(org.bukkit.event.player.PlayerInteractEvent)}. */ @Test @@ -429,55 +428,57 @@ public void testOnStartEndSetNoEnd() { verify(player).sendMessage("parkour.set-the-end"); } - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onStartEndSet(org.bukkit.event.player.PlayerInteractEvent)}. - */ - @Test - public void testOnStartEndSetRaceOver() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - Location l = mock(Location.class); - when(l.getWorld()).thenReturn(world); - when(l.getBlockX()).thenReturn(20); - when(this.parkourManager.getStart(island)).thenReturn(Optional.of(l)); - PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); - crl.onStartEndSet(e); - verify(player).playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#parkourStart(User, Location)}. - */ - @Test - public void testParkourStart() { - crl.parkourStart(u, location); - verify(u).sendMessage("parkour.start"); - verify(player).playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); - verify(u).setGameMode(GameMode.SURVIVAL); - - assertTrue(prm.checkpoints().containsKey(uuid)); - assertTrue(prm.timers().containsKey(uuid)); - - } - - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#parkourEnd(User, Island, Location)}. - */ - @Test - public void testParkourEnd() { - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - - crl.parkourEnd(u, island, location); - verify(u).notify("parkour.end"); - verify(player).playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); - verify(u).notify(eq("parkour.you-took"), eq(TextVariables.NUMBER), contains("parkour.seconds")); - verify(u).sendMessage("parkour.top.beat-previous-time"); - verify(parkourManager).addScore(eq(island), eq(u), anyLong()); - verify(u).sendMessage("parkour.top.your-rank", TextVariables.NUMBER, "0"); - verify(u).setGameMode(GameMode.CREATIVE); - } - - /** + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onStartEndSet(org.bukkit.event.player.PlayerInteractEvent)}. + */ + @Test + public void testOnStartEndSetRaceOver() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + Location l = mock(Location.class); + when(l.getWorld()).thenReturn(world); + when(l.getBlockX()).thenReturn(20); + when(this.parkourManager.getStart(island)).thenReturn(Optional.of(l)); + PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); + crl.onStartEndSet(e); + verify(player).playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#parkourStart(User, Location)}. + */ + @Test + public void testParkourStart() { + crl.parkourStart(u, location); + verify(u).sendMessage("parkour.start"); + verify(player).playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); + verify(u).setGameMode(GameMode.SURVIVAL); + + assertTrue(prm.checkpoints().containsKey(uuid)); + assertTrue(prm.timers().containsKey(uuid)); + + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#parkourEnd(User, Island, Location)}. + */ + @Test + public void testParkourEnd() { + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + + crl.parkourEnd(u, island, location); + verify(u).notify("parkour.end"); + verify(player).playSound(location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F); + verify(u).notify(eq("parkour.you-took"), eq(TextVariables.NUMBER), contains("parkour.seconds")); + verify(u).sendMessage("parkour.top.beat-previous-time"); + verify(parkourManager).addScore(eq(island), eq(u), anyLong()); + verify(u).sendMessage("parkour.top.your-rank", TextVariables.NUMBER, "0"); + verify(u).setGameMode(GameMode.CREATIVE); + } + + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#parkourEnd(User, Island, Location)}. */ @Test @@ -490,7 +491,7 @@ public void testParkourEndLongerTime() { verify(u).sendMessage("parkour.top.did-not-beat-previous-time"); } - /** + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#parkourEnd(User, Island, Location)}. */ @Test @@ -503,121 +504,126 @@ public void testParkourEndNoCreative() { verify(u, never()).setGameMode(GameMode.CREATIVE); } - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onCheckpoint(org.bukkit.event.player.PlayerInteractEvent)}. - */ - @Test - public void testOnCheckpointNotPhysical() { - PlayerInteractEvent e = new PlayerInteractEvent(player, Action.LEFT_CLICK_AIR, null, block, BlockFace.DOWN); - crl.onCheckpoint(e); - verify(block, never()).getLocation(); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onCheckpoint(org.bukkit.event.player.PlayerInteractEvent)}. - */ - @Test - public void testOnCheckpointInitialChecks() { - Location l = mock(Location.class); - when(l.toVector()).thenReturn(new Vector(100, 0, 20)); // Different to location - prm.checkpoints().put(uuid, l); - - when(block.getType()).thenReturn(Material.STONE); - - when(iwm.inWorld(location)).thenReturn(false); - - - PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); - crl.onCheckpoint(e); - verify(block, never()).getLocation(); - - when(iwm.inWorld(location)).thenReturn(true); - crl.onCheckpoint(e); - verify(block, never()).getLocation(); - - when(block.getType()).thenReturn(Material.POLISHED_BLACKSTONE_PRESSURE_PLATE); - crl.onCheckpoint(e); - verify(block, never()).getLocation(); - - prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago - crl.onCheckpoint(e); - verify(block).getLocation(); - - // Checkpoint reached! - verify(player).playSound(location, Sound.BLOCK_BELL_USE, 1F, 1F); - - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. - */ - @Test - public void testOnTeleport() { - // Player is running - for (TeleportCause cause : TeleportCause.values()) { - // Reset the maps - prm.checkpoints().clear(); - prm.timers().clear(); - prm.checkpoints().put(uuid, location); - prm.timers().put(uuid, 20L); - // Make the event - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, location, cause); - // Fire event - crl.onTeleport(e); - } - // Should fire 5 times: COMMAND, PLUGIN, SPECTATE, END_GATEWAY, UNKNOWN - verify(notifier, times(5)).notify(any(), eq("parkour.session-ended")); - // Should happen just 3 times: COMMAND, PLUGIN, UNKNOWN - verify(player, times(3)).setGameMode(GameMode.CREATIVE); - verify(player, never()).setGameMode(GameMode.SURVIVAL); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. - */ - @Test - public void testOnTeleportNoFlagActionNullTo() { - // Make the event - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, null, TeleportCause.ENDER_PEARL); - // Fire event - crl.onTeleport(e); - verify(player, never()).setGameMode(GameMode.CREATIVE); - verify(player, never()).setGameMode(GameMode.SURVIVAL); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. - */ - @Test - public void testOnTeleportToNoFlagActionNotInParkourWorld() { - // Make the event - Location l = mock(Location.class); - when(l.getWorld()).thenReturn(mock(World.class)); - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.PLUGIN); - // Fire event - crl.onTeleport(e); - verify(player, never()).setGameMode(GameMode.CREATIVE); - verify(player, never()).setGameMode(GameMode.SURVIVAL); - } - - /** - * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. - */ - @Test - public void testOnTeleportToNoFlagActionDifferentIsland() { - // Make the event - Location l = mock(Location.class); - when(l.getWorld()).thenReturn(world); - Island i = mock(Island.class); - when(im.getIslandAt(l)).thenReturn(Optional.of(i)); - PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.PLUGIN); - // Fire event - crl.onTeleport(e); - verify(player, never()).setGameMode(GameMode.CREATIVE); - verify(player, never()).setGameMode(GameMode.SURVIVAL); - } - - /** + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onCheckpoint(org.bukkit.event.player.PlayerInteractEvent)}. + */ + @Test + public void testOnCheckpointNotPhysical() { + PlayerInteractEvent e = new PlayerInteractEvent(player, Action.LEFT_CLICK_AIR, null, block, BlockFace.DOWN); + crl.onCheckpoint(e); + verify(block, never()).getLocation(); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onCheckpoint(org.bukkit.event.player.PlayerInteractEvent)}. + */ + @Test + public void testOnCheckpointInitialChecks() { + Location l = mock(Location.class); + when(l.toVector()).thenReturn(new Vector(100, 0, 20)); // Different to location + prm.checkpoints().put(uuid, l); + + when(block.getType()).thenReturn(Material.STONE); + + when(iwm.inWorld(location)).thenReturn(false); + + PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); + crl.onCheckpoint(e); + verify(block, never()).getLocation(); + + when(iwm.inWorld(location)).thenReturn(true); + crl.onCheckpoint(e); + verify(block, never()).getLocation(); + + when(block.getType()).thenReturn(Material.POLISHED_BLACKSTONE_PRESSURE_PLATE); + crl.onCheckpoint(e); + verify(block, never()).getLocation(); + + prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago + crl.onCheckpoint(e); + verify(block).getLocation(); + + // Checkpoint reached! + verify(player).playSound(location, Sound.BLOCK_BELL_USE, 1F, 1F); + + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. + */ + @Test + public void testOnTeleport() { + // Player is running + for (TeleportCause cause : TeleportCause.values()) { + // Reset the maps + prm.checkpoints().clear(); + prm.timers().clear(); + prm.checkpoints().put(uuid, location); + prm.timers().put(uuid, 20L); + // Make the event + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, location, cause); + // Fire event + crl.onTeleport(e); + } + // Should fire 5 times: COMMAND, PLUGIN, SPECTATE, END_GATEWAY, UNKNOWN + verify(notifier, times(5)).notify(any(), eq("parkour.session-ended")); + // Should happen just 3 times: COMMAND, PLUGIN, UNKNOWN + verify(player, times(3)).setGameMode(GameMode.CREATIVE); + verify(player, never()).setGameMode(GameMode.SURVIVAL); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. + */ + @Test + public void testOnTeleportNoFlagActionNullTo() { + // Make the event + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, null, TeleportCause.ENDER_PEARL); + // Fire event + crl.onTeleport(e); + verify(player, never()).setGameMode(GameMode.CREATIVE); + verify(player, never()).setGameMode(GameMode.SURVIVAL); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. + */ + @Test + public void testOnTeleportToNoFlagActionNotInParkourWorld() { + // Make the event + Location l = mock(Location.class); + when(l.getWorld()).thenReturn(mock(World.class)); + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.PLUGIN); + // Fire event + crl.onTeleport(e); + verify(player, never()).setGameMode(GameMode.CREATIVE); + verify(player, never()).setGameMode(GameMode.SURVIVAL); + } + + /** + * Test method for + * {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. + */ + @Test + public void testOnTeleportToNoFlagActionDifferentIsland() { + // Make the event + Location l = mock(Location.class); + when(l.getWorld()).thenReturn(world); + Island i = mock(Island.class); + when(im.getIslandAt(l)).thenReturn(Optional.of(i)); + PlayerTeleportEvent e = new PlayerTeleportEvent(player, location, l, TeleportCause.PLUGIN); + // Fire event + crl.onTeleport(e); + verify(player, never()).setGameMode(GameMode.CREATIVE); + verify(player, never()).setGameMode(GameMode.SURVIVAL); + } + + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. */ @Test @@ -634,7 +640,7 @@ public void testOnTeleportToFlagActionVisitors() { verify(player).setGameMode(GameMode.SURVIVAL); } - /** + /** * Test method for {@link world.bentobox.parkour.listeners.CourseRunnerListener#onTeleport(org.bukkit.event.player.PlayerTeleportEvent)}. */ @Test @@ -651,5 +657,4 @@ public void testOnTeleportToFlagActionVisitorsChorusFruit() { verify(player, never()).setGameMode(GameMode.SURVIVAL); } - } From eab215b24484cf64a7f991d7f32e54bbafde2a52 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 18 Aug 2024 16:26:08 -0700 Subject: [PATCH 08/13] Bring up to latest API and fix tests --- .../bentobox/parkour/commands/ClearTopCommand.java | 3 ++- .../bentobox/parkour/commands/SetWarpCommand.java | 4 +++- src/main/resources/addon.yml | 2 +- .../world/bentobox/parkour/AbstractParkourTest.java | 10 ++++++---- .../bentobox/parkour/commands/ClearTopCommandTest.java | 9 +++++---- .../bentobox/parkour/commands/SetWarpCommandTest.java | 9 +++++++-- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/commands/ClearTopCommand.java b/src/main/java/world/bentobox/parkour/commands/ClearTopCommand.java index 4ecb899..53b2afc 100644 --- a/src/main/java/world/bentobox/parkour/commands/ClearTopCommand.java +++ b/src/main/java/world/bentobox/parkour/commands/ClearTopCommand.java @@ -61,7 +61,8 @@ public boolean canExecute(User user, String label, List args) { Island island = getIslands().getIsland(getWorld(), user); int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Check the name of the score to clear diff --git a/src/main/java/world/bentobox/parkour/commands/SetWarpCommand.java b/src/main/java/world/bentobox/parkour/commands/SetWarpCommand.java index e2ce851..c3bb71b 100644 --- a/src/main/java/world/bentobox/parkour/commands/SetWarpCommand.java +++ b/src/main/java/world/bentobox/parkour/commands/SetWarpCommand.java @@ -10,6 +10,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.parkour.Parkour; import world.bentobox.parkour.ParkourManager; @@ -46,7 +47,8 @@ public boolean canExecute(User user, String label, List args) { Island island = getIslands().getIsland(getWorld(), user); int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } Optional start = ((Parkour) getAddon()).getParkourManager().getStart(island); diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index 225b32e..df83b72 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -1,7 +1,7 @@ name: Parkour main: world.bentobox.parkour.Parkour version: ${version}${build.number} -api-version: 1.24 +api-version: 2.4.0 metrics: true icon: "POLISHED_BLACKSTONE_PRESSURE_PLATE" repository: "BentoBoxWorld/Parkour" diff --git a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java index 06ef296..90ac0da 100644 --- a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java +++ b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java @@ -55,7 +55,8 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Config.class, DatabaseSetup.class, Util.class }) +@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Config.class, DatabaseSetup.class, Util.class, + RanksManager.class }) public abstract class AbstractParkourTest { @Mock @@ -76,6 +77,8 @@ public abstract class AbstractParkourTest { protected IslandWorldManager iwm; @Mock protected Parkour addon; + @Mock + private RanksManager rm; protected static AbstractDatabaseHandler h; @SuppressWarnings("unchecked") @@ -170,9 +173,8 @@ public void setUp() throws Exception { when(fm.getFlags()).thenReturn(Collections.emptyList()); // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - + Whitebox.setInternalState(RanksManager.class, "instance", rm); + when(rm.getRank(any())).thenReturn("ranks.member"); } } diff --git a/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java b/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java index ee94bd7..d01d036 100644 --- a/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java @@ -56,7 +56,7 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Util.class}) +@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Util.class, RanksManager.class }) public class ClearTopCommandTest { @Mock @@ -88,6 +88,8 @@ public class ClearTopCommandTest { private RankingsUI rankings; @Mock private PlayersManager pm; + @Mock + private RanksManager rm; /** * @throws java.lang.Exception @@ -155,8 +157,7 @@ public void setUp() throws Exception { when(addon.getSettings()).thenReturn(settings); // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); + Whitebox.setInternalState(RanksManager.class, "instance", rm); // Players Manager when(addon.getPlayers()).thenReturn(pm); @@ -217,7 +218,7 @@ public void testCanExecuteNoIsland() { public void testCanExecuteInsufficientRank() { when(island.getRankCommand(anyString())).thenReturn(RanksManager.ADMIN_RANK); assertFalse(cmd.canExecute(user, "", List.of())); - verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, RanksManager.MEMBER_RANK_REF); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, null); } diff --git a/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java b/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java index fb5b102..8a4ca3c 100644 --- a/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java @@ -24,7 +24,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; @@ -43,6 +45,7 @@ * */ @RunWith(PowerMockRunner.class) +@PrepareForTest(RanksManager.class) public class SetWarpCommandTest extends AbstractParkourTest { @Mock private LocalesManager lm; @@ -56,6 +59,8 @@ public class SetWarpCommandTest extends AbstractParkourTest { private Location location; @Mock private CompositeCommand ac; + @Mock + private RanksManager rm; /** * @throws java.lang.Exception @@ -112,8 +117,8 @@ public void setUp() throws Exception { when(addon.getSettings()).thenReturn(settings); // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); + Whitebox.setInternalState(RanksManager.class, "instance", rm); + when(rm.getRank(any())).thenReturn("ranks.member"); // DUT cmd = new SetWarpCommand(ac); From 97f9f44a002f8f6d36c65559db63fb49bf14b76c Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 18 Aug 2024 16:38:36 -0700 Subject: [PATCH 09/13] Added settings and updated to 1.21. --- pom.xml | 4 +- .../java/world/bentobox/parkour/Settings.java | 38 +++++++++++++++++++ .../bentobox/parkour/gui/CoursesTab.java | 19 +++++----- .../listeners/CourseRunnerListenerTest.java | 7 +++- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index c858c0e..6fa4abe 100644 --- a/pom.xml +++ b/pom.xml @@ -58,11 +58,11 @@ 2.0.9 - 1.20.1-R0.1-SNAPSHOT + 1.21-R0.1-SNAPSHOT 1.20.1-R0.1-SNAPSHOT - 2.0.0-SNAPSHOT + 2.5.0-SNAPSHOT ${build.version}-SNAPSHOT diff --git a/src/main/java/world/bentobox/parkour/Settings.java b/src/main/java/world/bentobox/parkour/Settings.java index 6d14156..5a7cfe5 100644 --- a/src/main/java/world/bentobox/parkour/Settings.java +++ b/src/main/java/world/bentobox/parkour/Settings.java @@ -138,6 +138,15 @@ public class Settings implements WorldSettings { @ConfigEntry(path = "world.max-areas") private int maxIslands = -1; + @ConfigComment("The number of concurrent areas a player can have") + @ConfigComment("A value of 0 will use the BentoBox config.yml default") + @ConfigEntry(path = "world.concurrent-area") + private int concurrentIslands = 0; + + @ConfigComment("Disallow team members from having their own area.") + @ConfigEntry(path = "world.disallow-team-member-areas") + private boolean disallowTeamMemberIslands = true; + @ConfigComment("The default game mode for this world. Players will be set to this mode when they create") @ConfigComment("a new area for example. Options are SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR") @ConfigEntry(path = "world.default-game-mode") @@ -1721,4 +1730,33 @@ public Biome getDefaultEndBiome() { public void setDefaultEndBiome(Biome defaultEndBiome) { this.defaultEndBiome = defaultEndBiome; } + + /** + * @return the concurrentIslands + */ + @Override + public int getConcurrentIslands() { + return concurrentIslands; + } + + /** + * @param concurrentIslands the concurrentIslands to set + */ + public void setConcurrentIslands(int concurrentIslands) { + this.concurrentIslands = concurrentIslands; + } + + /** + * @return the disallowTeamMemberIslands + */ + public boolean isDisallowTeamMemberIslands() { + return disallowTeamMemberIslands; + } + + /** + * @param disallowTeamMemberIslands the disallowTeamMemberIslands to set + */ + public void setDisallowTeamMemberIslands(boolean disallowTeamMemberIslands) { + this.disallowTeamMemberIslands = disallowTeamMemberIslands; + } } diff --git a/src/main/java/world/bentobox/parkour/gui/CoursesTab.java b/src/main/java/world/bentobox/parkour/gui/CoursesTab.java index 38c46e6..b711460 100644 --- a/src/main/java/world/bentobox/parkour/gui/CoursesTab.java +++ b/src/main/java/world/bentobox/parkour/gui/CoursesTab.java @@ -83,10 +83,11 @@ public String getName() { .sorted() .filter(hs -> Objects.nonNull(hs.getWarpSpot())) .forEach(hs -> { - UUID owner = addon.getIslands().getIslandById(hs.getUniqueId()).map(Island::getOwner).orElse(null); - if (owner != null) { - heads.add(getHead(hs, owner)); - } + addon.getIslands().getIslandById(hs.getUniqueId()).ifPresent(is -> { + if (is.getOwner() != null) { + heads.add(getHead(hs, is)); + } + }); }); return heads; } @@ -95,18 +96,18 @@ public String getName() { * Get the head panel item * * @param pd - parkour data - * @param playerUUID - the UUID of the owner + * @param is.getOwner() - the UUID of the owner * @return PanelItem */ - private PanelItem getHead(ParkourData pd, UUID playerUUID) { - final String name = addon.getPlayers().getName(playerUUID); + private PanelItem getHead(ParkourData pd, Island is) { + final String name = addon.getPlayers().getName(is.getOwner()); List description = new ArrayList<>(); if (pd.getRunCount() > 0) { description.add(user.getTranslation("parkour.courses.head-description", "[name]", name, "[runs]", String.valueOf(pd.getRunCount()))); } - if (addon.getIslands().inTeam(addon.getOverWorld(), playerUUID)) { + if (addon.getIslands().inTeam(addon.getOverWorld(), is.getOwner())) { List memberList = new ArrayList<>(); - for (UUID members : addon.getIslands().getMembers(addon.getOverWorld(), playerUUID)) { + for (UUID members : is.getMemberSet()) { memberList.add(ChatColor.AQUA + addon.getPlayers().getName(members)); } description.addAll(memberList); diff --git a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java index 2241681..84caa9e 100644 --- a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java +++ b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java @@ -30,6 +30,8 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; import org.bukkit.entity.Creeper; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; @@ -281,7 +283,8 @@ public void testOnVisitorLeaveNotRuning() { */ @Test public void testOnPlayerDeath() { - PlayerDeathEvent e = new PlayerDeathEvent(player, new ArrayList<>(), 0, 0, 0, 0, ""); + PlayerDeathEvent e = new PlayerDeathEvent(player, DamageSource.builder(DamageType.ARROW).build(), + new ArrayList<>(), 0, 0, 0, 0, null); crl.onPlayerDeath(e); assertFalse(prm.timers().containsKey(uuid)); assertFalse(prm.checkpoints().containsKey(uuid)); @@ -308,7 +311,7 @@ public void testOnVisitorFall() { PowerMockito.mockStatic(Util.class, RETURNS_MOCKS); prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago prm.checkpoints().put(uuid, location); - EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); + EntityDamageEvent e = new EntityDamageEvent(player, null, null, null); crl.onVisitorFall(e); verify(player).playEffect(EntityEffect.ENTITY_POOF); verify(player).setVelocity(new Vector(0, 0, 0)); From 0d1696be09e1b27eede90048151e02c7b10b4700 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 20 Aug 2024 20:53:16 -0700 Subject: [PATCH 10/13] Fix concurrent islands limit --- src/main/java/world/bentobox/parkour/Settings.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/world/bentobox/parkour/Settings.java b/src/main/java/world/bentobox/parkour/Settings.java index 5a7cfe5..3919d14 100644 --- a/src/main/java/world/bentobox/parkour/Settings.java +++ b/src/main/java/world/bentobox/parkour/Settings.java @@ -14,6 +14,7 @@ import com.google.common.base.Enums; +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.configuration.ConfigComment; import world.bentobox.bentobox.api.configuration.ConfigEntry; import world.bentobox.bentobox.api.configuration.StoreAt; @@ -1736,6 +1737,9 @@ public void setDefaultEndBiome(Biome defaultEndBiome) { */ @Override public int getConcurrentIslands() { + if (concurrentIslands <= 0) { + return BentoBox.getInstance().getSettings().getIslandNumber(); + } return concurrentIslands; } From aa00b82db3f6818cf4ee756b917f309f9f8dde75 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 30 Aug 2024 14:54:02 -0700 Subject: [PATCH 11/13] Fix tests --- .../parkour/commands/RemoveWarpCommand.java | 3 ++- .../world/bentobox/parkour/AbstractParkourTest.java | 6 +----- .../parkour/commands/SetWarpCommandTest.java | 5 ----- .../parkour/listeners/CourseRunnerListenerTest.java | 13 +++++-------- 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/main/java/world/bentobox/parkour/commands/RemoveWarpCommand.java b/src/main/java/world/bentobox/parkour/commands/RemoveWarpCommand.java index a6ba496..b72c4da 100644 --- a/src/main/java/world/bentobox/parkour/commands/RemoveWarpCommand.java +++ b/src/main/java/world/bentobox/parkour/commands/RemoveWarpCommand.java @@ -7,6 +7,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.parkour.Parkour; import world.bentobox.parkour.ParkourManager; @@ -39,7 +40,7 @@ public boolean canExecute(User user, String label, List args) { // Check rank to use command int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } diff --git a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java index 90ac0da..d929ac3 100644 --- a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java +++ b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java @@ -55,8 +55,7 @@ * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Config.class, DatabaseSetup.class, Util.class, - RanksManager.class }) +@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Config.class, DatabaseSetup.class, Util.class }) public abstract class AbstractParkourTest { @Mock @@ -172,9 +171,6 @@ public void setUp() throws Exception { when(plugin.getFlagsManager()).thenReturn(fm); when(fm.getFlags()).thenReturn(Collections.emptyList()); - // RanksManager - Whitebox.setInternalState(RanksManager.class, "instance", rm); - when(rm.getRank(any())).thenReturn("ranks.member"); } } diff --git a/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java b/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java index 8a4ca3c..8dc45f4 100644 --- a/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/SetWarpCommandTest.java @@ -26,7 +26,6 @@ import org.mockito.Mock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.reflect.Whitebox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; @@ -116,10 +115,6 @@ public void setUp() throws Exception { Settings settings = new Settings(); when(addon.getSettings()).thenReturn(settings); - // RanksManager - Whitebox.setInternalState(RanksManager.class, "instance", rm); - when(rm.getRank(any())).thenReturn("ranks.member"); - // DUT cmd = new SetWarpCommand(ac); } diff --git a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java index 84caa9e..be2f56b 100644 --- a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java +++ b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java @@ -30,8 +30,6 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.damage.DamageSource; -import org.bukkit.damage.DamageType; import org.bukkit.entity.Creeper; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; @@ -283,8 +281,7 @@ public void testOnVisitorLeaveNotRuning() { */ @Test public void testOnPlayerDeath() { - PlayerDeathEvent e = new PlayerDeathEvent(player, DamageSource.builder(DamageType.ARROW).build(), - new ArrayList<>(), 0, 0, 0, 0, null); + PlayerDeathEvent e = new PlayerDeathEvent(player, null, null, 0, 0, 0, 0, null); crl.onPlayerDeath(e); assertFalse(prm.timers().containsKey(uuid)); assertFalse(prm.checkpoints().containsKey(uuid)); @@ -311,7 +308,7 @@ public void testOnVisitorFall() { PowerMockito.mockStatic(Util.class, RETURNS_MOCKS); prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago prm.checkpoints().put(uuid, location); - EntityDamageEvent e = new EntityDamageEvent(player, null, null, null); + EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, null, 0); crl.onVisitorFall(e); verify(player).playEffect(EntityEffect.ENTITY_POOF); verify(player).setVelocity(new Vector(0, 0, 0)); @@ -328,7 +325,7 @@ public void testOnVisitorFall() { public void testOnVisitorFallNotVoid() { prm.timers().put(uuid, System.currentTimeMillis() - 20000); // ~ 20 seconds ago prm.checkpoints().put(uuid, location); - EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.BLOCK_EXPLOSION, 1D); + EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.BLOCK_EXPLOSION, null, 0); crl.onVisitorFall(e); verify(player, never()).playEffect(EntityEffect.ENTITY_POOF); verify(player, never()).setVelocity(new Vector(0, 0, 0)); @@ -342,7 +339,7 @@ public void testOnVisitorFallNotVoid() { */ @Test public void testOnVisitorFallNotRunning() { - EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, 1D); + EntityDamageEvent e = new EntityDamageEvent(player, DamageCause.VOID, null, 1D); crl.onVisitorFall(e); verify(player, never()).playEffect(EntityEffect.ENTITY_POOF); verify(player, never()).setVelocity(new Vector(0, 0, 0)); @@ -357,7 +354,7 @@ public void testOnVisitorFallNotRunning() { @Test public void testOnVisitorFallNotPlayer() { Creeper creeper = mock(Creeper.class); - EntityDamageEvent e = new EntityDamageEvent(creeper, DamageCause.VOID, 1D); + EntityDamageEvent e = new EntityDamageEvent(creeper, DamageCause.VOID, null, 1D); crl.onVisitorFall(e); verify(creeper, never()).playEffect(EntityEffect.ENTITY_POOF); } From 88c6df391d098a9f0635957a1974cb3919fa6b7f Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 10 Nov 2024 14:55:40 -0800 Subject: [PATCH 12/13] Update CodeMC and MC 1.21.3 --- pom.xml | 22 +++++++++---------- .../java/world/bentobox/parkour/Settings.java | 2 +- src/main/resources/addon.yml | 2 +- src/main/resources/plugin.yml | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 6fa4abe..276e803 100644 --- a/pom.xml +++ b/pom.xml @@ -41,13 +41,9 @@ - - codemc-snapshots - https://repo.codemc.org/repository/maven-snapshots - - - codemc-releases - https://repo.codemc.org/repository/maven-releases + + bentoboxworld + https://repo.codemc.org/repository/bentoboxworld/ @@ -58,17 +54,17 @@ 2.0.9 - 1.21-R0.1-SNAPSHOT + 1.21.3-R0.1-SNAPSHOT - 1.20.1-R0.1-SNAPSHOT - 2.5.0-SNAPSHOT + 1.21.3-R0.1-SNAPSHOT + 2.7.1-SNAPSHOT ${build.version}-SNAPSHOT -LOCAL - 1.3.1 + 1.4.0 bentobox-world https://sonarcloud.io @@ -124,6 +120,10 @@ papermc https://repo.papermc.io/repository/maven-public/ + + bentoboxworld + https://repo.codemc.org/repository/bentoboxworld/ + codemc https://repo.codemc.org/repository/maven-snapshots/ diff --git a/src/main/java/world/bentobox/parkour/Settings.java b/src/main/java/world/bentobox/parkour/Settings.java index 3919d14..43d82f8 100644 --- a/src/main/java/world/bentobox/parkour/Settings.java +++ b/src/main/java/world/bentobox/parkour/Settings.java @@ -158,7 +158,7 @@ public class Settings implements WorldSettings { private Biome defaultBiome = Biome.PLAINS; @ConfigComment("The default biome for the nether world (this may affect what mobs can spawn)") @ConfigEntry(path = "world.default-nether-biome") - private Biome defaultNetherBiome = Enums.getIfPresent(Biome.class, "NETHER").or(Enums.getIfPresent(Biome.class, "NETHER_WASTES").or(Biome.BADLANDS)); + private Biome defaultNetherBiome = Biome.NETHER_WASTES; @ConfigComment("The default biome for the end world (this may affect what mobs can spawn)") @ConfigEntry(path = "world.default-end-biome") private Biome defaultEndBiome = Biome.THE_END; diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index df83b72..b2ecd55 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -1,7 +1,7 @@ name: Parkour main: world.bentobox.parkour.Parkour version: ${version}${build.number} -api-version: 2.4.0 +api-version: 2.7.1 metrics: true icon: "POLISHED_BLACKSTONE_PRESSURE_PLATE" repository: "BentoBoxWorld/Parkour" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 76abb7e..75f1ee7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: BentoBox-Parkour main: world.bentobox.parkour.ParkourPladdon version: ${project.version}${build.number} -api-version: "1.20" +api-version: "1.21" authors: [tastybento] contributors: ["The BentoBoxWorld Community"] From 41a6adedba5358ac01d5bbfa472eecfe2d56851c Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 10 Nov 2024 20:12:05 -0800 Subject: [PATCH 13/13] Fix tests --- .../bentobox/parkour/AbstractParkourTest.java | 4 +- .../bentobox/parkour/ParkourManagerTest.java | 4 + .../world/bentobox/parkour/SettingsTest.java | 21 +++- .../parkour/commands/ClearTopCommandTest.java | 18 ++- .../listeners/CourseRunnerListenerTest.java | 40 +++++- .../bentobox/parkour/mocks/ServerMocks.java | 118 ++++++++++++++++++ 6 files changed, 193 insertions(+), 12 deletions(-) create mode 100644 src/test/java/world/bentobox/parkour/mocks/ServerMocks.java diff --git a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java index d929ac3..9e0d134 100644 --- a/src/test/java/world/bentobox/parkour/AbstractParkourTest.java +++ b/src/test/java/world/bentobox/parkour/AbstractParkourTest.java @@ -49,6 +49,7 @@ import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; +import world.bentobox.parkour.mocks.ServerMocks; /** * @author tastybento @@ -96,6 +97,7 @@ public static void beforeClass() throws IllegalAccessException, InvocationTarget @After public void tearDown() throws IOException { + ServerMocks.unsetBukkitServer(); User.clearUsers(); Mockito.framework().clearInlineMocks(); deleteAll(new File("database")); @@ -117,6 +119,7 @@ protected void deleteAll(File file) throws IOException { */ @Before public void setUp() throws Exception { + Server server = ServerMocks.newServer(); // Set up plugin Whitebox.setInternalState(BentoBox.class, "instance", plugin); when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger()); @@ -158,7 +161,6 @@ public void setUp() throws Exception { // Server PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); - Server server = mock(Server.class); when(Bukkit.getServer()).thenReturn(server); when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class)); diff --git a/src/test/java/world/bentobox/parkour/ParkourManagerTest.java b/src/test/java/world/bentobox/parkour/ParkourManagerTest.java index 171b5c6..56b3c8e 100644 --- a/src/test/java/world/bentobox/parkour/ParkourManagerTest.java +++ b/src/test/java/world/bentobox/parkour/ParkourManagerTest.java @@ -47,6 +47,7 @@ import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.util.Util; +import world.bentobox.parkour.mocks.ServerMocks; import world.bentobox.parkour.objects.ParkourData; /** @@ -99,6 +100,8 @@ public static void beforeClass() throws IllegalAccessException, InvocationTarget @Before public void setUp() { + ServerMocks.newServer(); + when(addon.getPlugin()).thenReturn(plugin); // Set up plugin Whitebox.setInternalState(BentoBox.class, "instance", plugin); @@ -150,6 +153,7 @@ public void setUp() { */ @After public void tearDown() throws Exception { + ServerMocks.unsetBukkitServer(); deleteAll(new File("database")); User.clearUsers(); Mockito.framework().clearInlineMocks(); diff --git a/src/test/java/world/bentobox/parkour/SettingsTest.java b/src/test/java/world/bentobox/parkour/SettingsTest.java index 402dc03..5b95165 100644 --- a/src/test/java/world/bentobox/parkour/SettingsTest.java +++ b/src/test/java/world/bentobox/parkour/SettingsTest.java @@ -3,26 +3,36 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; import java.util.Collections; import java.util.List; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.Difficulty; import org.bukkit.GameMode; +import org.bukkit.Server; import org.bukkit.block.Biome; import org.bukkit.entity.EntityType; import org.junit.After; 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 world.bentobox.bentobox.api.user.User; +import world.bentobox.parkour.mocks.ServerMocks; + /** * @author tastybento * */ @RunWith(PowerMockRunner.class) +@PrepareForTest(Bukkit.class) public class SettingsTest { private Settings s; @@ -32,14 +42,17 @@ public class SettingsTest { */ @Before public void setUp() throws Exception { + Server server = ServerMocks.newServer(); + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); + when(Bukkit.getServer()).thenReturn(server); s = new Settings(); } - /** - * @throws java.lang.Exception - */ @After - public void tearDown() throws Exception { + public void tearDown() { + ServerMocks.unsetBukkitServer(); + User.clearUsers(); + Mockito.framework().clearInlineMocks(); } /** diff --git a/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java b/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java index d01d036..0a23d2e 100644 --- a/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java +++ b/src/test/java/world/bentobox/parkour/commands/ClearTopCommandTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertEquals; 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.anyInt; @@ -24,6 +25,7 @@ import org.bukkit.entity.Player; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,6 +52,7 @@ import world.bentobox.parkour.ParkourManager; import world.bentobox.parkour.Settings; import world.bentobox.parkour.gui.RankingsUI; +import world.bentobox.parkour.mocks.ServerMocks; /** * @author tastybento @@ -96,6 +99,7 @@ public class ClearTopCommandTest { */ @Before public void setUp() throws Exception { + ServerMocks.newServer(); // Set up plugin Whitebox.setInternalState(BentoBox.class, "instance", plugin); world.bentobox.bentobox.Settings s = new world.bentobox.bentobox.Settings(); @@ -166,18 +170,22 @@ public void setUp() throws Exception { // DUT cmd = new ClearTopCommand(ac); } + + @After + public void tearDown() { + ServerMocks.unsetBukkitServer(); + User.clearUsers(); + Mockito.framework().clearInlineMocks(); + } + /** * Test method for {@link world.bentobox.parkour.commands.ClearTopCommand#ClearTopCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}. */ @Test public void testClearTopCommand() { - assertNonNull(cmd); + assertNotNull(cmd); } - private void assertNonNull(ClearTopCommand cmd2) { - // TODO Auto-generated method stub - - } /** * Test method for {@link world.bentobox.parkour.commands.ClearTopCommand#setup()}. */ diff --git a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java index be2f56b..8c05df3 100644 --- a/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java +++ b/src/test/java/world/bentobox/parkour/listeners/CourseRunnerListenerTest.java @@ -1,5 +1,6 @@ package world.bentobox.parkour.listeners; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -9,6 +10,7 @@ import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.RETURNS_MOCKS; +import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -32,6 +34,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.entity.Creeper; import org.bukkit.entity.Player; +import org.bukkit.entity.Player.Spigot; import org.bukkit.event.block.Action; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; @@ -46,11 +49,13 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.modules.junit4.PowerMockRunner; +import net.md_5.bungee.api.chat.TextComponent; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.events.island.IslandEnterEvent; import world.bentobox.bentobox.api.events.island.IslandExitEvent; @@ -100,6 +105,8 @@ public class CourseRunnerListenerTest extends AbstractParkourTest { private Block block; @Mock private User u; + @Mock + private Spigot spigot; /** * @throws java.lang.Exception @@ -118,6 +125,7 @@ public void setUp() throws Exception { when(player.hasPermission(anyString())).thenReturn(false); when(player.getGameMode()).thenReturn(GameMode.SURVIVAL); when(player.getServer()).thenReturn(server); + when(player.spigot()).thenReturn(spigot); User.setPlugin(plugin); user = User.getInstance(player); @@ -414,7 +422,7 @@ public void testOnVisitorCommandQuittingParkour() { public void testOnStartEndSet() { PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); crl.onStartEndSet(e); - verify(player).sendMessage("parkour.start"); + checkSpigotMessage("parkour.start"); } /** @@ -425,7 +433,7 @@ public void testOnStartEndSetNoEnd() { when(this.parkourManager.getEnd(island)).thenReturn(Optional.empty()); PlayerInteractEvent e = new PlayerInteractEvent(player, Action.PHYSICAL, null, block, BlockFace.DOWN); crl.onStartEndSet(e); - verify(player).sendMessage("parkour.set-the-end"); + checkSpigotMessage("parkour.set-the-end"); } /** @@ -657,4 +665,32 @@ public void testOnTeleportToFlagActionVisitorsChorusFruit() { verify(player, never()).setGameMode(GameMode.SURVIVAL); } + /** + * Check that spigot sent the message + * @param message - message to check + */ + public void checkSpigotMessage(String expectedMessage) { + checkSpigotMessage(expectedMessage, 1); + } + + public void checkSpigotMessage(String expectedMessage, int expectedOccurrences) { + // Capture the argument passed to spigot().sendMessage(...) if messages are sent + ArgumentCaptor captor = ArgumentCaptor.forClass(TextComponent.class); + + // Verify that sendMessage() was called at least 0 times (capture any sent messages) + verify(spigot, atLeast(0)).sendMessage(captor.capture()); + + // Get all captured TextComponents + List capturedMessages = captor.getAllValues(); + + // Count the number of occurrences of the expectedMessage in the captured messages + long actualOccurrences = capturedMessages.stream().map(component -> component.toLegacyText()) // Convert each TextComponent to plain text + .filter(messageText -> messageText.contains(expectedMessage)) // Check if the message contains the expected text + .count(); // Count how many times the expected message appears + + // Assert that the number of occurrences matches the expectedOccurrences + assertEquals("Expected message occurrence mismatch: " + expectedMessage, expectedOccurrences, + actualOccurrences); + } + } diff --git a/src/test/java/world/bentobox/parkour/mocks/ServerMocks.java b/src/test/java/world/bentobox/parkour/mocks/ServerMocks.java new file mode 100644 index 0000000..7f8b4b8 --- /dev/null +++ b/src/test/java/world/bentobox/parkour/mocks/ServerMocks.java @@ -0,0 +1,118 @@ +package world.bentobox.parkour.mocks; + +import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.Server; +import org.bukkit.Tag; +import org.bukkit.UnsafeValues; +import org.eclipse.jdt.annotation.NonNull; + +public final class ServerMocks { + + public static @NonNull Server newServer() { + Server mock = mock(Server.class); + + Logger noOp = mock(Logger.class); + when(mock.getLogger()).thenReturn(noOp); + when(mock.isPrimaryThread()).thenReturn(true); + + // Unsafe + UnsafeValues unsafe = mock(UnsafeValues.class); + when(mock.getUnsafe()).thenReturn(unsafe); + + // Server must be available before tags can be mocked. + Bukkit.setServer(mock); + + // Bukkit has a lot of static constants referencing registry values. To initialize those, the + // registries must be able to be fetched before the classes are touched. + Map, Object> registers = new HashMap<>(); + + doAnswer(invocationGetRegistry -> registers.computeIfAbsent(invocationGetRegistry.getArgument(0), clazz -> { + Registry registry = mock(Registry.class); + Map cache = new HashMap<>(); + doAnswer(invocationGetEntry -> { + NamespacedKey key = invocationGetEntry.getArgument(0); + // Some classes (like BlockType and ItemType) have extra generics that will be + // erased during runtime calls. To ensure accurate typing, grab the constant's field. + // This approach also allows us to return null for unsupported keys. + Class constantClazz; + try { + //noinspection unchecked + constantClazz = (Class) clazz + .getField(key.getKey().toUpperCase(Locale.ROOT).replace('.', '_')).getType(); + } catch (ClassCastException e) { + throw new RuntimeException(e); + } catch (NoSuchFieldException e) { + return null; + } + + return cache.computeIfAbsent(key, key1 -> { + Keyed keyed = mock(constantClazz); + doReturn(key).when(keyed).getKey(); + return keyed; + }); + }).when(registry).get(notNull()); + return registry; + })).when(mock).getRegistry(notNull()); + + // Tags are dependent on registries, but use a different method. + // This will set up blank tags for each constant; all that needs to be done to render them + // functional is to re-mock Tag#getValues. + doAnswer(invocationGetTag -> { + Tag tag = mock(Tag.class); + doReturn(invocationGetTag.getArgument(1)).when(tag).getKey(); + doReturn(Set.of()).when(tag).getValues(); + doAnswer(invocationIsTagged -> { + Keyed keyed = invocationIsTagged.getArgument(0); + Class type = invocationGetTag.getArgument(2); + if (!type.isAssignableFrom(keyed.getClass())) { + return null; + } + // Since these are mocks, the exact instance might not be equal. Consider equal keys equal. + return tag.getValues().contains(keyed) + || tag.getValues().stream().anyMatch(value -> value.getKey().equals(keyed.getKey())); + }).when(tag).isTagged(notNull()); + return tag; + }).when(mock).getTag(notNull(), notNull(), notNull()); + + // Once the server is all set up, touch BlockType and ItemType to initialize. + // This prevents issues when trying to access dependent methods from a Material constant. + try { + Class.forName("org.bukkit.inventory.ItemType"); + Class.forName("org.bukkit.block.BlockType"); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + + return mock; + } + + public static void unsetBukkitServer() { + try { + Field server = Bukkit.class.getDeclaredField("server"); + server.setAccessible(true); + server.set(null, null); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private ServerMocks() { + } + +} \ No newline at end of file