From 5eb6447f0168a39eb44ceb927abfd730164b3e3d Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 7 May 2018 20:11:03 -0700 Subject: [PATCH] Added admin team add command Unit tests pass, but not tested on real server yet. --- locales/en-US.yml | 11 + .../tastybento/bskyblock/api/user/User.java | 6 +- .../bskyblock/commands/AdminCommand.java | 7 + .../admin/teams/AdminTeamAddCommand.java | 69 ++++- .../admin/teams/AdminTeamDisbandCommand.java | 2 +- ...d.java => AdminTeamMakeLeaderCommand.java} | 2 +- .../admin/teams/AdminTeamAddCommandTest.java | 293 ++++++++++++++++++ 7 files changed, 384 insertions(+), 6 deletions(-) rename src/main/java/us/tastybento/bskyblock/commands/admin/teams/{AdminTeamCommand.java => AdminTeamMakeLeaderCommand.java} (57%) create mode 100644 src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java diff --git a/locales/en-US.yml b/locales/en-US.yml index 4f780664f..8433e9e03 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -30,6 +30,7 @@ general: not-in-team: "&cThat player is not in your team!" offline-player: "&cThat player is offline or doesn't exist." unknown-player: "&cUnknown player!" + unknown-player-name: "&c[name] is an unknown player!" general: "&cThat command is not ready yet - contact admin" unknown-command: "&cUnknown command. Do &b/[label] help &cfor help." warp-not-safe: "&cThat warp is not safe right now!" @@ -50,6 +51,16 @@ commands: help: description: "admin command" team: + add: + parameters: "[leader] [player]" + description: "add player to leader's team" + name-not-leader: "&c[name] is not the leader" + name-has-island: "&c[name] has an island. Unregister or delete them first!" + disband: + parameters: "[team leader]" + description: "disband team leader's team" + user-disband-leader: "&cNot leader! Use disband [leader]" + disbanded: "&cAdmin disbanded your team!" kick: parameters: "[team player]" description: "kick a player from a team" diff --git a/src/main/java/us/tastybento/bskyblock/api/user/User.java b/src/main/java/us/tastybento/bskyblock/api/user/User.java index c8f6b7744..2e2919367 100644 --- a/src/main/java/us/tastybento/bskyblock/api/user/User.java +++ b/src/main/java/us/tastybento/bskyblock/api/user/User.java @@ -122,15 +122,15 @@ public class User { } public PlayerInventory getInventory() { - return player.getInventory(); + return player != null ? player.getInventory() : null; } public Location getLocation() { - return player.getLocation(); + return player != null ? player.getLocation() : null; } public String getName() { - return player.getName(); + return player != null ? player.getName() : playerUUID.toString(); } /** diff --git a/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java b/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java index 22c9d185b..4fd21b85a 100755 --- a/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java @@ -11,6 +11,9 @@ import us.tastybento.bskyblock.commands.admin.AdminReloadCommand; import us.tastybento.bskyblock.commands.admin.AdminSetRankCommand; import us.tastybento.bskyblock.commands.admin.AdminTeleportCommand; import us.tastybento.bskyblock.commands.admin.AdminVersionCommand; +import us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand; +import us.tastybento.bskyblock.commands.admin.teams.AdminTeamDisbandCommand; +import us.tastybento.bskyblock.commands.admin.teams.AdminTeamKickCommand; public class AdminCommand extends CompositeCommand { @@ -32,6 +35,10 @@ public class AdminCommand extends CompositeCommand { new AdminGetRankCommand(this); new AdminSetRankCommand(this); new AdminInfoCommand(this); + // Team commands + new AdminTeamAddCommand(this); + new AdminTeamKickCommand(this); + new AdminTeamDisbandCommand(this); } @Override diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java index 5872de262..0d92057ec 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java @@ -1,4 +1,71 @@ package us.tastybento.bskyblock.commands.admin.teams; -public class AdminTeamAddCommand { +import java.util.List; +import java.util.UUID; + +import us.tastybento.bskyblock.Constants; +import us.tastybento.bskyblock.api.commands.CompositeCommand; +import us.tastybento.bskyblock.api.user.User; + +public class AdminTeamAddCommand extends CompositeCommand { + + public AdminTeamAddCommand(CompositeCommand parent) { + super(parent, "add"); + + } + + @Override + public void setup() { + setPermission(Constants.PERMPREFIX + "admin.team"); + setParameters("commands.admin.team.add.parameters"); + setDescription("commands.admin.team.add.description"); + } + + @Override + public boolean execute(User user, List args) { + // If args are not right, show help + if (args.size() != 2) { + showHelp(this, user); + return false; + } + // Get leader and target + UUID leaderUUID = getPlayers().getUUID(args.get(0)); + if (leaderUUID == null) { + user.sendMessage("general.errors.unknown-player-name", "[name]", args.get(0)); + return false; + } + UUID targetUUID = getPlayers().getUUID(args.get(1)); + if (targetUUID == null) { + user.sendMessage("general.errors.unknown-player-name", "[name]", args.get(1)); + return false; + } + if (!getIslands().hasIsland(leaderUUID)) { + user.sendMessage("general.errors.player-has-no-island"); + return false; + } + if (getIslands().inTeam(leaderUUID) && !getIslands().getTeamLeader(leaderUUID).equals(leaderUUID)) { + user.sendMessage("commands.admin.team.add.name-not-leader", "[name]", args.get(0)); + getIslands().getIsland(leaderUUID).showMembers(getPlugin(), user); + return false; + } + if (getIslands().inTeam(targetUUID)) { + user.sendMessage("commands.island.team.invite.errors.already-on-team"); + return false; + } + if (getIslands().hasIsland(targetUUID)) { + user.sendMessage("commands.admin.team.add.name-has-island", "[name]", args.get(1)); + return false; + } + // Success + User target = User.getInstance(targetUUID); + User leader = User.getInstance(leaderUUID); + leader.sendMessage("commands.island.team.invite.accept.name-joined-your-island", "[name]", target.getName()); + target.sendMessage("commands.island.team.invite.accept.you-joined-island", "[label]", Constants.ISLANDCOMMAND); + getIslands().getIsland(leaderUUID).addMember(targetUUID); + user.sendMessage("general.success"); + return true; + + } + + } diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamDisbandCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamDisbandCommand.java index 340c94980..357b91bd9 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamDisbandCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamDisbandCommand.java @@ -47,7 +47,7 @@ public class AdminTeamDisbandCommand extends CompositeCommand { } // Disband team getIslands().getMembers(targetUUID).forEach(m -> { - User.getInstance(m).sendMessage("commands.admin.team.disbanded"); + User.getInstance(m).sendMessage("commands.admin.team.disband.disbanded"); // The leader gets to keep the island if (!m.equals(targetUUID)) { getIslands().setLeaveTeam(m); diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamMakeLeaderCommand.java similarity index 57% rename from src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamCommand.java rename to src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamMakeLeaderCommand.java index f79633851..a02d58bf1 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamMakeLeaderCommand.java @@ -1,4 +1,4 @@ package us.tastybento.bskyblock.commands.admin.teams; -public class AdminTeamCommand { +public class AdminTeamMakeLeaderCommand { } diff --git a/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java b/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java new file mode 100644 index 000000000..4767e32be --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java @@ -0,0 +1,293 @@ +package us.tastybento.bskyblock.commands.admin.teams; + +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.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitScheduler; +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 AdminTeamAddCommandTest { + + 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.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteWrongArgs() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + List args = new ArrayList<>(); + assertFalse(itl.execute(user, args)); + // Show help + args.add("arg1"); + assertFalse(itl.execute(user, args)); + // Show help + args.add("args2"); + args.add("args3"); + assertFalse(itl.execute(user, args)); + // Show help + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteUnknownPlayer() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + // Unknown leader + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(null); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("general.errors.unknown-player-name", "[name]", "tastybento"); + + // Unknown target + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(null); + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("general.errors.unknown-player-name", "[name]", "poslovich"); + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteTargetTargetInTeam() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + + when(im.inTeam(notUUID)).thenReturn(true); + + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage(Mockito.eq("commands.island.team.invite.errors.already-on-team")); + } + + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteAddNoIsland() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + + // No island, + when(im.hasIsland(uuid)).thenReturn(false); + + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("general.errors.player-has-no-island"); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteAddNotLeader() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + + // Has island, has team, but not a leader + when(im.hasIsland(uuid)).thenReturn(true); + when(im.inTeam(uuid)).thenReturn(true); + when(im.getTeamLeader(uuid)).thenReturn(notUUID); + + // Island + Island island = mock(Island.class); + when(im.getIsland(uuid)).thenReturn(island); + + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("commands.admin.team.add.name-not-leader", "[name]", "tastybento"); + Mockito.verify(island).showMembers(Mockito.eq(plugin), Mockito.any()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteAddTargetHasIsland() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + + // Has island, has team, is leader + when(im.hasIsland(uuid)).thenReturn(true); + when(im.inTeam(uuid)).thenReturn(true); + when(im.getTeamLeader(uuid)).thenReturn(uuid); + + // Target has island + when(im.hasIsland(notUUID)).thenReturn(true); + + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("commands.admin.team.add.name-has-island", "[name]", "poslovich"); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteAddTargetHasIslandNoTeam() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + + // Has island, no team + when(im.hasIsland(uuid)).thenReturn(true); + when(im.inTeam(uuid)).thenReturn(false); + + // Target has island + when(im.hasIsland(notUUID)).thenReturn(true); + + assertFalse(itl.execute(user, Arrays.asList(name))); + Mockito.verify(user).sendMessage("commands.admin.team.add.name-has-island", "[name]", "poslovich"); + + } + + /** + * Test method for {@link us.us.tastybento.bskyblock.commands.admin.teams.AdminTeamAddCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}. + */ + @Test + public void testExecuteSuccess() { + AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); + String[] name = {"tastybento", "poslovich"}; + + when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + + // Has island, no team + when(im.hasIsland(uuid)).thenReturn(true); + when(im.inTeam(uuid)).thenReturn(false); + + // Target has no island + when(im.hasIsland(notUUID)).thenReturn(false); + + // Island + Island island = mock(Island.class); + when(im.getIsland(uuid)).thenReturn(island); + + + // Success + assertTrue(itl.execute(user, Arrays.asList(name))); + Mockito.verify(island).addMember(notUUID); + Mockito.verify(user).sendMessage(Mockito.eq("general.success")); + } + +}