#305 Fix label handling, add extensive tests for command handler

This commit is contained in:
ljacqu
2015-12-19 16:27:00 +01:00
parent 42c34c56a0
commit a928a4092d
3 changed files with 231 additions and 17 deletions
@@ -1,25 +1,38 @@
package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission;
import org.bukkit.command.CommandSender;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Test for {@link CommandHandler}.
@@ -32,17 +45,36 @@ public class CommandHandlerTest {
@BeforeClass
public static void setUpCommandHandler() {
// Register /authme
CommandDescription authMeBase = createCommand(null, null, singletonList("authme"));
// Register /authme login <password>
createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"), newArgument("password", false));
// Register /authme register <password> <confirmation>, alias: /authme reg
createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg"),
newArgument("password", false), newArgument("confirmation", false));
CommandDescription testBase = createCommand(null, null, singletonList("test"), newArgument("test", true));
commands = new HashSet<>(asList(authMeBase, testBase));
// Register /email [player]
CommandDescription emailBase = createCommand(null, null, singletonList("email"));
// Register /email helptest -- use only to test for help command arguments special case
CommandDescription.builder().parent(emailBase).labels("helptest").executableCommand(mock(HelpCommand.class))
.description("test").detailedDescription("Test.").withArgument("Query", "", false).build();
// Register /unregister <player>, alias: /unreg
CommandDescription unregisterBase = createCommand(null, null, asList("unregister", "unreg"),
newArgument("player", false));
commands = newHashSet(authMeBase, emailBase, unregisterBase);
}
@Before
public void setUpMocks() {
permissionsManagerMock = mock(PermissionsManager.class);
handler = new CommandHandler(commands, permissionsManagerMock);
}
// -----------
// mapPartsToCommand() tests
// -----------
@Test
public void shouldMapPartsToLoginChildCommand() {
// given
@@ -56,6 +88,8 @@ public class CommandHandlerTest {
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.SUCCESS));
assertThat(result.getArguments(), contains("test1"));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), contains(parts.get(2)));
}
@Test
@@ -69,6 +103,7 @@ public class CommandHandlerTest {
// then
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.SUCCESS));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), contains("arg1", "arg2"));
assertThat(result.getDifference(), equalTo(0.0));
}
@@ -85,6 +120,8 @@ public class CommandHandlerTest {
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), equalTo(parts.subList(2, 5)));
}
@Test
@@ -99,6 +136,8 @@ public class CommandHandlerTest {
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getLabels(), equalTo(parts));
assertThat(result.getArguments(), empty());
}
@Test
@@ -113,6 +152,8 @@ public class CommandHandlerTest {
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.UNKNOWN_LABEL));
assertThat(result.getDifference() < 0.75, equalTo(true));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), contains("pass123", "pass123"));
}
/** In contrast to the previous test, we test a command request with a very apart label. */
@@ -128,8 +169,172 @@ public class CommandHandlerTest {
assertThat(result.getCommandDescription(), not(nullValue()));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.UNKNOWN_LABEL));
assertThat(result.getDifference() > 0.75, equalTo(true));
assertThat(result.getLabels(), equalTo(parts));
assertThat(result.getArguments(), empty());
}
@Test
public void shouldHandleBaseWithWrongArguments() {
// given
List<String> parts = singletonList("unregister");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getCommandDescription(), equalTo(getCommandWithLabel("unregister", commands)));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getArguments(), empty());
assertThat(result.getLabels(), equalTo(parts));
}
@Test
public void shouldHandleUnknownBase() {
// given
List<String> parts = asList("bogus", "label1", "arg1");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.MISSING_BASE_COMMAND));
assertThat(result.getCommandDescription(), nullValue());
}
@Test
public void shouldHandleNullInput() {
// given / when
FoundCommandResult result = handler.mapPartsToCommand(null);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.MISSING_BASE_COMMAND));
assertThat(result.getCommandDescription(), nullValue());
}
@Test
public void shouldMapToBaseWithProperArguments() {
// given
List<String> parts = asList("Unreg", "player1");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.SUCCESS));
assertThat(result.getCommandDescription(), equalTo(getCommandWithLabel("unregister", commands)));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getArguments(), contains("player1"));
assertThat(result.getLabels(), contains("Unreg"));
}
@Test
public void shouldReturnChildlessBaseCommandWithArgCountError() {
// given
List<String> parts = asList("unregistER", "player1", "wrongArg");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getCommandDescription(), equalTo(getCommandWithLabel("unregister", commands)));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getArguments(), contains("player1", "wrongArg"));
assertThat(result.getLabels(), contains("unregistER"));
}
// ----------
// processCommand() tests
// ----------
@Test
public void shouldCallMappedCommandWithArgs() {
// given
String bukkitLabel = "Authme";
String[] bukkitArgs = {"Login", "myPass"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = getChildWithLabel("login", "authme");
given(permissionsManagerMock.hasPermission(sender, command)).willReturn(true);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
ArgumentCaptor<List> argsCaptor = ArgumentCaptor.forClass(List.class);
verify(command.getExecutableCommand()).executeCommand(eq(sender), argsCaptor.capture());
List<String> argument = argsCaptor.getValue();
assertThat(argument, contains("myPass"));
// Ensure that no error message was issued to the command sender
verify(sender, never()).sendMessage(anyString());
}
@Test
public void shouldNotCallExecutableCommandIfNoPermission() {
// given
String bukkitLabel = "unreg";
String[] bukkitArgs = {"testPlayer"};
CommandSender sender = mock(CommandSender.class);
given(permissionsManagerMock.hasPermission(any(CommandSender.class), any(CommandDescription.class)))
.willReturn(false);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
CommandDescription command = getCommandWithLabel("unregister", commands);
verify(permissionsManagerMock).hasPermission(sender, command);
verify(command.getExecutableCommand(), never())
.executeCommand(any(CommandSender.class), anyListOf(String.class));
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(messageCaptor.capture());
String message = messageCaptor.getValue();
assertThat(message, stringContainsInOrder("You don't have permission"));
}
@Test
public void shouldStripWhitespace() {
// given
String bukkitLabel = "AuthMe";
String[] bukkitArgs = {" ", "", "LOGIN", " ", "testArg", " "};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = getChildWithLabel("login", "authme");
given(permissionsManagerMock.hasPermission(sender, command)).willReturn(true);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
ArgumentCaptor<List> argsCaptor = ArgumentCaptor.forClass(List.class);
verify(command.getExecutableCommand()).executeCommand(eq(sender), argsCaptor.capture());
List<String> arguments = argsCaptor.getValue();
assertThat(arguments, contains("testArg"));
verify(sender, never()).sendMessage(anyString());
}
@Test
public void shouldPassCommandPathAsArgumentsToHelpCommand() {
// given
String bukkitLabel = "email";
String[] bukkitArgs = {"helptest", "arg1"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = getChildWithLabel("helptest", "email");
given(permissionsManagerMock.hasPermission(sender, command)).willReturn(true);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
ArgumentCaptor<List> argsCaptor = ArgumentCaptor.forClass(List.class);
verify(command.getExecutableCommand()).executeCommand(eq(sender), argsCaptor.capture());
List<String> arguments = argsCaptor.getValue();
assertThat(arguments, contains("email", "arg1"));
}
// ----------
// Helper methods
// ----------
@@ -163,7 +368,7 @@ public class CommandHandlerTest {
private static CommandDescription getCommandWithLabel(String label, Collection<CommandDescription> commands) {
for (CommandDescription child : commands) {
if (child.getLabels().contains(label)) {
if (child.hasLabel(label)) {
return child;
}
}