mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-05 01:59:34 +01:00
Unit test ConsoleLogger + clean up and unit test RecoverEmailCommand
This commit is contained in:
parent
a8df8ceb09
commit
914462fc3f
@ -44,36 +44,27 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
commandService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
|
||||
return;
|
||||
}
|
||||
if (dataSource.isAuthAvailable(playerName)) {
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerAuth auth;
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
auth = playerCache.getAuth(playerName);
|
||||
} else if (dataSource.isAuthAvailable(playerName)) {
|
||||
auth = dataSource.getAuth(playerName);
|
||||
} else {
|
||||
commandService.send(player, MessageKey.UNKNOWN_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerMail.equalsIgnoreCase(auth.getEmail()) || "your@email.com".equalsIgnoreCase(playerMail)
|
||||
|| "your@email.com".equalsIgnoreCase(auth.getEmail())) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
String thePass = RandomString.generate(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH));
|
||||
HashedPassword hashNew = passwordSecurity.computeHash(thePass, playerName);
|
||||
auth.setPassword(hashNew);
|
||||
dataSource.updatePassword(auth);
|
||||
sendMailSsl.sendPasswordMail(auth, thePass);
|
||||
commandService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
|
||||
} else {
|
||||
commandService.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
if (playerCache.isAuthenticated(playerName)) {
|
||||
commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerAuth auth = dataSource.getAuth(playerName);
|
||||
if (auth == null) {
|
||||
commandService.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerMail.equalsIgnoreCase(auth.getEmail()) || "your@email.com".equalsIgnoreCase(auth.getEmail())) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
String thePass = RandomString.generate(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH));
|
||||
HashedPassword hashNew = passwordSecurity.computeHash(thePass, playerName);
|
||||
auth.setPassword(hashNew);
|
||||
dataSource.updatePassword(auth);
|
||||
sendMailSsl.sendPasswordMail(auth, thePass);
|
||||
commandService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
142
src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
Normal file
142
src/test/java/fr/xephi/authme/ConsoleLoggerTest.java
Normal file
@ -0,0 +1,142 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import fr.xephi.authme.output.LogLevel;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Test for {@link ConsoleLogger}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ConsoleLoggerTest {
|
||||
|
||||
@Mock
|
||||
private Logger logger;
|
||||
|
||||
@Mock
|
||||
private NewSetting settings;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
private File logFile;
|
||||
|
||||
@Before
|
||||
public void setMockLogger() throws IOException {
|
||||
ConsoleLogger.setLogger(logger);
|
||||
File folder = temporaryFolder.newFolder();
|
||||
File logFile = new File(folder, "authme.log");
|
||||
if (!logFile.createNewFile()) {
|
||||
throw new IOException("Could not create file '" + logFile.getPath() + "'");
|
||||
}
|
||||
ConsoleLogger.setLogFile(logFile);
|
||||
this.logFile = logFile;
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeFileHandlers() {
|
||||
ConsoleLogger.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLogToFile() throws IOException {
|
||||
// given
|
||||
ConsoleLogger.setLoggingOptions(newSettings(true, LogLevel.FINE));
|
||||
|
||||
// when
|
||||
ConsoleLogger.fine("Logging a FINE message");
|
||||
ConsoleLogger.debug("Logging a DEBUG message");
|
||||
ConsoleLogger.info("This is an INFO message");
|
||||
|
||||
// then
|
||||
verify(logger, times(2)).info(anyString());
|
||||
verifyNoMoreInteractions(logger);
|
||||
List<String> loggedLines = Files.readAllLines(logFile.toPath(), Charset.forName("UTF-8"));
|
||||
assertThat(loggedLines, hasSize(2));
|
||||
assertThat(loggedLines.get(0), containsString("[FINE] Logging a FINE message"));
|
||||
assertThat(loggedLines.get(1), containsString("[INFO] This is an INFO message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotLogToFile() throws IOException {
|
||||
// given
|
||||
ConsoleLogger.setLoggingOptions(newSettings(false, LogLevel.DEBUG));
|
||||
|
||||
// when
|
||||
ConsoleLogger.debug("Created test");
|
||||
ConsoleLogger.warning("Encountered a warning");
|
||||
|
||||
// then
|
||||
verify(logger).info("Debug: Created test");
|
||||
verify(logger).warning("Encountered a warning");
|
||||
verifyNoMoreInteractions(logger);
|
||||
assertThat(logFile.length(), equalTo(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLogStackTraceToFile() throws IOException {
|
||||
// given
|
||||
ConsoleLogger.setLoggingOptions(newSettings(true, LogLevel.INFO));
|
||||
Exception e = new IllegalStateException("Test exception message");
|
||||
|
||||
// when
|
||||
ConsoleLogger.info("Info text");
|
||||
ConsoleLogger.debug("Debug message");
|
||||
ConsoleLogger.fine("Fine-level message");
|
||||
ConsoleLogger.logException("Exception occurred:", e);
|
||||
|
||||
// then
|
||||
verify(logger).info("Info text");
|
||||
verify(logger).warning("Exception occurred: [IllegalStateException]: Test exception message");
|
||||
verifyNoMoreInteractions(logger);
|
||||
List<String> loggedLines = Files.readAllLines(logFile.toPath(), Charset.forName("UTF-8"));
|
||||
assertThat(loggedLines.size(), greaterThan(3));
|
||||
assertThat(loggedLines.get(0), containsString("[INFO] Info text"));
|
||||
assertThat(loggedLines.get(1),
|
||||
containsString("[WARN] Exception occurred: [IllegalStateException]: Test exception message"));
|
||||
// Check that we have this class' full name somewhere in the file -> stacktrace of Exception e
|
||||
assertThat(StringUtils.join("", loggedLines), containsString(getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveHiddenConstructor() {
|
||||
TestHelper.validateHasOnlyPrivateEmptyConstructor(ConsoleLogger.class);
|
||||
}
|
||||
|
||||
private static NewSetting newSettings(boolean logToFile, LogLevel logLevel) {
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(SecuritySettings.USE_LOGGING)).willReturn(logToFile);
|
||||
given(settings.getProperty(PluginSettings.LOG_LEVEL)).willReturn(logLevel);
|
||||
return settings;
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ public final class TestHelper {
|
||||
*/
|
||||
public static Path getJarPath(String path) {
|
||||
String sqlFilePath = getUriOrThrow(path).getPath();
|
||||
// Windows preprends the path with a '/' or '\', which Paths cannot handle
|
||||
// Windows prepends the path with a '/' or '\', which Paths cannot handle
|
||||
String appropriatePath = System.getProperty("os.name").contains("indow")
|
||||
? sqlFilePath.substring(1)
|
||||
: sqlFilePath;
|
||||
|
@ -0,0 +1,217 @@
|
||||
package fr.xephi.authme.command.executable.email;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
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.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
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.Matchers.eq;
|
||||
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 RecoverEmailCommand}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RecoverEmailCommandTest {
|
||||
|
||||
private static final String DEFAULT_EMAIL = "your@email.com";
|
||||
|
||||
@InjectMocks
|
||||
private RecoverEmailCommand command;
|
||||
|
||||
@Mock
|
||||
private PasswordSecurity passwordSecurity;
|
||||
|
||||
@Mock
|
||||
private CommandService commandService;
|
||||
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
|
||||
@Mock
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Mock
|
||||
private SendMailSSL sendMailSsl;
|
||||
|
||||
@BeforeClass
|
||||
public static void initLogger() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleMissingMailProperties() {
|
||||
// given
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(false);
|
||||
Player sender = mock(Player.class);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList("some@email.tld"));
|
||||
|
||||
// then
|
||||
verify(commandService).send(sender, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
|
||||
verifyZeroInteractions(dataSource, passwordSecurity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldShowErrorForAuthenticatedUser() {
|
||||
// given
|
||||
String name = "Bobby";
|
||||
Player sender = mock(Player.class);
|
||||
given(sender.getName()).willReturn(name);
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
given(playerCache.isAuthenticated(name)).willReturn(true);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList("bobby@example.org"));
|
||||
|
||||
// then
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verifyZeroInteractions(dataSource);
|
||||
verify(commandService).send(sender, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldShowRegisterMessageForUnregisteredPlayer() {
|
||||
// given
|
||||
String name = "Player123";
|
||||
Player sender = mock(Player.class);
|
||||
given(sender.getName()).willReturn(name);
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
given(playerCache.isAuthenticated(name)).willReturn(false);
|
||||
given(dataSource.getAuth(name)).willReturn(null);
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList("someone@example.com"));
|
||||
|
||||
// then
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verify(dataSource).getAuth(name);
|
||||
verifyNoMoreInteractions(dataSource);
|
||||
verify(commandService).send(sender, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleDefaultEmail() {
|
||||
// given
|
||||
String name = "Tract0r";
|
||||
Player sender = mock(Player.class);
|
||||
given(sender.getName()).willReturn(name);
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
given(playerCache.isAuthenticated(name)).willReturn(false);
|
||||
given(dataSource.getAuth(name)).willReturn(authWithEmail(DEFAULT_EMAIL));
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(DEFAULT_EMAIL));
|
||||
|
||||
// then
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verify(dataSource).getAuth(name);
|
||||
verifyNoMoreInteractions(dataSource);
|
||||
verify(commandService).send(sender, MessageKey.INVALID_EMAIL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleInvalidEmailInput() {
|
||||
// given
|
||||
String name = "Rapt0r";
|
||||
Player sender = mock(Player.class);
|
||||
given(sender.getName()).willReturn(name);
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
given(playerCache.isAuthenticated(name)).willReturn(false);
|
||||
given(dataSource.getAuth(name)).willReturn(authWithEmail("raptor@example.org"));
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList("wrong-email@example.com"));
|
||||
|
||||
// then
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verify(dataSource).getAuth(name);
|
||||
verifyNoMoreInteractions(dataSource);
|
||||
verify(commandService).send(sender, MessageKey.INVALID_EMAIL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldResetPasswordAndSendEmail() {
|
||||
// given
|
||||
String name = "Vultur3";
|
||||
Player sender = mock(Player.class);
|
||||
given(sender.getName()).willReturn(name);
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
given(playerCache.isAuthenticated(name)).willReturn(false);
|
||||
String email = "vulture@example.com";
|
||||
PlayerAuth auth = authWithEmail(email);
|
||||
given(dataSource.getAuth(name)).willReturn(auth);
|
||||
given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20);
|
||||
given(passwordSecurity.computeHash(anyString(), eq(name)))
|
||||
.willAnswer(new Answer<HashedPassword>() {
|
||||
@Override
|
||||
public HashedPassword answer(InvocationOnMock invocationOnMock) {
|
||||
return new HashedPassword((String) invocationOnMock.getArguments()[0]);
|
||||
}
|
||||
});
|
||||
|
||||
// when
|
||||
command.executeCommand(sender, Collections.singletonList(email.toUpperCase()));
|
||||
|
||||
// then
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verify(dataSource).getAuth(name);
|
||||
verify(passwordSecurity).computeHash(anyString(), eq(name));
|
||||
verify(dataSource).updatePassword(auth);
|
||||
assertThat(auth.getPassword().getHash(), stringWithLength(20));
|
||||
verify(sendMailSsl).sendPasswordMail(eq(auth), argThat(stringWithLength(20)));
|
||||
verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
|
||||
}
|
||||
|
||||
|
||||
private static PlayerAuth authWithEmail(String email) {
|
||||
return PlayerAuth.builder()
|
||||
.name("tester")
|
||||
.email(email)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Matcher<String> stringWithLength(final int length) {
|
||||
return new TypeSafeMatcher<String>() {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("String of length " + length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(String s) {
|
||||
return s.length() == length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user