From 2e269b6f5e5c610d3d849a7d15284f6f6f2c6a8c Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 5 Jun 2016 13:21:05 +0200 Subject: [PATCH] Add missing unit tests for commands --- .../executable/authme/ConverterCommand.java | 4 +- .../unregister/UnregisterCommand.java | 5 +- .../command/executable/HelpCommandTest.java | 158 +++++++++++++++ .../authme/ConverterCommandTest.java | 104 ++++++++++ .../authme/SetEmailCommandTest.java | 188 ++++++++++++++++++ .../authme/UnregisterAdminCommandTest.java | 71 +++++++ .../unregister/UnregisterCommandTest.java | 74 +++++++ 7 files changed, 602 insertions(+), 2 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java create mode 100644 src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java create mode 100644 src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java create mode 100644 src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java create mode 100644 src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java index 4c2865b5f..e18c9dc4e 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java @@ -1,5 +1,6 @@ package fr.xephi.authme.command.executable.authme; +import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.converter.Converter; @@ -58,7 +59,8 @@ public class ConverterCommand implements ExecutableCommand { sender.sendMessage("[AuthMe] Successfully converted from " + jobType.getName()); } - private enum ConvertType { + @VisibleForTesting + enum ConvertType { XAUTH("xauth", xAuthConverter.class), CRAZYLOGIN("crazylogin", CrazyLoginConverter.class), RAKAMAK("rakamak", RakamakConverter.class), diff --git a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java index e289480e0..720b136e1 100644 --- a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java @@ -18,13 +18,16 @@ public class UnregisterCommand extends PlayerCommand { @Inject private CommandService commandService; + @Inject + private PlayerCache playerCache; + @Override public void runCommand(Player player, List arguments) { String playerPass = arguments.get(0); final String playerNameLowerCase = player.getName().toLowerCase(); // Make sure the player is authenticated - if (!PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { + if (!playerCache.isAuthenticated(playerNameLowerCase)) { commandService.send(player, MessageKey.NOT_LOGGED_IN); return; } diff --git a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java new file mode 100644 index 000000000..143ae26b8 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java @@ -0,0 +1,158 @@ +package fr.xephi.authme.command.executable; + +import fr.xephi.authme.command.CommandDescription; +import fr.xephi.authme.command.CommandMapper; +import fr.xephi.authme.command.FoundCommandResult; +import fr.xephi.authme.command.help.HelpProvider; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.Collections; +import java.util.List; + +import static fr.xephi.authme.command.FoundResultStatus.INCORRECT_ARGUMENTS; +import static fr.xephi.authme.command.FoundResultStatus.MISSING_BASE_COMMAND; +import static fr.xephi.authme.command.FoundResultStatus.SUCCESS; +import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Test for {@link HelpCommand}. + */ +@RunWith(MockitoJUnitRunner.class) +public class HelpCommandTest { + + @InjectMocks + private HelpCommand command; + + @Mock + private CommandMapper commandMapper; + + @Mock + private HelpProvider helpProvider; + + @Test + public void shouldHandleMissingBaseCommand() { + // given + List arguments = asList("some", "command"); + CommandSender sender = mock(CommandSender.class); + FoundCommandResult foundCommandResult = new FoundCommandResult(null, null, null, 0.0, MISSING_BASE_COMMAND); + given(commandMapper.mapPartsToCommand(sender, arguments)).willReturn(foundCommandResult); + + // when + command.executeCommand(sender, arguments); + + // then + verify(sender).sendMessage(argThat(containsString("Could not get base command"))); + verifyZeroInteractions(helpProvider); + } + + @Test + public void shouldHandleWrongCommandWithSuggestion() { + // given + List arguments = asList("authme", "ragister", "test"); + CommandSender sender = mock(CommandSender.class); + CommandDescription description = newCommandDescription("authme", "register"); + FoundCommandResult foundCommandResult = new FoundCommandResult(description, asList("authme", "ragister"), + singletonList("test"), 0.1, UNKNOWN_LABEL); + given(commandMapper.mapPartsToCommand(sender, arguments)).willReturn(foundCommandResult); + + // when + command.executeCommand(sender, arguments); + + // then + ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); + verify(sender).sendMessage(captor.capture()); + assertThat(removeColors(captor.getValue()), containsString("Assuming /authme register")); + verify(helpProvider).outputHelp(sender, foundCommandResult, HelpProvider.ALL_OPTIONS); + } + + @Test + public void shouldHandleWrongCommandWithoutSuggestion() { + List arguments = asList("authme", "ragister", "test"); + CommandSender sender = mock(CommandSender.class); + FoundCommandResult foundCommandResult = new FoundCommandResult(null, asList("authme", "ragister"), + singletonList("test"), 0.4, UNKNOWN_LABEL); + given(commandMapper.mapPartsToCommand(sender, arguments)).willReturn(foundCommandResult); + + // when + command.executeCommand(sender, arguments); + + // then + ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); + verify(sender).sendMessage(captor.capture()); + assertThat(removeColors(captor.getValue()), containsString("Unknown command")); + verifyZeroInteractions(helpProvider); + } + + @Test + public void shouldShowChildrenOfBaseCommand() { + List arguments = singletonList("authme"); + CommandSender sender = mock(CommandSender.class); + CommandDescription commandDescription = mock(CommandDescription.class); + given(commandDescription.getLabelCount()).willReturn(1); + FoundCommandResult foundCommandResult = new FoundCommandResult(commandDescription, singletonList("authme"), + Collections.emptyList(), 0.0, SUCCESS); + given(commandMapper.mapPartsToCommand(sender, arguments)).willReturn(foundCommandResult); + + // when + command.executeCommand(sender, arguments); + + // then + verify(sender, never()).sendMessage(anyString()); + verify(helpProvider).outputHelp(sender, foundCommandResult, HelpProvider.SHOW_CHILDREN); + } + + @Test + public void shouldShowDetailedHelpForChildCommand() { + List arguments = asList("authme", "getpos"); + CommandSender sender = mock(CommandSender.class); + CommandDescription commandDescription = mock(CommandDescription.class); + given(commandDescription.getLabelCount()).willReturn(2); + FoundCommandResult foundCommandResult = new FoundCommandResult(commandDescription, asList("authme", "getpos"), + Collections.emptyList(), 0.0, INCORRECT_ARGUMENTS); + given(commandMapper.mapPartsToCommand(sender, arguments)).willReturn(foundCommandResult); + + // when + command.executeCommand(sender, arguments); + + // then + verify(sender, never()).sendMessage(anyString()); + verify(helpProvider).outputHelp(sender, foundCommandResult, HelpProvider.ALL_OPTIONS); + } + + private static CommandDescription newCommandDescription(String... labels) { + CommandDescription parent = null; + // iterate through the labels backwards so we can set the parent + for (String label : labels) { + CommandDescription description = mock(CommandDescription.class); + given(description.getParent()).willReturn(parent); + given(description.getLabels()).willReturn(singletonList(label)); + parent = description; + } + return parent; + } + + private static String removeColors(String str) { + for (ChatColor color : ChatColor.values()) { + str = str.replace(color.toString(), ""); + } + return str; + } +} diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java new file mode 100644 index 000000000..5f781752f --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java @@ -0,0 +1,104 @@ +package fr.xephi.authme.command.executable.authme; + +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.converter.RakamakConverter; +import fr.xephi.authme.initialization.AuthMeServiceInitializer; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.util.BukkitService; +import org.bukkit.command.CommandSender; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Test for {@link ConverterCommand}. + */ +@RunWith(MockitoJUnitRunner.class) +public class ConverterCommandTest { + + @InjectMocks + private ConverterCommand command; + + @Mock + private CommandService commandService; + + @Mock + private BukkitService bukkitService; + + @Mock + private AuthMeServiceInitializer initializer; + + @Test + public void shouldHandleUnknownConversionType() { + // given + CommandSender sender = mock(CommandSender.class); + + // when + command.executeCommand(sender, Collections.singletonList("invalid")); + + // then + verify(commandService).send(sender, MessageKey.ERROR); + verifyNoMoreInteractions(commandService); + verifyZeroInteractions(initializer); + verifyZeroInteractions(bukkitService); + } + + @Test + public void shouldHaveUniqueNameAndClassForEachType() { + // given + ConverterCommand.ConvertType[] types = ConverterCommand.ConvertType.values(); + List names = new ArrayList<>(types.length); + List> classes = new ArrayList<>(types.length); + + // when / then + for (ConverterCommand.ConvertType type : types) { + assertThat("Name for '" + type + "' is not null", + type.getName(), not(nullValue())); + assertThat("Class for '" + type + "' is not null", + type.getConverterClass(), not(nullValue())); + assertThat("Name '" + type.getName() + "' is unique", + names, not(hasItem(type.getName()))); + assertThat("Class '" + type.getConverterClass() + "' is unique", + classes, not(hasItem(type.getConverterClass()))); + names.add(type.getName()); + classes.add(type.getConverterClass()); + } + } + + @Test + public void shouldLaunchConverterForAllTypes() { + // given + ConverterCommand.ConvertType type = ConverterCommand.ConvertType.RAKAMAK; + RakamakConverter converter = mock(RakamakConverter.class); + given(initializer.newInstance(RakamakConverter.class)).willReturn(converter); + CommandSender sender = mock(CommandSender.class); + + // when + command.executeCommand(sender, Collections.singletonList(type.getName())); + TestHelper.runInnerRunnable(bukkitService); + + // then + verify(converter).execute(sender); + verifyNoMoreInteractions(converter); + verify(initializer).newInstance(type.getConverterClass()); + verifyNoMoreInteractions(initializer); + } + +} diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java new file mode 100644 index 000000000..26d118445 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java @@ -0,0 +1,188 @@ +package fr.xephi.authme.command.executable.authme; + +import fr.xephi.authme.cache.auth.PlayerAuth; +import fr.xephi.authme.cache.auth.PlayerCache; +import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.util.BukkitService; +import org.bukkit.command.CommandSender; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.Arrays; + +import static fr.xephi.authme.TestHelper.runInnerRunnable; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Test for {@link SetEmailCommand}. + */ +@RunWith(MockitoJUnitRunner.class) +public class SetEmailCommandTest { + + @InjectMocks + private SetEmailCommand command; + + @Mock + private DataSource dataSource; + + @Mock + private CommandService commandService; + + @Mock + private PlayerCache playerCache; + + @Mock + private BukkitService bukkitService; + + @Test + public void shouldRejectInvalidMail() { + // given + String user = "somebody"; + String email = "some.test@example.org"; + given(commandService.validateEmail(email)).willReturn(false); + CommandSender sender = mock(CommandSender.class); + + // when + command.executeCommand(sender, Arrays.asList(user, email)); + + // then + verify(commandService).validateEmail(email); + verify(commandService).send(sender, MessageKey.INVALID_EMAIL); + verifyZeroInteractions(dataSource); + } + + @Test + public void shouldHandleUnknownUser() { + // given + String user = "nonexistent"; + String email = "mail@example.com"; + given(commandService.validateEmail(email)).willReturn(true); + given(dataSource.getAuth(user)).willReturn(null); + CommandSender sender = mock(CommandSender.class); + + // when + command.executeCommand(sender, Arrays.asList(user, email)); + runInnerRunnable(bukkitService); + + // then + verify(commandService).validateEmail(email); + verify(dataSource).getAuth(user); + verify(commandService).send(sender, MessageKey.UNKNOWN_USER); + verifyNoMoreInteractions(dataSource); + } + + @Test + public void shouldHandleAlreadyTakenEmail() { + // given + String user = "someone"; + String email = "mail@example.com"; + given(commandService.validateEmail(email)).willReturn(true); + PlayerAuth auth = mock(PlayerAuth.class); + given(dataSource.getAuth(user)).willReturn(auth); + CommandSender sender = mock(CommandSender.class); + given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(false); + + // when + command.executeCommand(sender, Arrays.asList(user, email)); + runInnerRunnable(bukkitService); + + // then + verify(commandService).validateEmail(email); + verify(dataSource).getAuth(user); + verify(commandService).isEmailFreeForRegistration(email, sender); + verify(commandService).send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR); + verifyNoMoreInteractions(dataSource); + verifyZeroInteractions(auth); + } + + @Test + public void shouldHandlePersistenceError() { + // given + String user = "Bobby"; + String email = "new-addr@example.org"; + given(commandService.validateEmail(email)).willReturn(true); + PlayerAuth auth = mock(PlayerAuth.class); + given(dataSource.getAuth(user)).willReturn(auth); + CommandSender sender = mock(CommandSender.class); + given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(true); + given(dataSource.updateEmail(auth)).willReturn(false); + + // when + command.executeCommand(sender, Arrays.asList(user, email)); + runInnerRunnable(bukkitService); + + // then + verify(commandService).validateEmail(email); + verify(dataSource).getAuth(user); + verify(commandService).isEmailFreeForRegistration(email, sender); + verify(commandService).send(sender, MessageKey.ERROR); + verify(dataSource).updateEmail(auth); + verifyNoMoreInteractions(dataSource); + } + + @Test + public void shouldUpdateEmail() { + // given + String user = "Bobby"; + String email = "new-addr@example.org"; + given(commandService.validateEmail(email)).willReturn(true); + PlayerAuth auth = mock(PlayerAuth.class); + given(dataSource.getAuth(user)).willReturn(auth); + CommandSender sender = mock(CommandSender.class); + given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(true); + given(dataSource.updateEmail(auth)).willReturn(true); + given(playerCache.getAuth(user)).willReturn(null); + + // when + command.executeCommand(sender, Arrays.asList(user, email)); + runInnerRunnable(bukkitService); + + // then + verify(commandService).validateEmail(email); + verify(dataSource).getAuth(user); + verify(commandService).isEmailFreeForRegistration(email, sender); + verify(commandService).send(sender, MessageKey.EMAIL_CHANGED_SUCCESS); + verify(dataSource).updateEmail(auth); + verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); + verifyNoMoreInteractions(dataSource); + } + + @Test + public void shouldUpdateEmailAndPlayerCache() { + // given + String user = "Bobby"; + String email = "new-addr@example.org"; + given(commandService.validateEmail(email)).willReturn(true); + PlayerAuth auth = mock(PlayerAuth.class); + given(dataSource.getAuth(user)).willReturn(auth); + CommandSender sender = mock(CommandSender.class); + given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(true); + given(dataSource.updateEmail(auth)).willReturn(true); + given(playerCache.getAuth(user)).willReturn(mock(PlayerAuth.class)); + + // when + command.executeCommand(sender, Arrays.asList(user, email)); + runInnerRunnable(bukkitService); + + // then + verify(commandService).validateEmail(email); + verify(dataSource).getAuth(user); + verify(commandService).isEmailFreeForRegistration(email, sender); + verify(commandService).send(sender, MessageKey.EMAIL_CHANGED_SUCCESS); + verify(dataSource).updateEmail(auth); + verify(playerCache).updatePlayer(auth); + verifyNoMoreInteractions(dataSource); + } + +} diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java new file mode 100644 index 000000000..f41eeb202 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java @@ -0,0 +1,71 @@ +package fr.xephi.authme.command.executable.authme; + +import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.output.MessageKey; +import org.bukkit.command.CommandSender; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.Collections; + +import static org.hamcrest.Matchers.equalToIgnoringCase; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +/** + * Test for {@link UnregisterAdminCommand}. + */ +@RunWith(MockitoJUnitRunner.class) +public class UnregisterAdminCommandTest { + + @InjectMocks + private UnregisterAdminCommand command; + + @Mock + private DataSource dataSource; + + @Mock + private CommandService commandService; + + @Test + public void shouldHandleUnknownPlayer() { + // given + String user = "bobby"; + given(dataSource.isAuthAvailable(user)).willReturn(false); + CommandSender sender = mock(CommandSender.class); + + // when + command.executeCommand(sender, Collections.singletonList(user)); + + // then + verify(dataSource).isAuthAvailable(user); + verifyNoMoreInteractions(dataSource); + verify(commandService).send(sender, MessageKey.UNKNOWN_USER); + } + + @Test + public void shouldHandleDatabaseError() { + // given + String user = "personaNonGrata"; + given(dataSource.isAuthAvailable(argThat(equalToIgnoringCase(user)))).willReturn(true); + given(dataSource.removeAuth(argThat(equalToIgnoringCase(user)))).willReturn(false); + CommandSender sender = mock(CommandSender.class); + + // when + command.executeCommand(sender, Collections.singletonList(user)); + + // then + verify(dataSource).isAuthAvailable(argThat(equalToIgnoringCase(user))); + verify(dataSource).removeAuth(argThat(equalToIgnoringCase(user))); + verifyNoMoreInteractions(dataSource); + verify(commandService).send(sender, MessageKey.ERROR); + } + +} diff --git a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java new file mode 100644 index 000000000..976649aea --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java @@ -0,0 +1,74 @@ +package fr.xephi.authme.command.executable.unregister; + +import fr.xephi.authme.cache.auth.PlayerCache; +import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.process.Management; +import org.bukkit.entity.Player; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.Collections; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Test for {@link UnregisterCommand}. + */ +@RunWith(MockitoJUnitRunner.class) +public class UnregisterCommandTest { + + @InjectMocks + private UnregisterCommand command; + + @Mock + private Management management; + + @Mock + private CommandService commandService; + + @Mock + private PlayerCache playerCache; + + @Test + public void shouldCatchUnauthenticatedUser() { + // given + String password = "mySecret123"; + String name = "player77"; + Player player = mock(Player.class); + given(player.getName()).willReturn(name); + given(playerCache.isAuthenticated(name)).willReturn(false); + + // when + command.executeCommand(player, Collections.singletonList(password)); + + // then + verify(playerCache).isAuthenticated(name); + verify(commandService).send(player, MessageKey.NOT_LOGGED_IN); + verifyZeroInteractions(management); + } + + @Test + public void shouldForwardDataToAsyncTask() { + // given + String password = "p@ssw0rD"; + String name = "jas0n_"; + Player player = mock(Player.class); + given(player.getName()).willReturn(name); + given(playerCache.isAuthenticated(name)).willReturn(true); + + // when + command.executeCommand(player, Collections.singletonList(password)); + + // then + verify(playerCache).isAuthenticated(name); + verify(management).performUnregister(player, password, false); + } + +}