Unit test verifications done on joining
- Write unit tests for checks done when a player joins - Move join event handler methods back to PlayerListener; move join check logic to new separate class
This commit is contained in:
@@ -21,11 +21,11 @@ import static org.junit.Assert.fail;
|
||||
public final class ListenerConsistencyTest {
|
||||
|
||||
private static final Class<?>[] LISTENERS = { AuthMeBlockListener.class, AuthMeEntityListener.class,
|
||||
AuthMePlayerJoinListener.class, AuthMePlayerListener.class, AuthMePlayerListener16.class,
|
||||
AuthMePlayerListener18.class, AuthMeServerListener.class };
|
||||
AuthMePlayerListener.class, AuthMePlayerListener16.class, AuthMePlayerListener18.class,
|
||||
AuthMeServerListener.class };
|
||||
|
||||
private static final Set<String> CANCELED_EXCEPTIONS = Sets.newHashSet("AuthMePlayerJoinListener#onPlayerJoin",
|
||||
"AuthMePlayerJoinListener#onPreLogin", "AuthMePlayerJoinListener#onPlayerLogin",
|
||||
private static final Set<String> CANCELED_EXCEPTIONS = Sets.newHashSet("AuthMePlayerListener#onPlayerJoin",
|
||||
"AuthMePlayerListener#onPreLogin", "AuthMePlayerListener#onPlayerLogin",
|
||||
"AuthMePlayerListener#onPlayerQuit", "AuthMeServerListener#onPluginDisable",
|
||||
"AuthMeServerListener#onServerPing", "AuthMeServerListener#onPluginEnable",
|
||||
"AuthMePlayerListener#onJoinMessage");
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import fr.xephi.authme.AntiBot;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
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 OnJoinVerifier}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class OnJoinVerifierTest {
|
||||
|
||||
@InjectMocks
|
||||
private OnJoinVerifier onJoinVerifier;
|
||||
|
||||
@Mock
|
||||
private NewSetting settings;
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
@Mock
|
||||
private Messages messages;
|
||||
@Mock
|
||||
private PermissionsManager permissionsManager;
|
||||
@Mock
|
||||
private AntiBot antiBot;
|
||||
@Mock
|
||||
private ValidationService validationService;
|
||||
@Mock
|
||||
private BukkitService bukkitService;
|
||||
@Mock
|
||||
private LimboCache limboCache;
|
||||
@Mock
|
||||
private Server server;
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpLogger() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotDoAnythingForNormalEvent() {
|
||||
// given
|
||||
PlayerLoginEvent event = mock(PlayerLoginEvent.class);
|
||||
given(event.getResult()).willReturn(PlayerLoginEvent.Result.ALLOWED);
|
||||
|
||||
// when
|
||||
boolean result = onJoinVerifier.refusePlayerForFullServer(event);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
verify(event).getResult();
|
||||
verifyNoMoreInteractions(event);
|
||||
verifyZeroInteractions(bukkitService);
|
||||
verifyZeroInteractions(dataSource);
|
||||
verifyZeroInteractions(permissionsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRefuseNonVipPlayerForFullServer() {
|
||||
// given
|
||||
Player player = mock(Player.class);
|
||||
PlayerLoginEvent event = new PlayerLoginEvent(player, "hostname", null);
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
|
||||
given(permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)).willReturn(false);
|
||||
String serverFullMessage = "server is full";
|
||||
given(messages.retrieveSingle(MessageKey.KICK_FULL_SERVER)).willReturn(serverFullMessage);
|
||||
|
||||
// when
|
||||
boolean result = onJoinVerifier.refusePlayerForFullServer(event);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
assertThat(event.getResult(), equalTo(PlayerLoginEvent.Result.KICK_FULL));
|
||||
assertThat(event.getKickMessage(), equalTo(serverFullMessage));
|
||||
verifyZeroInteractions(bukkitService);
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldKickNonVipForJoiningVipPlayer() {
|
||||
// given
|
||||
Player player = mock(Player.class);
|
||||
PlayerLoginEvent event = new PlayerLoginEvent(player, "hostname", null);
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
|
||||
given(permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)).willReturn(true);
|
||||
List<Player> onlinePlayers = Arrays.asList(mock(Player.class), mock(Player.class));
|
||||
given(permissionsManager.hasPermission(onlinePlayers.get(0), PlayerStatePermission.IS_VIP)).willReturn(true);
|
||||
given(permissionsManager.hasPermission(onlinePlayers.get(1), PlayerStatePermission.IS_VIP)).willReturn(false);
|
||||
returnOnlineListFromBukkitServer(onlinePlayers);
|
||||
given(server.getMaxPlayers()).willReturn(onlinePlayers.size());
|
||||
given(messages.retrieveSingle(MessageKey.KICK_FOR_VIP)).willReturn("kick for vip");
|
||||
|
||||
// when
|
||||
boolean result = onJoinVerifier.refusePlayerForFullServer(event);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
assertThat(event.getResult(), equalTo(PlayerLoginEvent.Result.ALLOWED));
|
||||
// First player is VIP, so expect no interactions there and second player to have been kicked
|
||||
verifyZeroInteractions(onlinePlayers.get(0));
|
||||
verify(onlinePlayers.get(1)).kickPlayer("kick for vip");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldKickVipPlayerIfNoPlayerCanBeKicked() {
|
||||
// given
|
||||
Player player = mock(Player.class);
|
||||
PlayerLoginEvent event = new PlayerLoginEvent(player, "hostname", null);
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_FULL);
|
||||
given(permissionsManager.hasPermission(player, PlayerStatePermission.IS_VIP)).willReturn(true);
|
||||
List<Player> onlinePlayers = Collections.singletonList(mock(Player.class));
|
||||
given(permissionsManager.hasPermission(onlinePlayers.get(0), PlayerStatePermission.IS_VIP)).willReturn(true);
|
||||
returnOnlineListFromBukkitServer(onlinePlayers);
|
||||
given(server.getMaxPlayers()).willReturn(onlinePlayers.size());
|
||||
given(messages.retrieveSingle(MessageKey.KICK_FULL_SERVER)).willReturn("kick full server");
|
||||
|
||||
// when
|
||||
boolean result = onJoinVerifier.refusePlayerForFullServer(event);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
assertThat(event.getResult(), equalTo(PlayerLoginEvent.Result.KICK_FULL));
|
||||
assertThat(event.getKickMessage(), equalTo("kick full server"));
|
||||
verifyZeroInteractions(onlinePlayers.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldKickNonRegistered() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED)).willReturn(true);
|
||||
|
||||
// expect
|
||||
expectValidationExceptionWith(MessageKey.MUST_REGISTER_MESSAGE);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkKickNonRegistered(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotKickRegisteredPlayer() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED)).willReturn(true);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkKickNonRegistered(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotKickUnregisteredPlayer() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED)).willReturn(false);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkKickNonRegistered(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAllowValidName() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.MIN_NICKNAME_LENGTH)).willReturn(4);
|
||||
given(settings.getProperty(RestrictionSettings.MAX_NICKNAME_LENGTH)).willReturn(8);
|
||||
given(settings.getProperty(RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS)).willReturn("[a-zA-Z0-9]+");
|
||||
onJoinVerifier.reload(); // @PostConstruct method
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkIsValidName("Bobby5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectTooLongName() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.MIN_NICKNAME_LENGTH)).willReturn(4);
|
||||
given(settings.getProperty(RestrictionSettings.MAX_NICKNAME_LENGTH)).willReturn(8);
|
||||
given(settings.getProperty(RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS)).willReturn("[a-zA-Z0-9]+");
|
||||
onJoinVerifier.reload(); // @PostConstruct method
|
||||
|
||||
// expect
|
||||
expectValidationExceptionWith(MessageKey.INVALID_NAME_LENGTH);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkIsValidName("longerthaneight");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectTooShortName() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.MIN_NICKNAME_LENGTH)).willReturn(4);
|
||||
given(settings.getProperty(RestrictionSettings.MAX_NICKNAME_LENGTH)).willReturn(8);
|
||||
given(settings.getProperty(RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS)).willReturn("[a-zA-Z0-9]+");
|
||||
onJoinVerifier.reload(); // @PostConstruct method
|
||||
|
||||
// expect
|
||||
expectValidationExceptionWith(MessageKey.INVALID_NAME_LENGTH);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkIsValidName("abc");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectNameWithInvalidCharacters() throws FailedVerificationException {
|
||||
// given
|
||||
given(settings.getProperty(RestrictionSettings.MIN_NICKNAME_LENGTH)).willReturn(4);
|
||||
given(settings.getProperty(RestrictionSettings.MAX_NICKNAME_LENGTH)).willReturn(8);
|
||||
given(settings.getProperty(RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS)).willReturn("[a-zA-Z0-9]+");
|
||||
onJoinVerifier.reload(); // @PostConstruct method
|
||||
|
||||
// expect
|
||||
expectValidationExceptionWith(MessageKey.INVALID_NAME_CHARACTERS, "[a-zA-Z0-9]+");
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkIsValidName("Tester!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAllowProperlyCasedName() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("Bobby");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("bobby").realName("Bobby").build();
|
||||
given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(true);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectNameWithWrongCasing() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("Tester");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("tester").realName("testeR").build();
|
||||
given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(true);
|
||||
|
||||
// expect
|
||||
expectValidationExceptionWith(MessageKey.INVALID_NAME_CASE, "testeR", "Tester");
|
||||
|
||||
// when / then
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateMissingRealName() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("Authme");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("authme").realName("").build();
|
||||
given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(true);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
|
||||
// then
|
||||
verify(dataSource).updateRealName("authme", "Authme");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateDefaultRealName() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("SOMEONE");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("someone").realName("Player").build();
|
||||
given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(true);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
|
||||
// then
|
||||
verify(dataSource).updateRealName("someone", "SOMEONE");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptCasingMismatchForDisabledSetting() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("Test");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("test").realName("TEST").build();
|
||||
given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(false);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptNameForUnregisteredAccount() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("MyPlayer");
|
||||
PlayerAuth auth = null;
|
||||
given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(true);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkNameCasing(player, auth);
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptNameThatIsNotOnline() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("bobby");
|
||||
given(settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)).willReturn(true);
|
||||
given(bukkitService.getPlayerExact("bobby")).willReturn(null);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkSingleSession(player);
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(limboCache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectNameAlreadyOnline() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("Charlie");
|
||||
Player onlinePlayer = newPlayerWithName("charlie");
|
||||
given(bukkitService.getPlayerExact("Charlie")).willReturn(onlinePlayer);
|
||||
given(settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)).willReturn(true);
|
||||
|
||||
// expect
|
||||
expectValidationExceptionWith(MessageKey.USERNAME_ALREADY_ONLINE_ERROR);
|
||||
|
||||
// when / then
|
||||
onJoinVerifier.checkSingleSession(player);
|
||||
verify(limboCache).getLimboPlayer("charlie");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptAlreadyOnlineNameForDisabledSetting() throws FailedVerificationException {
|
||||
// given
|
||||
Player player = newPlayerWithName("Felipe");
|
||||
given(settings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)).willReturn(false);
|
||||
|
||||
// when
|
||||
onJoinVerifier.checkSingleSession(player);
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(bukkitService);
|
||||
verifyZeroInteractions(limboCache);
|
||||
}
|
||||
|
||||
private static Player newPlayerWithName(String name) {
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
return player;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void returnOnlineListFromBukkitServer(Collection<Player> onlineList) {
|
||||
// Note ljacqu 20160529: The compiler gets lost in generics because Collection<? extends Player> is returned
|
||||
// from getOnlinePlayers(). We need to uncheck onlineList to a simple Collection or it will refuse to compile.
|
||||
given(bukkitService.getOnlinePlayers()).willReturn((Collection) onlineList);
|
||||
}
|
||||
|
||||
private void expectValidationExceptionWith(MessageKey messageKey, String... args) {
|
||||
//expectedException.expect(FailedVerificationException.class);
|
||||
expectedException.expect(exceptionWithData(messageKey, args));
|
||||
}
|
||||
|
||||
private static Matcher<FailedVerificationException> exceptionWithData(final MessageKey messageKey,
|
||||
final String... args) {
|
||||
return new TypeSafeMatcher<FailedVerificationException>() {
|
||||
@Override
|
||||
protected boolean matchesSafely(FailedVerificationException item) {
|
||||
return messageKey.equals(item.getReason()) && Arrays.equals(args, item.getArgs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendValue("VerificationFailedException: reason=" + messageKey + ";args="
|
||||
+ (args == null ? "null" : StringUtils.join(", ", args)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user