diff --git a/src/main/java/fr/xephi/authme/AntiBot.java b/src/main/java/fr/xephi/authme/AntiBot.java index 3b8d0afc8..72be5ac7f 100644 --- a/src/main/java/fr/xephi/authme/AntiBot.java +++ b/src/main/java/fr/xephi/authme/AntiBot.java @@ -17,7 +17,7 @@ public class AntiBot { private static final AuthMe plugin = AuthMe.getInstance(); private static final Messages messages = plugin.getMessages(); - private static Wrapper wrapper = new Wrapper(plugin); + private static Wrapper wrapper = Wrapper.getInstance(); private static final List antibotPlayers = new ArrayList<>(); private static AntiBotStatus antiBotStatus = AntiBotStatus.DISABLED; diff --git a/src/main/java/fr/xephi/authme/ConsoleLogger.java b/src/main/java/fr/xephi/authme/ConsoleLogger.java index 6009bc3a1..890318046 100644 --- a/src/main/java/fr/xephi/authme/ConsoleLogger.java +++ b/src/main/java/fr/xephi/authme/ConsoleLogger.java @@ -17,7 +17,7 @@ import java.util.Date; */ public final class ConsoleLogger { - private static Wrapper wrapper = new Wrapper(AuthMe.getInstance()); + private static Wrapper wrapper = Wrapper.getInstance(); private static final DateFormat df = new SimpleDateFormat("[MM-dd HH:mm:ss]"); private ConsoleLogger() { diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 3e4234580..74428e3f7 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -226,11 +226,11 @@ public class CommandDescription { */ public void setLabels(List labels) { // Check whether the command label list should be cleared - if (labels == null) + if (labels == null) { this.labels.clear(); - - else + } else { this.labels = labels; + } } /** @@ -344,7 +344,7 @@ public class CommandDescription { /** * Get the absolute command label, without a slash. * - * @return String + * @return the absolute label */ public String getAbsoluteLabel() { return getAbsoluteLabel(false); @@ -364,8 +364,8 @@ public class CommandDescription { /** * Get the absolute command label. * - * @param includeSlash boolean - * @param reference CommandParts + * @param includeSlash + * @param reference * * @return Absolute command label. */ @@ -644,11 +644,11 @@ public class CommandDescription { */ public void setArguments(List arguments) { // Convert null into an empty argument list - if (arguments == null) + if (arguments == null) { this.arguments.clear(); - - else + } else { this.arguments = arguments; + } } /** @@ -659,12 +659,7 @@ public class CommandDescription { * @return True if this argument already exists, false otherwise. */ public boolean hasArgument(CommandArgumentDescription argument) { - // Make sure the argument is valid - if (argument == null) - return false; - - // Check whether the argument exists, return the result - return this.arguments.contains(argument); + return argument != null && arguments.contains(argument); } /** @@ -881,19 +876,22 @@ public class CommandDescription { */ public int getSuitableArgumentsDifference(CommandParts commandReference) { // Make sure the command reference is valid - if (commandReference.getCount() <= 0) + if (commandReference.getCount() <= 0) { return -1; + } // Get the remaining command reference element count int remainingElementCount = commandReference.getCount() - getParentCount() - 1; - // Check if there are too less arguments - if (getMinimumArguments() > remainingElementCount) + // Check if there are too few arguments + if (getMinimumArguments() > remainingElementCount) { return Math.abs(getMinimumArguments() - remainingElementCount); + } // Check if there are too many arguments - if (getMaximumArguments() < remainingElementCount && getMaximumArguments() >= 0) + if (getMaximumArguments() < remainingElementCount && getMaximumArguments() >= 0) { return Math.abs(remainingElementCount - getMaximumArguments()); + } // The arguments seem to be EQUALS, return the result return 0; @@ -934,12 +932,14 @@ public class CommandDescription { */ public boolean isValid() { // Make sure any command label is set - if (getLabels().size() == 0) + if (getLabels().size() == 0) { return false; + } // Make sure the permissions are set up properly - if (this.permissions == null) + if (this.permissions == null) { return false; + } // Everything seems to be correct, return the result return true; diff --git a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java index 42083612f..0ebff20c5 100644 --- a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java @@ -17,6 +17,11 @@ public class ChangePasswordCommand extends ExecutableCommand { @Override public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { + // Make sure the current command executor is a player + if (!(sender instanceof Player)) { + return true; + } + final AuthMe plugin = AuthMe.getInstance(); final Messages m = plugin.getMessages(); @@ -24,11 +29,6 @@ public class ChangePasswordCommand extends ExecutableCommand { String playerPass = commandArguments.get(0); String playerPassVerify = commandArguments.get(1); - // Make sure the current command executor is a player - if (!(sender instanceof Player)) { - return true; - } - // Get the player instance and make sure it's authenticated Player player = (Player) sender; String name = player.getName().toLowerCase(); @@ -38,6 +38,7 @@ public class ChangePasswordCommand extends ExecutableCommand { } // Make sure the password is allowed + // TODO ljacqu 20151121: The password confirmation appears to be never verified String playerPassLowerCase = playerPass.toLowerCase(); if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") @@ -56,11 +57,9 @@ public class ChangePasswordCommand extends ExecutableCommand { m.send(player, MessageKey.INVALID_PASSWORD_LENGTH); return true; } - if (!Settings.unsafePasswords.isEmpty()) { - if (Settings.unsafePasswords.contains(playerPassLowerCase)) { - m.send(player, MessageKey.PASSWORD_UNSAFE_ERROR); - return true; - } + if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) { + m.send(player, MessageKey.PASSWORD_UNSAFE_ERROR); + return true; } // Set the password diff --git a/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java index b384509fb..7a403957d 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java @@ -12,19 +12,19 @@ public class AddEmailCommand extends ExecutableCommand { @Override public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { - // Get the parameter values - String playerMail = commandArguments.get(0); - String playerMailVerify = commandArguments.get(1); - // Make sure the current command executor is a player if (!(sender instanceof Player)) { return true; } + // Get the parameter values + String playerMail = commandArguments.get(0); + String playerMailVerify = commandArguments.get(1); + // Get the player and perform email addition final AuthMe plugin = AuthMe.getInstance(); final Player player = (Player) sender; - plugin.management.performAddEmail(player, playerMail, playerMailVerify); + plugin.getManagement().performAddEmail(player, playerMail, playerMailVerify); return true; } } diff --git a/src/main/java/fr/xephi/authme/command/executable/email/ChangeEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/ChangeEmailCommand.java index ffff76a45..11889f882 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/ChangeEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/ChangeEmailCommand.java @@ -12,19 +12,19 @@ public class ChangeEmailCommand extends ExecutableCommand { @Override public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { - // Get the parameter values - String playerMailOld = commandArguments.get(0); - String playerMailNew = commandArguments.get(1); - // Make sure the current command executor is a player if (!(sender instanceof Player)) { return true; } + // Get the parameter values + String playerMailOld = commandArguments.get(0); + String playerMailNew = commandArguments.get(1); + // Get the player instance and execute action final AuthMe plugin = AuthMe.getInstance(); final Player player = (Player) sender; - plugin.management.performChangeEmail(player, playerMailOld, playerMailNew); + plugin.getManagement().performChangeEmail(player, playerMailOld, playerMailNew); return true; } } diff --git a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java index ce4dedf47..1aac6f5bf 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java @@ -22,14 +22,14 @@ public class RecoverEmailCommand extends ExecutableCommand { @Override public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { - // Get the parameter values - String playerMail = commandArguments.get(0); - // Make sure the current command executor is a player if (!(sender instanceof Player)) { return true; } + // Get the parameter values + String playerMail = commandArguments.get(0); + // Get the player instance and name final Player player = (Player) sender; final String playerName = player.getName(); diff --git a/src/main/java/fr/xephi/authme/process/Management.java b/src/main/java/fr/xephi/authme/process/Management.java index 1796d8d72..58ce248f7 100644 --- a/src/main/java/fr/xephi/authme/process/Management.java +++ b/src/main/java/fr/xephi/authme/process/Management.java @@ -12,8 +12,6 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitScheduler; /** - * @author Gabriele - * @version $Revision: 1.0 $ */ public class Management { @@ -30,13 +28,6 @@ public class Management { this.sched = this.plugin.getServer().getScheduler(); } - /** - * Method performLogin. - * - * @param player Player - * @param password String - * @param forceLogin boolean - */ public void performLogin(final Player player, final String password, final boolean forceLogin) { sched.runTaskAsynchronously(plugin, new Runnable() { @@ -47,11 +38,6 @@ public class Management { }); } - /** - * Method performLogout. - * - * @param player Player - */ public void performLogout(final Player player) { sched.runTaskAsynchronously(plugin, new Runnable() { @@ -62,13 +48,6 @@ public class Management { }); } - /** - * Method performRegister. - * - * @param player Player - * @param password String - * @param email String - */ public void performRegister(final Player player, final String password, final String email) { sched.runTaskAsynchronously(plugin, new Runnable() { @@ -79,13 +58,6 @@ public class Management { }); } - /** - * Method performUnregister. - * - * @param player Player - * @param password String - * @param force boolean - */ public void performUnregister(final Player player, final String password, final boolean force) { sched.runTaskAsynchronously(plugin, new Runnable() { @@ -96,11 +68,6 @@ public class Management { }); } - /** - * Method performJoin. - * - * @param player Player - */ public void performJoin(final Player player) { sched.runTaskAsynchronously(plugin, new Runnable() { @@ -112,12 +79,6 @@ public class Management { }); } - /** - * Method performQuit. - * - * @param player Player - * @param isKick boolean - */ public void performQuit(final Player player, final boolean isKick) { sched.runTaskAsynchronously(plugin, new Runnable() { @@ -129,13 +90,6 @@ public class Management { }); } - /** - * Method performAddEmail. - * - * @param player Player - * @param newEmail String - * @param newEmailVerify String - */ public void performAddEmail(final Player player, final String newEmail, final String newEmailVerify) { sched.runTaskAsynchronously(plugin, new Runnable() { @Override @@ -145,13 +99,6 @@ public class Management { }); } - /** - * Method performChangeEmail. - * - * @param player Player - * @param oldEmail String - * @param newEmail String - */ public void performChangeEmail(final Player player, final String oldEmail, final String newEmail) { sched.runTaskAsynchronously(plugin, new Runnable() { @Override diff --git a/src/main/java/fr/xephi/authme/util/GeoLiteAPI.java b/src/main/java/fr/xephi/authme/util/GeoLiteAPI.java index b9d730e7a..ebd0deb31 100644 --- a/src/main/java/fr/xephi/authme/util/GeoLiteAPI.java +++ b/src/main/java/fr/xephi/authme/util/GeoLiteAPI.java @@ -17,7 +17,6 @@ public class GeoLiteAPI { "available at http://www.maxmind.com"; private static final String GEOIP_URL = "http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry" + "/GeoIP.dat.gz"; - private static final Wrapper wrapper = new Wrapper(AuthMe.getInstance()); private static final AuthMe plugin = AuthMe.getInstance(); private static LookupService lookupService; diff --git a/src/main/java/fr/xephi/authme/util/StringUtils.java b/src/main/java/fr/xephi/authme/util/StringUtils.java index ad6e560d1..eef90ed3f 100644 --- a/src/main/java/fr/xephi/authme/util/StringUtils.java +++ b/src/main/java/fr/xephi/authme/util/StringUtils.java @@ -10,10 +10,14 @@ import java.io.StringWriter; /** * Utility class for String operations. */ -public class StringUtils { +public final class StringUtils { public static final String newline = System.getProperty("line.separator"); + private StringUtils() { + // Utility class + } + /** * Get the difference of two strings. * diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index 7d9808bef..420706ef1 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -26,7 +26,7 @@ import java.util.Collections; */ public final class Utils { - private static final AuthMe plugin; + private static AuthMe plugin; private static Wrapper wrapper; private static boolean getOnlinePlayersIsCollection = false; @@ -34,7 +34,7 @@ public final class Utils { static { plugin = AuthMe.getInstance(); - wrapper = new Wrapper(plugin); + wrapper = Wrapper.getInstance(); initializeOnlinePlayersIsCollectionField(); } @@ -116,9 +116,10 @@ public final class Utils { // Get the permissions manager, and make sure it's valid PermissionsManager permsMan = plugin.getPermissionsManager(); - if (permsMan == null) - ConsoleLogger.showError("Failed to access permissions manager instance, shutting down."); - assert permsMan != null; + if (permsMan == null) { + ConsoleLogger.showError("Failed to access permissions manager instance, aborting."); + return false; + } // Remove old groups permsMan.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup, diff --git a/src/main/java/fr/xephi/authme/util/Wrapper.java b/src/main/java/fr/xephi/authme/util/Wrapper.java index 1505a203e..978d0ab58 100644 --- a/src/main/java/fr/xephi/authme/util/Wrapper.java +++ b/src/main/java/fr/xephi/authme/util/Wrapper.java @@ -13,22 +13,31 @@ import java.util.logging.Logger; */ public class Wrapper { - private AuthMe authMe; + private static Wrapper singleton; - public Wrapper(AuthMe authMe) { - this.authMe = authMe; + /** + * Package-private constructor for testing purposes to inject a mock instance. + */ + Wrapper() { + } + + public static Wrapper getInstance() { + if (singleton == null) { + singleton = new Wrapper(); + } + return singleton; } public AuthMe getAuthMe() { - return authMe; + return AuthMe.getInstance(); } public Server getServer() { - return authMe.getServer(); + return getAuthMe().getServer(); } public Logger getLogger() { - return authMe.getLogger(); + return getAuthMe().getLogger(); } public BukkitScheduler getScheduler() { diff --git a/src/test/java/fr/xephi/authme/AuthMeMockUtil.java b/src/test/java/fr/xephi/authme/AuthMeMockUtil.java index 821157f36..1cc0ef7c8 100644 --- a/src/test/java/fr/xephi/authme/AuthMeMockUtil.java +++ b/src/test/java/fr/xephi/authme/AuthMeMockUtil.java @@ -1,7 +1,9 @@ package fr.xephi.authme; +import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.settings.Messages; import fr.xephi.authme.util.Wrapper; +import fr.xephi.authme.util.WrapperMock; import org.mockito.Mockito; import java.lang.reflect.Field; @@ -34,6 +36,19 @@ public final class AuthMeMockUtil { mockSingletonForClass(Messages.class, "singleton", mock); } + /** + * Creates a mock singleton for the player cache, retrievable from {@link PlayerCache#getInstance()}. + */ + public static void mockPlayerCacheInstance() { + PlayerCache mock = Mockito.mock(PlayerCache.class); + mockSingletonForClass(PlayerCache.class, "singleton", mock); + } + + public static void initializeWrapperMock() { + WrapperMock wrapper = new WrapperMock(); + mockSingletonForClass(Wrapper.class, "singleton", wrapper); + } + /** * Set the given class' {@link Wrapper} field to a mock implementation. * @@ -50,7 +65,7 @@ public final class AuthMeMockUtil { } public static Wrapper insertMockWrapperInstance(Class clazz, String fieldName, AuthMe authMe) { - Wrapper wrapperMock = new WrapperMock(authMe); + Wrapper wrapperMock = new WrapperMock(); mockSingletonForClass(clazz, fieldName, wrapperMock); return wrapperMock; } @@ -69,7 +84,7 @@ public final class AuthMeMockUtil { * @param fieldName The field name * @param mock The mock to set for the given field */ - private static void mockSingletonForClass(Class clazz, String fieldName, Object mock) { + public static void mockSingletonForClass(Class clazz, String fieldName, Object mock) { try { Field instance = clazz.getDeclaredField(fieldName); instance.setAccessible(true); diff --git a/src/test/java/fr/xephi/authme/command/CommandManagerTest.java b/src/test/java/fr/xephi/authme/command/CommandManagerTest.java new file mode 100644 index 000000000..9309d4a00 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/CommandManagerTest.java @@ -0,0 +1,41 @@ +package fr.xephi.authme.command; + +import org.junit.Test; + +import java.util.List; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +/** + * Test for {@link CommandManager}. + */ +public class CommandManagerTest { + + @Test + public void shouldInitializeCommands() { + // given/when + CommandManager manager = new CommandManager(true); + int commandCount = manager.getCommandDescriptionCount(); + List commands = manager.getCommandDescriptions(); + + // then + // It obviously doesn't make sense to test much of the concrete data + // that is being initialized; we just want to guarantee with this test + // that data is indeed being initialized and we take a few "probes" + assertThat(commandCount, equalTo(9)); + assertThat(commandsIncludeLabel(commands, "authme"), equalTo(true)); + assertThat(commandsIncludeLabel(commands, "register"), equalTo(true)); + assertThat(commandsIncludeLabel(commands, "help"), equalTo(false)); + } + + private static boolean commandsIncludeLabel(Iterable commands, String label) { + for (CommandDescription command : commands) { + if (command.getLabels().contains(label)) { + return true; + } + } + return false; + } + +} diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java new file mode 100644 index 000000000..d991797e1 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -0,0 +1,166 @@ +package fr.xephi.authme.command.executable.changepassword; + +import fr.xephi.authme.AuthMeMockUtil; +import fr.xephi.authme.cache.auth.PlayerCache; +import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.settings.Settings; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import org.junit.Before; +import org.junit.Test; + + +import java.util.Arrays; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Test for {@link ChangePasswordCommand}. + */ +public class ChangePasswordCommandTest { + + private Messages messagesMock; + private PlayerCache cacheMock; + + @Before + public void setUpMocks() { + AuthMeMockUtil.mockAuthMeInstance(); + AuthMeMockUtil.mockPlayerCacheInstance(); + cacheMock = PlayerCache.getInstance(); + + AuthMeMockUtil.mockMessagesInstance(); + messagesMock = Messages.getInstance(); + + // Only allow passwords with alphanumerical characters for the test + Settings.getPassRegex = "[a-zA-Z0-9]+"; + Settings.getPasswordMinLen = 2; + Settings.passwordMaxLength = 50; + + // TODO ljacqu 20151121: Cannot mock getServer() as it's final + // Probably the Command class should delegate as the others do + /* + Server server = Mockito.mock(Server.class); + schedulerMock = Mockito.mock(BukkitScheduler.class); + Mockito.when(server.getScheduler()).thenReturn(schedulerMock); + Mockito.when(pluginMock.getServer()).thenReturn(server); + */ + } + + @Test + public void shouldRejectNonPlayerSender() { + // given + CommandSender sender = mock(BlockCommandSender.class); + ChangePasswordCommand command = new ChangePasswordCommand(); + CommandParts arguments = mock(CommandParts.class); + + // when + command.executeCommand(sender, new CommandParts(), arguments); + + // then + verify(arguments, never()).get(anyInt()); + //verify(pluginMock, never()).getServer(); + } + + @Test + public void shouldRejectNotLoggedInPlayer() { + // given + CommandSender sender = initPlayerWithName("name", false); + ChangePasswordCommand command = new ChangePasswordCommand(); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts("pass")); + + // then + verify(messagesMock).send(sender, "not_logged_in"); + //verify(pluginMock, never()).getServer(); + } + + @Test + public void shouldDenyInvalidPassword() { + // given + CommandSender sender = initPlayerWithName("name", true); + ChangePasswordCommand command = new ChangePasswordCommand(); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts("!pass")); + + // then + verify(messagesMock).send(sender, "password_error"); + //verify(pluginMock, never()).getServer(); + } + + + @Test + public void shouldRejectPasswordEqualToNick() { + // given + CommandSender sender = initPlayerWithName("tester", true); + ChangePasswordCommand command = new ChangePasswordCommand(); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts("Tester")); + + // then + verify(messagesMock).send(sender, "password_error_nick"); + //verify(pluginMock, never()).getServer(); + } + + @Test + public void shouldRejectTooLongPassword() { + // given + CommandSender sender = initPlayerWithName("abc12", true); + ChangePasswordCommand command = new ChangePasswordCommand(); + Settings.passwordMaxLength = 3; + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts("test")); + + // then + verify(messagesMock).send(sender, "pass_len"); + //verify(pluginMock, never()).getServer(); + } + + @Test + public void shouldRejectTooShortPassword() { + // given + CommandSender sender = initPlayerWithName("abc12", true); + ChangePasswordCommand command = new ChangePasswordCommand(); + Settings.getPasswordMinLen = 7; + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts("tester")); + + // then + verify(messagesMock).send(sender, "pass_len"); + //verify(pluginMock, never()).getServer(); + } + + @Test + public void shouldRejectUnsafeCustomPassword() { + // given + CommandSender sender = initPlayerWithName("player", true); + ChangePasswordCommand command = new ChangePasswordCommand(); + Settings.unsafePasswords = Arrays.asList("test", "abc123"); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts("abc123")); + + // then + verify(messagesMock).send(sender, "password_error_unsafe"); + //verify(pluginMock, never()).getServer(); + } + + private Player initPlayerWithName(String name, boolean loggedIn) { + Player player = mock(Player.class); + when(player.getName()).thenReturn(name); + when(cacheMock.isAuthenticated(name)).thenReturn(loggedIn); + return player; + } + +} diff --git a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java new file mode 100644 index 000000000..795fe1bec --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java @@ -0,0 +1,63 @@ +package fr.xephi.authme.command.executable.email; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.AuthMeMockUtil; +import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.process.Management; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.Arrays; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Test for {@link AddEmailCommand}. + */ +public class AddEmailCommandTest { + + private AuthMe authMeMock; + private Management managementMock; + + @Before + public void setUpMocks() { + AuthMeMockUtil.mockAuthMeInstance(); + authMeMock = AuthMe.getInstance(); + managementMock = Mockito.mock(Management.class); + when(authMeMock.getManagement()).thenReturn(managementMock); + } + + @Test + public void shouldRejectNonPlayerSender() { + // given + CommandSender sender = Mockito.mock(BlockCommandSender.class); + AddEmailCommand command = new AddEmailCommand(); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts()); + + // then + verify(authMeMock, never()).getManagement(); + } + + @Test + public void shouldForwardData() { + // given + Player sender = Mockito.mock(Player.class); + AddEmailCommand command = new AddEmailCommand(); + + // when + command.executeCommand(sender, new CommandParts(), + new CommandParts(Arrays.asList("mail@example", "other_example"))); + + // then + verify(authMeMock).getManagement(); + verify(managementMock).performAddEmail(sender, "mail@example", "other_example"); + } +} diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java new file mode 100644 index 000000000..db6e6b84e --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java @@ -0,0 +1,63 @@ +package fr.xephi.authme.command.executable.email; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.AuthMeMockUtil; +import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.process.Management; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.Arrays; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Test for {@link ChangeEmailCommand}. + */ +public class ChangeEmailCommandTest { + + private AuthMe authMeMock; + private Management managementMock; + + @Before + public void setUpMocks() { + AuthMeMockUtil.mockAuthMeInstance(); + authMeMock = AuthMe.getInstance(); + managementMock = Mockito.mock(Management.class); + when(authMeMock.getManagement()).thenReturn(managementMock); + } + + @Test + public void shouldRejectNonPlayerSender() { + // given + CommandSender sender = Mockito.mock(BlockCommandSender.class); + ChangeEmailCommand command = new ChangeEmailCommand(); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts()); + + // then + verify(authMeMock, never()).getManagement(); + } + + @Test + public void shouldForwardData() { + // given + Player sender = Mockito.mock(Player.class); + ChangeEmailCommand command = new ChangeEmailCommand(); + + // when + command.executeCommand(sender, new CommandParts(), + new CommandParts(Arrays.asList("new.mail@example.org", "old_mail@example.org"))); + + // then + verify(authMeMock).getManagement(); + verify(managementMock).performChangeEmail(sender, "new.mail@example.org", "old_mail@example.org"); + } +} diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java new file mode 100644 index 000000000..bd1e2e442 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -0,0 +1,36 @@ +package fr.xephi.authme.command.executable.email; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.AuthMeMockUtil; +import fr.xephi.authme.command.CommandParts; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +/** + * Test for {@link RecoverEmailCommand}. + */ +public class RecoverEmailCommandTest { + + @Before + public void setUpMocks() { + AuthMeMockUtil.mockAuthMeInstance(); + } + + @Test + public void shouldRejectNonPlayerSender() { + // given + CommandSender sender = Mockito.mock(BlockCommandSender.class); + RecoverEmailCommand command = new RecoverEmailCommand(); + + // when + command.executeCommand(sender, new CommandParts(), new CommandParts()); + + // then + } + + // TODO ljacqu 20151121: Expand tests. This command doesn't use a scheduler and has all of its + // logic inside here. +} diff --git a/src/test/java/fr/xephi/authme/util/StringUtilsTest.java b/src/test/java/fr/xephi/authme/util/StringUtilsTest.java index 47d183979..e2270b361 100644 --- a/src/test/java/fr/xephi/authme/util/StringUtilsTest.java +++ b/src/test/java/fr/xephi/authme/util/StringUtilsTest.java @@ -6,7 +6,9 @@ import java.net.MalformedURLException; import java.util.Arrays; import java.util.List; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.stringContainsInOrder; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -97,4 +99,32 @@ public class StringUtilsTest { // then assertThat(result, equalTo("[MalformedURLException]: Unrecognized URL format")); } + + @Test + public void shouldPrintStackTrace() { + // given + MalformedURLException ex = new MalformedURLException("Unrecognized URL format"); + + // when + String result = StringUtils.getStackTrace(ex); + + // then + assertThat(result, stringContainsInOrder(getClass().getName())); + } + + @Test + public void shouldGetDifferenceWithNullString() { + // given/when/then + assertThat(StringUtils.getDifference(null, "test"), equalTo(1.0)); + assertThat(StringUtils.getDifference("test", null), equalTo(1.0)); + assertThat(StringUtils.getDifference(null, null), equalTo(1.0)); + } + + @Test + public void shouldGetDifferenceBetweenTwoString() { + // given/when/then + assertThat(StringUtils.getDifference("test", "taste"), equalTo(0.4)); + assertThat(StringUtils.getDifference("test", "bear"), equalTo(0.75)); + assertThat(StringUtils.getDifference("test", "something"), greaterThan(0.88)); + } } diff --git a/src/test/java/fr/xephi/authme/util/UtilsTest.java b/src/test/java/fr/xephi/authme/util/UtilsTest.java index f228947f8..586b81f3e 100644 --- a/src/test/java/fr/xephi/authme/util/UtilsTest.java +++ b/src/test/java/fr/xephi/authme/util/UtilsTest.java @@ -2,63 +2,44 @@ package fr.xephi.authme.util; import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMeMockUtil; -import fr.xephi.authme.WrapperMock; +import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.permission.PermissionsManager; -import org.bukkit.Server; +import fr.xephi.authme.settings.Settings; +import org.bukkit.GameMode; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; +import org.mockito.Mockito; import java.lang.reflect.Field; import java.util.Collection; +import java.util.logging.Logger; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.*; /** * Test for the {@link Utils} class. */ -@Ignore -// TODO ljacqu 20151123: Fix test setup public class UtilsTest { private AuthMe authMeMock; private PermissionsManager permissionsManagerMock; - private Wrapper wrapperMock; @Before public void setUpMocks() { authMeMock = AuthMeMockUtil.mockAuthMeInstance(); - - // We need to create the Wrapper mock before injecting it into Utils because it runs a lot of code in - // a static block which needs the proper mocks to be set up. - wrapperMock = new WrapperMock(authMeMock); - Server serverMock = wrapperMock.getServer(); - - BukkitScheduler schedulerMock = mock(BukkitScheduler.class); - when(serverMock.getScheduler()).thenReturn(schedulerMock); - - - when(schedulerMock.runTaskAsynchronously(any(Plugin.class), any(Runnable.class))) - .thenReturn(mock(BukkitTask.class)); - - System.out.println("Initialized scheduler mock for server mock"); - AuthMeMockUtil.insertMockWrapperInstance(Utils.class, "wrapper", (WrapperMock) wrapperMock); - System.out.println("Iniadfk"); - - permissionsManagerMock = mock(PermissionsManager.class); + AuthMeMockUtil.mockSingletonForClass(Utils.class, "plugin", authMeMock); + permissionsManagerMock = Mockito.mock(PermissionsManager.class); when(authMeMock.getPermissionsManager()).thenReturn(permissionsManagerMock); + + AuthMeMockUtil.initializeWrapperMock(); } - // TODO ljacques 20151122: The tests for Utils.forceGM somehow can't be set up with the mocks correctly - /*@Test + @Test public void shouldForceSurvivalGameMode() { // given Player player = mock(Player.class); @@ -68,6 +49,7 @@ public class UtilsTest { Utils.forceGM(player); // then + verify(authMeMock).getPermissionsManager(); verify(player).setGameMode(GameMode.SURVIVAL); } @@ -84,10 +66,40 @@ public class UtilsTest { verify(authMeMock).getPermissionsManager(); verify(permissionsManagerMock).hasPermission(player, "authme.bypassforcesurvival"); verify(player, never()).setGameMode(any(GameMode.class)); - }*/ + } @Test - // Note ljacqu 20151122: This is a heavy test setup with Reflections... If it causes trouble, skip it with @Ignore + public void shouldNotAddToNormalGroupIfPermissionsAreDisabled() { + // given + Settings.isPermissionCheckEnabled = false; + Player player = mock(Player.class); + + // when + boolean result = Utils.addNormal(player, "test_group"); + + // then + assertThat(result, equalTo(false)); + verify(authMeMock, never()).getPermissionsManager(); + } + + @Test + public void shouldNotAddToNormalGroupIfPermManagerIsNull() { + // given + Settings.isPermissionCheckEnabled = true; + given(authMeMock.getPermissionsManager()).willReturn(null); + Player player = mock(Player.class); + AuthMeMockUtil.mockSingletonForClass(ConsoleLogger.class, "wrapper", Wrapper.getInstance()); + + // when + boolean result = Utils.addNormal(player, "test_group"); + + // then + assertThat(result, equalTo(false)); + verify(authMeMock).getPermissionsManager(); + } + + @Test + // Note ljacqu 20151122: This is a heavy test setup with reflections... If it causes trouble, skip it with @Ignore public void shouldRetrieveListOfOnlinePlayersFromReflectedMethod() { // given setField("getOnlinePlayersIsCollection", false); @@ -114,6 +126,7 @@ public class UtilsTest { } } + // Note: This method is used through reflections public static Player[] onlinePlayersImpl() { return new Player[]{ mock(Player.class), mock(Player.class) diff --git a/src/test/java/fr/xephi/authme/WrapperMock.java b/src/test/java/fr/xephi/authme/util/WrapperMock.java similarity index 86% rename from src/test/java/fr/xephi/authme/WrapperMock.java rename to src/test/java/fr/xephi/authme/util/WrapperMock.java index 7812c6d33..1517d929b 100644 --- a/src/test/java/fr/xephi/authme/WrapperMock.java +++ b/src/test/java/fr/xephi/authme/util/WrapperMock.java @@ -1,6 +1,6 @@ -package fr.xephi.authme; +package fr.xephi.authme.util; -import fr.xephi.authme.util.Wrapper; +import fr.xephi.authme.AuthMe; import org.bukkit.Server; import org.bukkit.scheduler.BukkitScheduler; import org.mockito.Mockito; @@ -19,11 +19,7 @@ public class WrapperMock extends Wrapper { private static Map, Object> mocks = new HashMap<>(); public WrapperMock() { - this((AuthMe) getMock(AuthMe.class)); - } - - public WrapperMock(AuthMe authMe) { - super(authMe); + super(); } @Override