#930 Extract common captcha functionality into abstract superclass
- Create AbstractCaptchaManager - Add tests
This commit is contained in:
@@ -17,6 +17,7 @@ import java.util.Collections;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.only;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
@@ -39,7 +40,7 @@ public class CaptchaCommandTest {
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Mock
|
||||
private CommonService commandService;
|
||||
private CommonService commonService;
|
||||
|
||||
@Mock
|
||||
private LimboService limboService;
|
||||
@@ -55,7 +56,7 @@ public class CaptchaCommandTest {
|
||||
command.executeCommand(player, Collections.singletonList("123"));
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
verify(commonService).send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -65,14 +66,16 @@ public class CaptchaCommandTest {
|
||||
Player player = mockPlayerWithName(name);
|
||||
given(playerCache.isAuthenticated(name)).willReturn(false);
|
||||
given(loginCaptchaManager.isCaptchaRequired(name)).willReturn(false);
|
||||
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(false);
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.singletonList("1234"));
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.USAGE_LOGIN);
|
||||
verify(commonService).send(player, MessageKey.USAGE_LOGIN);
|
||||
verify(loginCaptchaManager).isCaptchaRequired(name);
|
||||
verifyNoMoreInteractions(loginCaptchaManager);
|
||||
verify(registrationCaptchaManager).isCaptchaRequired(name);
|
||||
verifyNoMoreInteractions(loginCaptchaManager, registrationCaptchaManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,10 +95,10 @@ public class CaptchaCommandTest {
|
||||
verify(loginCaptchaManager).isCaptchaRequired(name);
|
||||
verify(loginCaptchaManager).checkCode(name, captchaCode);
|
||||
verifyNoMoreInteractions(loginCaptchaManager);
|
||||
verify(commandService).send(player, MessageKey.CAPTCHA_SUCCESS);
|
||||
verify(commandService).send(player, MessageKey.LOGIN_MESSAGE);
|
||||
verify(commonService).send(player, MessageKey.CAPTCHA_SUCCESS);
|
||||
verify(commonService).send(player, MessageKey.LOGIN_MESSAGE);
|
||||
verify(limboService).unmuteMessageTask(player);
|
||||
verifyNoMoreInteractions(commandService);
|
||||
verifyNoMoreInteractions(commonService);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -118,8 +121,47 @@ public class CaptchaCommandTest {
|
||||
verify(loginCaptchaManager).checkCode(name, captchaCode);
|
||||
verify(loginCaptchaManager).generateCode(name);
|
||||
verifyNoMoreInteractions(loginCaptchaManager);
|
||||
verify(commandService).send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode);
|
||||
verifyNoMoreInteractions(commandService);
|
||||
verify(commonService).send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode);
|
||||
verifyNoMoreInteractions(commonService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVerifyWithRegisterCaptchaManager() {
|
||||
// given
|
||||
String name = "john";
|
||||
Player player = mockPlayerWithName(name);
|
||||
given(loginCaptchaManager.isCaptchaRequired(name)).willReturn(false);
|
||||
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(true);
|
||||
String captchaCode = "A89Y3";
|
||||
given(registrationCaptchaManager.checkCode(name, captchaCode)).willReturn(true);
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.singletonList(captchaCode));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).checkCode(name, captchaCode);
|
||||
verify(loginCaptchaManager, only()).isCaptchaRequired(name);
|
||||
verify(commonService).send(player, MessageKey.CAPTCHA_SUCCESS);
|
||||
verify(commonService).send(player, MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleFailedRegisterCaptcha() {
|
||||
// given
|
||||
String name = "asfd";
|
||||
Player player = mockPlayerWithName(name);
|
||||
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(true);
|
||||
String captchaCode = "SFL3";
|
||||
given(registrationCaptchaManager.checkCode(name, captchaCode)).willReturn(false);
|
||||
given(registrationCaptchaManager.generateCode(name)).willReturn("new code");
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.singletonList(captchaCode));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).checkCode(name, captchaCode);
|
||||
verify(registrationCaptchaManager).generateCode(name);
|
||||
verify(commonService).send(player, MessageKey.CAPTCHA_WRONG_ERROR, "new code");
|
||||
}
|
||||
|
||||
private static Player mockPlayerWithName(String name) {
|
||||
|
||||
@@ -93,12 +93,13 @@ public class RegisterCommandTest {
|
||||
public void shouldForwardToManagementForTwoFactor() {
|
||||
// given
|
||||
given(commonService.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.TWO_FACTOR);
|
||||
Player player = mock(Player.class);
|
||||
Player player = mockPlayerWithName("test2");
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.emptyList());
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).isCaptchaRequired("test2");
|
||||
verify(management).performRegister(eq(RegistrationMethod.TWO_FACTOR_REGISTRATION),
|
||||
argThat(isEqualTo(TwoFactorRegisterParams.of(player))));
|
||||
verifyZeroInteractions(emailService);
|
||||
@@ -210,12 +211,13 @@ public class RegisterCommandTest {
|
||||
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL);
|
||||
given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.CONFIRMATION);
|
||||
given(emailService.hasAllInformation()).willReturn(true);
|
||||
Player player = mock(Player.class);
|
||||
Player player = mockPlayerWithName("brett");
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Arrays.asList(playerMail, playerMail));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).isCaptchaRequired("brett");
|
||||
verify(validationService).validateEmail(playerMail);
|
||||
verify(emailService).hasAllInformation();
|
||||
verify(management).performRegister(eq(RegistrationMethod.EMAIL_REGISTRATION),
|
||||
@@ -240,12 +242,13 @@ public class RegisterCommandTest {
|
||||
@Test
|
||||
public void shouldPerformPasswordRegistration() {
|
||||
// given
|
||||
Player player = mock(Player.class);
|
||||
Player player = mockPlayerWithName("newPlayer");
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.singletonList("myPass"));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).isCaptchaRequired("newPlayer");
|
||||
verify(management).performRegister(eq(RegistrationMethod.PASSWORD_REGISTRATION),
|
||||
argThat(isEqualTo(PasswordRegisterParams.of(player, "myPass", null))));
|
||||
}
|
||||
@@ -275,12 +278,13 @@ public class RegisterCommandTest {
|
||||
given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.EMAIL_OPTIONAL);
|
||||
String email = "email@example.org";
|
||||
given(validationService.validateEmail(email)).willReturn(false);
|
||||
Player player = mock(Player.class);
|
||||
Player player = mockPlayerWithName("Waaa");
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Arrays.asList("myPass", email));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).isCaptchaRequired("Waaa");
|
||||
verify(validationService).validateEmail(email);
|
||||
verify(commonService).send(player, MessageKey.INVALID_EMAIL);
|
||||
verifyZeroInteractions(management);
|
||||
@@ -291,13 +295,38 @@ public class RegisterCommandTest {
|
||||
// given
|
||||
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.PASSWORD);
|
||||
given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.EMAIL_OPTIONAL);
|
||||
Player player = mock(Player.class);
|
||||
Player player = mockPlayerWithName("Doa");
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.singletonList("myPass"));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).isCaptchaRequired("Doa");
|
||||
verify(management).performRegister(eq(RegistrationMethod.PASSWORD_REGISTRATION),
|
||||
argThat(isEqualTo(PasswordRegisterParams.of(player, "myPass", null))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRequestCaptcha() {
|
||||
// given
|
||||
given(registrationCaptchaManager.isCaptchaRequired(anyString())).willReturn(true);
|
||||
String name = "Brian";
|
||||
Player player = mockPlayerWithName(name);
|
||||
String captcha = "AB923C";
|
||||
given(registrationCaptchaManager.getCaptchaCodeOrGenerateNew(name)).willReturn(captcha);
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Arrays.asList("myPass", "myPass"));
|
||||
|
||||
// then
|
||||
verify(registrationCaptchaManager).isCaptchaRequired(name);
|
||||
verify(commonService).send(player, MessageKey.CAPTCHA_FOR_REGISTRATION_REQUIRED, captcha);
|
||||
verifyZeroInteractions(management, validationService);
|
||||
}
|
||||
|
||||
private static Player mockPlayerWithName(String name) {
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ public class LoginCaptchaManagerTest {
|
||||
assertThat(captchaCode.length(), equalTo(4));
|
||||
assertThat(badResult, equalTo(false));
|
||||
assertThat(goodResult, equalTo(true));
|
||||
// Supplying correct code should clear the entry, and any code should be valid if no entry is present
|
||||
assertThat(manager.checkCode(player, "bogus"), equalTo(true));
|
||||
// Supplying correct code should clear the entry, and a code should be invalid if no entry is present
|
||||
assertThat(manager.checkCode(player, "bogus"), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package fr.xephi.authme.data;
|
||||
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.expiring.ExpiringMap;
|
||||
import org.junit.Test;
|
||||
|
||||
import static fr.xephi.authme.AuthMeMatchers.stringWithLength;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link RegistrationCaptchaManager}.
|
||||
*/
|
||||
public class RegistrationCaptchaManagerTest {
|
||||
|
||||
@Test
|
||||
public void shouldBeDisabled() {
|
||||
// given
|
||||
Settings settings = mock(Settings.class);
|
||||
// Return false first time, and true after that
|
||||
given(settings.getProperty(SecuritySettings.ENABLE_CAPTCHA_FOR_REGISTRATION))
|
||||
.willReturn(false).willReturn(true);
|
||||
given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(12);
|
||||
|
||||
// when
|
||||
RegistrationCaptchaManager captchaManager1 = new RegistrationCaptchaManager(settings);
|
||||
RegistrationCaptchaManager captchaManager2 = new RegistrationCaptchaManager(settings);
|
||||
|
||||
// then
|
||||
assertThat(captchaManager1.isCaptchaRequired("bob"), equalTo(false));
|
||||
assertThat(captchaManager2.isCaptchaRequired("bob"), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVerifyCodeSuccessfully() {
|
||||
// given
|
||||
Settings settings = mock(Settings.class);
|
||||
given(settings.getProperty(SecuritySettings.ENABLE_CAPTCHA_FOR_REGISTRATION)).willReturn(true);
|
||||
given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(12);
|
||||
|
||||
String captcha = "abc3";
|
||||
RegistrationCaptchaManager captchaManager = new RegistrationCaptchaManager(settings);
|
||||
getCodeMap(captchaManager).put("test", captcha);
|
||||
|
||||
// when
|
||||
boolean isSuccessful = captchaManager.checkCode("TeSt", captcha);
|
||||
|
||||
// then
|
||||
assertThat(isSuccessful, equalTo(true));
|
||||
assertThat(getCodeMap(captchaManager).isEmpty(), equalTo(true));
|
||||
assertThat(captchaManager.isCaptchaRequired("test"), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateAndRetrieveCode() {
|
||||
// given
|
||||
Settings settings = mock(Settings.class);
|
||||
given(settings.getProperty(SecuritySettings.ENABLE_CAPTCHA_FOR_REGISTRATION)).willReturn(true);
|
||||
int captchaLength = 9;
|
||||
given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(captchaLength);
|
||||
RegistrationCaptchaManager captchaManager = new RegistrationCaptchaManager(settings);
|
||||
|
||||
// when
|
||||
String captcha1 = captchaManager.getCaptchaCodeOrGenerateNew("toast");
|
||||
String captcha2 = captchaManager.getCaptchaCodeOrGenerateNew("Toast");
|
||||
|
||||
// then
|
||||
assertThat(captcha1, equalTo(captcha2));
|
||||
assertThat(captcha1, stringWithLength(captchaLength));
|
||||
|
||||
// when (2) / then (2)
|
||||
assertThat(captchaManager.checkCode("toast", captcha1), equalTo(true));
|
||||
}
|
||||
|
||||
private static ExpiringMap<String, String> getCodeMap(AbstractCaptchaManager captchaManager) {
|
||||
return ReflectionTestUtils.getFieldValue(AbstractCaptchaManager.class, captchaManager, "captchaCodes");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user