From a8cdce5d18009a80aeca8b46da34876386ece82a Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 9 May 2018 00:14:20 -0400 Subject: [PATCH] Added admin register command and test. Unit tests pass, not tested in-game yet. Still no WiFi. North Platte, Nebraska. 1856km to San Francisco. 800kph ground speed. 107kph headwind. -56C outside temperature. 12035m altitude. --- .circleci/config.yml | 29 --- locales/en-US.yml | 6 + .../commands/admin/AdminRegisterCommand.java | 63 ++++- .../admin/AdminUnregisterCommand.java | 1 - .../bskyblock/managers/IslandsManager.java | 24 +- .../managers/island/IslandCache.java | 11 + .../admin/AdminRegisterCommandTest.java | 216 ++++++++++++++++++ 7 files changed, 311 insertions(+), 39 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 src/test/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommandTest.java diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index fe633c89c..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: 2 -jobs: - build: - - working_directory: ~/circleci-bskyblock - - docker: - - image: circleci/openjdk:8-jdk-browsers - - steps: - - - checkout - - - restore_cache: - key: circleci-bskyblock-{{ checksum "pom.xml" }} - - - run: mvn dependency:go-offline - - - save_cache: - paths: - - ~/.m2 - key: circleci-demo-java-spring-{{ checksum "pom.xml" }} - - - run: mvn clean - - run: mvn package - - run: mvn install - - - store_artifacts: - path: target/bskyblock-alpha-0.0.1.jar diff --git a/locales/en-US.yml b/locales/en-US.yml index 0a086ea2d..11568ca86 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -23,6 +23,7 @@ general: use-in-game: "&cThis command is only available in game." no-team: "&cYou do not have a team!" no-island: "&cYou do not have an island!" + player-has-island: "&cPlayer already has an island!" player-has-no-island: "&cThat player has no island!" already-have-island: "&cYou already have an island!" no-safe-location: "&cNo safe location found on island!" @@ -70,6 +71,11 @@ commands: parameters: "[player]" description: "make player the team's leader" already-leader: "&cPlayer is already the leader!" + register: + parameters: "[player]" + description: "register player to unowned island you are on" + registered-island: "&aRegistered player to island at [xyz]." + already-owned: "&cIsland is already owned by another player!" unregister: parameters: "[owner]" description: "unregister owner from island, but keep island blocks" diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java index e854b074a..2e5730b97 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java @@ -1,4 +1,63 @@ package us.tastybento.bskyblock.commands.admin; -public class AdminRegisterCommand { -} +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import us.tastybento.bskyblock.Constants; +import us.tastybento.bskyblock.api.commands.CompositeCommand; +import us.tastybento.bskyblock.api.user.User; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.util.Util; + +public class AdminRegisterCommand extends CompositeCommand { + + public AdminRegisterCommand(CompositeCommand parent) { + super(parent, "unregister"); + } + + @Override + public void setup() { + setPermission(Constants.PERMPREFIX + "admin.unregister"); + setOnlyPlayer(true); + setParameters("commands.admin.unregister.parameters"); + setDescription("commands.admin.unregister.description"); + } + + @Override + public boolean execute(User user, List args) { + // If args are not right, show help + if (args.size() != 1) { + showHelp(this, user); + return false; + } + // Get target + UUID targetUUID = getPlayers().getUUID(args.get(0)); + if (targetUUID == null) { + user.sendMessage("general.errors.unknown-player"); + return false; + } + if (getIslands().hasIsland(targetUUID)) { + user.sendMessage("general.errors.player-has-island"); + return false; + } + if (getIslands().inTeam(targetUUID)) { + user.sendMessage("commands.admin.register.cannot-register-team-player"); + return false; + } + // Check if island is owned + Optional island = getIslands().getIslandAt(user.getLocation()); + if (island.map(i -> i.getOwner() != null).orElse(false)) { + user.sendMessage("commands.admin.register.already-owned"); + return false; + } + // Register island if it exists + return island.map(i -> { + // Island exists + getIslands().makeLeader(user, targetUUID, i); + user.sendMessage("commands.admin.register.registered-island", "[xyz]", Util.xyz(i.getCenter().toVector())); + user.sendMessage("general.success"); + return true; + }).orElse(false); // Island does not exist + } +} \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java index 6b007da19..99d93c4fc 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java @@ -6,7 +6,6 @@ import java.util.UUID; import us.tastybento.bskyblock.Constants; import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.user.User; -import us.tastybento.bskyblock.database.objects.Island; import us.tastybento.bskyblock.util.Util; public class AdminUnregisterCommand extends CompositeCommand { diff --git a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java index eed74dc16..323d463ce 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java @@ -817,6 +817,10 @@ public class IslandsManager { public boolean inTeam(UUID playerUUID) { return getMembers(playerUUID).size() > 1; } + + private int getMaxRangeSize(User user) { + return Util.getPermValue(user.getPlayer(), "island.range.", plugin.getSettings().getIslandProtectionRange()); + } /** * Makes a new leader for an island @@ -824,9 +828,18 @@ public class IslandsManager { * @param targetUUID - the current island member who is going to become the leader */ public void makeLeader(User user, UUID targetUUID) { - // target is the new leader - Island island = getIsland(user.getUniqueId()); - island.setOwner(targetUUID); + makeLeader(user, targetUUID, getIsland(targetUUID)); + } + + /** + * Makes a new leader for an island + * @param user - requester + * @param targetUUID - new leader + * @param island - island to register + */ + public void makeLeader(User user, UUID targetUUID, Island island) { + islandCache.setOwner(island, targetUUID); + user.sendMessage("commands.island.team.setowner.name-is-the-owner", "[name]", plugin.getPlayers().getName(targetUUID)); // Check if online @@ -845,10 +858,7 @@ public class IslandsManager { island.setProtectionRange(range); } - } - - private int getMaxRangeSize(User user) { - return Util.getPermValue(user.getPlayer(), "island.range.", plugin.getSettings().getIslandProtectionRange()); + } } diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java b/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java index 2febb83a6..8f4ef81ae 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java @@ -284,5 +284,16 @@ public class IslandCache { public int size() { return islandsByLocation.size(); } + + /** + * Sets an island owner. Clears out any other owner + * @param island - island + * @param newOwnerUUID - new owner + */ + public void setOwner(Island island, UUID newOwnerUUID) { + island.setOwner(newOwnerUUID); + islandsByUUID.put(newOwnerUUID, island); + islandsByLocation.put(island.getCenter(), island); + } } diff --git a/src/test/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommandTest.java b/src/test/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommandTest.java new file mode 100644 index 000000000..8a2a761c5 --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommandTest.java @@ -0,0 +1,216 @@ +package us.tastybento.bskyblock.commands.admin; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.util.Vector; +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 org.powermock.reflect.Whitebox; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.Settings; +import us.tastybento.bskyblock.api.user.User; +import us.tastybento.bskyblock.commands.AdminCommand; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.managers.CommandsManager; +import us.tastybento.bskyblock.managers.IslandsManager; +import us.tastybento.bskyblock.managers.LocalesManager; +import us.tastybento.bskyblock.managers.PlayersManager; + + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, BSkyBlock.class, User.class }) +public class AdminRegisterCommandTest { + + private BSkyBlock plugin; + private AdminCommand ac; + private UUID uuid; + private User user; + private Settings s; + private IslandsManager im; + private PlayersManager pm; + private UUID notUUID; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // Set up plugin + plugin = mock(BSkyBlock.class); + Whitebox.setInternalState(BSkyBlock.class, "instance", plugin); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Settings + s = mock(Settings.class); + when(s.getResetWait()).thenReturn(0L); + when(s.getResetLimit()).thenReturn(3); + when(plugin.getSettings()).thenReturn(s); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + user = mock(User.class); + when(user.isOp()).thenReturn(false); + uuid = UUID.randomUUID(); + notUUID = UUID.randomUUID(); + while(notUUID.equals(uuid)) { + notUUID = UUID.randomUUID(); + } + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + User.setPlugin(plugin); + + // Parent command has no aliases + ac = mock(AdminCommand.class); + when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); + + // Player has island to begin with + im = mock(IslandsManager.class); + when(im.hasIsland(Mockito.any())).thenReturn(true); + when(im.isOwner(Mockito.any())).thenReturn(true); + when(im.getTeamLeader(Mockito.any())).thenReturn(uuid); + when(plugin.getIslands()).thenReturn(im); + + // Has team + pm = mock(PlayersManager.class); + when(im.inTeam(Mockito.eq(uuid))).thenReturn(true); + + when(plugin.getPlayers()).thenReturn(pm); + + // Server & Scheduler + BukkitScheduler sch = mock(BukkitScheduler.class); + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getScheduler()).thenReturn(sch); + + // Locales + LocalesManager lm = mock(LocalesManager.class); + when(lm.get(Mockito.any(), Mockito.any())).thenReturn("mock translation"); + when(plugin.getLocalesManager()).thenReturn(lm); + } + + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminRegisterCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteNoTarget() { + AdminRegisterCommand itl = new AdminRegisterCommand(ac); + assertFalse(itl.execute(user, new ArrayList<>())); + // Show help + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminRegisterCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteUnknownPlayer() { + AdminRegisterCommand itl = new AdminRegisterCommand(ac); + String[] name = {"tastybento"}; + when(pm.getUUID(Mockito.any())).thenReturn(null); + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage(Mockito.eq("general.errors.unknown-player")); + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminRegisterCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecutePlayerHasIsland() { + AdminRegisterCommand itl = new AdminRegisterCommand(ac); + String[] name = {"tastybento"}; + when(pm.getUUID(Mockito.any())).thenReturn(notUUID); + when(im.hasIsland(Mockito.any())).thenReturn(true); + when(im.inTeam(Mockito.any())).thenReturn(false); + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage(Mockito.eq("general.errors.player-has-island")); + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminRegisterCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteInTeam() { + when(im.hasIsland(Mockito.any())).thenReturn(false); + when(im.inTeam(Mockito.any())).thenReturn(true); + String[] name = {"tastybento"}; + when(pm.getUUID(Mockito.any())).thenReturn(notUUID); + AdminRegisterCommand itl = new AdminRegisterCommand(ac); + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("commands.admin.register.cannot-register-team-player"); + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminRegisterCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteAlreadyOwnedIsland() { + when(im.inTeam(Mockito.any())).thenReturn(false); + when(im.hasIsland(Mockito.any())).thenReturn(false); + String[] name = {"tastybento"}; + when(pm.getUUID(Mockito.any())).thenReturn(notUUID); + Location loc = mock(Location.class); + + // Island has owner + Island is = mock(Island.class); + when(is.getOwner()).thenReturn(uuid); + Optional opi = Optional.of(is); + when(im.getIslandAt(Mockito.any())).thenReturn(opi); + when(user.getLocation()).thenReturn(loc); + AdminRegisterCommand itl = new AdminRegisterCommand(ac); + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("commands.admin.register.already-owned"); + } + + /** + * Test method for {@link us.us.tastybento.bskyblock.commands.admin.teams.AdminRegisterCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteSuccess() { + when(im.inTeam(Mockito.any())).thenReturn(false); + when(im.hasIsland(Mockito.any())).thenReturn(false); + Island is = mock(Island.class); + Location loc = mock(Location.class); + when(loc.toVector()).thenReturn(new Vector(123,123,432)); + when(is.getCenter()).thenReturn(loc); + when(im.getIsland(Mockito.any())).thenReturn(is); + Optional opi = Optional.of(is); + when(im.getIslandAt(Mockito.any())).thenReturn(opi); + when(user.getLocation()).thenReturn(loc); + String[] name = {"tastybento"}; + when(pm.getUUID(Mockito.any())).thenReturn(notUUID); + + AdminRegisterCommand itl = new AdminRegisterCommand(ac); + assertTrue(itl.execute(user, Arrays.asList(name))); + // Add other verifications + Mockito.verify(user).sendMessage("commands.admin.register.registered-island", "[xyz]", "123,123,432"); + Mockito.verify(user).sendMessage(Mockito.eq("general.success")); + } + +}