Service cleanup

This commit is contained in:
Gabriele C
2016-10-04 19:08:18 +02:00
parent 5c2d7139bc
commit 42dbb27728
89 changed files with 319 additions and 257 deletions
@@ -10,7 +10,6 @@ import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -0,0 +1,73 @@
package fr.xephi.authme.service;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Collection;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Test for {@link BukkitService}.
*/
@RunWith(MockitoJUnitRunner.class)
public class BukkitServiceTest {
@Mock
private AuthMe authMe;
@Mock
private Settings settings;
/**
* Checks that {@link BukkitService#getOnlinePlayersIsCollection} is initialized to {@code true} on startup;
* the test scope is configured with a Bukkit implementation that returns a Collection and not an array.
*/
@Test
public void shouldHavePlayerListAsCollectionMethod() {
// given
given(settings.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true);
BukkitService bukkitService = new BukkitService(authMe, settings);
// when
boolean doesMethodReturnCollection = ReflectionTestUtils
.getFieldValue(BukkitService.class, bukkitService, "getOnlinePlayersIsCollection");
// then
assertThat(doesMethodReturnCollection, equalTo(true));
}
@Test
public void shouldRetrieveListOfOnlinePlayersFromReflectedMethod() {
// given
given(settings.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true);
BukkitService bukkitService = new BukkitService(authMe, settings);
ReflectionTestUtils.setField(BukkitService.class, bukkitService, "getOnlinePlayersIsCollection", false);
ReflectionTestUtils.setField(BukkitService.class, bukkitService, "getOnlinePlayers",
ReflectionTestUtils.getMethod(BukkitServiceTest.class, "onlinePlayersImpl"));
// when
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
// then
assertThat(players, hasSize(2));
}
// Note: This method is used through reflections
public static Player[] onlinePlayersImpl() {
return new Player[]{
mock(Player.class), mock(Player.class)
};
}
}
@@ -0,0 +1,135 @@
package fr.xephi.authme.service;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.security.crypts.SHA256;
import fr.xephi.authme.service.MigrationService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import java.util.Arrays;
import static fr.xephi.authme.AuthMeMatchers.equalToHash;
import static org.hamcrest.Matchers.equalToIgnoringCase;
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.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Test for {@link MigrationService}.
*/
@RunWith(MockitoJUnitRunner.class)
public class MigrationServiceTest {
@Mock
private Settings settings;
@Mock
private DataSource dataSource;
@Mock
private SHA256 sha256;
@BeforeClass
public static void setUpLogger() {
TestHelper.setupLogger();
}
@Test
public void shouldMigratePlaintextHashes() {
// given
PlayerAuth auth1 = authWithNickAndHash("bobby", "test");
PlayerAuth auth2 = authWithNickAndHash("user", "myPassword");
PlayerAuth auth3 = authWithNickAndHash("Tester12", "$tester12_pw");
given(dataSource.getAllAuths()).willReturn(Arrays.asList(auth1, auth2, auth3));
setSha256MockToUppercase(sha256);
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.PLAINTEXT);
// when
MigrationService.changePlainTextToSha256(settings, dataSource, sha256);
// then
verify(sha256, times(3)).computeHash(anyString(), anyString());
verify(dataSource).getAllAuths(); // need to verify this because we use verifyNoMoreInteractions() after
verify(dataSource).updatePassword(auth1);
assertThat(auth1.getPassword(), equalToHash("TEST"));
verify(dataSource).updatePassword(auth2);
assertThat(auth2.getPassword(), equalToHash("MYPASSWORD"));
verify(dataSource).updatePassword(auth3);
assertThat(auth3.getPassword(), equalToHash("$TESTER12_PW"));
verifyNoMoreInteractions(dataSource);
verify(settings).setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
}
@Test
public void shouldNotMigrateShaHashes() {
// given
PlayerAuth auth1 = authWithNickAndHash("testUser", "abc1234");
PlayerAuth auth2 = authWithNickAndHash("minecraft", "$SHA$f28930ae09823eba4cd98a3");
given(dataSource.getAllAuths()).willReturn(Arrays.asList(auth1, auth2));
setSha256MockToUppercase(sha256);
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.PLAINTEXT);
// when
MigrationService.changePlainTextToSha256(settings, dataSource, sha256);
// then
verify(sha256).computeHash(eq("abc1234"), argThat(equalToIgnoringCase("testUser")));
verifyNoMoreInteractions(sha256);
verify(dataSource).getAllAuths(); // need to verify this because we use verifyNoMoreInteractions() after
verify(dataSource).updatePassword(auth1);
assertThat(auth1.getPassword(), equalToHash("ABC1234"));
verifyNoMoreInteractions(dataSource);
verify(settings).setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
}
@Test
public void shouldNotMigrateForHashOtherThanPlaintext() {
// given
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.BCRYPT);
// when
MigrationService.changePlainTextToSha256(settings, dataSource, sha256);
// then
verify(settings).getProperty(SecuritySettings.PASSWORD_HASH);
verifyNoMoreInteractions(settings, dataSource, sha256);
}
@Test
public void shouldHaveHiddenEmptyConstructorOnly() {
TestHelper.validateHasOnlyPrivateEmptyConstructor(MigrationService.class);
}
private static PlayerAuth authWithNickAndHash(String nick, String hash) {
return PlayerAuth.builder()
.name(nick)
.password(hash, null)
.build();
}
private static void setSha256MockToUppercase(SHA256 sha256) {
given(sha256.computeHash(anyString(), anyString())).willAnswer(new Answer<HashedPassword>() {
@Override
public HashedPassword answer(InvocationOnMock invocation) {
String plainPassword = (String) invocation.getArguments()[0];
return new HashedPassword(plainPassword.toUpperCase(), null);
}
});
}
}
@@ -4,7 +4,7 @@ import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.service.RecoveryCodeManager.ExpiringEntry;
import fr.xephi.authme.service.RecoveryCodeService.ExpiringEntry;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.junit.Test;
@@ -20,13 +20,13 @@ import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Test for {@link RecoveryCodeManager}.
* Test for {@link RecoveryCodeService}.
*/
@RunWith(DelayedInjectionRunner.class)
public class RecoveryCodeManagerTest {
public class RecoveryCodeServiceTest {
@InjectDelayed
private RecoveryCodeManager recoveryCodeManager;
private RecoveryCodeService recoveryCodeService;
@Mock
private Settings settings;
@@ -39,16 +39,16 @@ public class RecoveryCodeManagerTest {
@Test
public void shouldBeDisabledForNonPositiveLength() {
assertThat(recoveryCodeManager.isRecoveryCodeNeeded(), equalTo(true));
assertThat(recoveryCodeService.isRecoveryCodeNeeded(), equalTo(true));
// given
given(settings.getProperty(SecuritySettings.RECOVERY_CODE_LENGTH)).willReturn(0);
// when
recoveryCodeManager.reload(settings);
recoveryCodeService.reload(settings);
// then
assertThat(recoveryCodeManager.isRecoveryCodeNeeded(), equalTo(false));
assertThat(recoveryCodeService.isRecoveryCodeNeeded(), equalTo(false));
}
@Test
@@ -57,7 +57,7 @@ public class RecoveryCodeManagerTest {
String name = "Bobbers";
// when
recoveryCodeManager.generateCode(name);
recoveryCodeService.generateCode(name);
// then
ExpiringEntry entry = getCodeMap().get(name);
@@ -72,7 +72,7 @@ public class RecoveryCodeManagerTest {
setCodeInMap(player, code, System.currentTimeMillis() - 500);
// when
boolean result = recoveryCodeManager.isCodeValid(player, code);
boolean result = recoveryCodeService.isCodeValid(player, code);
// then
assertThat(result, equalTo(false));
@@ -82,10 +82,10 @@ public class RecoveryCodeManagerTest {
public void shouldRecognizeCorrectCode() {
// given
String player = "dragon";
String code = recoveryCodeManager.generateCode(player);
String code = recoveryCodeService.generateCode(player);
// when
boolean result = recoveryCodeManager.isCodeValid(player, code);
boolean result = recoveryCodeService.isCodeValid(player, code);
// then
assertThat(result, equalTo(true));
@@ -95,19 +95,19 @@ public class RecoveryCodeManagerTest {
public void shouldRemoveCode() {
// given
String player = "Tester";
String code = recoveryCodeManager.generateCode(player);
String code = recoveryCodeService.generateCode(player);
// when
recoveryCodeManager.removeCode(player);
recoveryCodeService.removeCode(player);
// then
assertThat(recoveryCodeManager.isCodeValid(player, code), equalTo(false));
assertThat(recoveryCodeService.isCodeValid(player, code), equalTo(false));
assertThat(getCodeMap().get(player), nullValue());
}
private Map<String, ExpiringEntry> getCodeMap() {
return ReflectionTestUtils.getFieldValue(RecoveryCodeManager.class, recoveryCodeManager, "recoveryCodes");
return ReflectionTestUtils.getFieldValue(RecoveryCodeService.class, recoveryCodeService, "recoveryCodes");
}
private void setCodeInMap(String player, String code, long expiration) {
@@ -0,0 +1,443 @@
package fr.xephi.authme.service;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
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.Arrays;
import static fr.xephi.authme.TestHelper.runSyncDelayedTask;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Test for {@link TeleportationService}.
*/
@RunWith(MockitoJUnitRunner.class)
public class TeleportationServiceTest {
@InjectMocks
private TeleportationService teleportationService;
@Mock
private Settings settings;
@Mock
private BukkitService bukkitService;
@Mock
private SpawnLoader spawnLoader;
@Mock
private PlayerCache playerCache;
@Before
public void setUpForcedWorlds() {
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_ON_WORLDS))
.willReturn(Arrays.asList("forced1", "OtherForced"));
teleportationService.reload();
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(false);
}
// -----------
// JOINING
// -----------
@Test
public void shouldNotTeleportPlayerOnJoin() {
// given
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(true);
Player player = mock(Player.class);
// when
teleportationService.teleportOnJoin(player);
// then
verifyZeroInteractions(player);
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldTeleportPlayerToFirstSpawn() {
// given
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(false);
given(player.isOnline()).willReturn(true);
Location firstSpawn = mockLocation();
given(spawnLoader.getFirstSpawn()).willReturn(firstSpawn);
// when
teleportationService.teleportNewPlayerToFirstSpawn(player);
runSyncDelayedTask(bukkitService);
// then
verify(player).teleport(firstSpawn);
verify(bukkitService).callEvent(any(FirstSpawnTeleportEvent.class));
verify(spawnLoader).getFirstSpawn();
verify(spawnLoader, never()).getSpawnLocation(any(Player.class));
}
@Test
public void shouldTeleportPlayerToSpawn() {
// given
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
// when
teleportationService.teleportOnJoin(player);
runSyncDelayedTask(bukkitService);
// then
verify(player).teleport(spawn);
verify(bukkitService).callEvent(any(SpawnTeleportEvent.class));
verify(spawnLoader).getSpawnLocation(player);
}
@Test
// No first spawn defined, no teleport settings enabled
public void shouldNotTeleportNewPlayer() {
// given
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(false);
given(player.isOnline()).willReturn(true);
given(player.getWorld()).willReturn(mock(World.class));
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(false);
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false);
given(spawnLoader.getFirstSpawn()).willReturn(null);
// when
teleportationService.teleportNewPlayerToFirstSpawn(player);
// then
verify(player, never()).teleport(any(Location.class));
verify(spawnLoader).getFirstSpawn();
verify(spawnLoader, never()).getSpawnLocation(any(Player.class));
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldNotTeleportPlayerToFirstSpawnIfNoTeleportEnabled() {
// given
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(false);
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(true);
// when
teleportationService.teleportNewPlayerToFirstSpawn(player);
// then
verify(player, never()).teleport(any(Location.class));
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldNotTeleportNotNewPlayerToFirstSpawn() {
// given
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(true);
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(false);
// when
teleportationService.teleportNewPlayerToFirstSpawn(player);
// then
verify(player, never()).teleport(any(Location.class));
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldNotTeleportPlayerForRemovedLocationInEvent() {
// given
final Player player = mock(Player.class);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
SpawnTeleportEvent event = (SpawnTeleportEvent) invocation.getArguments()[0];
assertThat(event.getPlayer(), equalTo(player));
event.setTo(null);
return null;
}
}).when(bukkitService).callEvent(any(SpawnTeleportEvent.class));
// when
teleportationService.teleportOnJoin(player);
runSyncDelayedTask(bukkitService);
// then
verify(bukkitService).callEvent(any(SpawnTeleportEvent.class));
verify(player, never()).teleport(any(Location.class));
}
@Test
public void shouldNotTeleportPlayerForCanceledEvent() {
// given
final Player player = mock(Player.class);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
SpawnTeleportEvent event = (SpawnTeleportEvent) invocation.getArguments()[0];
assertThat(event.getPlayer(), equalTo(player));
event.setCancelled(true);
return null;
}
}).when(bukkitService).callEvent(any(SpawnTeleportEvent.class));
// when
teleportationService.teleportOnJoin(player);
runSyncDelayedTask(bukkitService);
// then
verify(bukkitService).callEvent(any(SpawnTeleportEvent.class));
verify(player, never()).teleport(any(Location.class));
}
// ---------
// LOGIN
// ---------
@Test
public void shouldNotTeleportUponLogin() {
// given
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(true);
Player player = mock(Player.class);
PlayerAuth auth = mock(PlayerAuth.class);
PlayerData limbo = mock(PlayerData.class);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
// then
verifyZeroInteractions(player, auth, limbo, bukkitService, spawnLoader);
}
@Test
public void shouldTeleportPlayerToSpawnAfterLogin() {
// given
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(true);
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
PlayerAuth auth = mock(PlayerAuth.class);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limboLocation.getWorld().getName()).willReturn("forced1");
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
runSyncDelayedTask(bukkitService);
// then
verify(player).teleport(spawn);
}
@Test
// Check that the worlds for "force spawn loc after login" are case-sensitive
public void shouldNotTeleportToSpawnForOtherCaseInWorld() {
// given
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(true);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(false);
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
PlayerAuth auth = mock(PlayerAuth.class);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limboLocation.getWorld().getName()).willReturn("Forced1"); // different case
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
// then
verify(player, never()).teleport(spawn);
verifyZeroInteractions(bukkitService, spawnLoader);
}
@Test
public void shouldTeleportBackToPlayerAuthLocation() {
// given
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(true);
PlayerAuth auth = createAuthWithLocation();
auth.setWorld("myWorld");
World world = mock(World.class);
given(bukkitService.getWorld("myWorld")).willReturn(world);
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
runSyncDelayedTask(bukkitService);
// then
ArgumentCaptor<Location> locationCaptor = ArgumentCaptor.forClass(Location.class);
verify(player).teleport(locationCaptor.capture());
assertCorrectLocation(locationCaptor.getValue(), auth, world);
}
@Test
public void shouldTeleportAccordingToPlayerAuthAndPlayerWorldAsFallback() {
// given
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(true);
PlayerAuth auth = createAuthWithLocation();
auth.setWorld("myWorld");
given(bukkitService.getWorld("myWorld")).willReturn(null);
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
World world = mock(World.class);
given(player.getWorld()).willReturn(world);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
runSyncDelayedTask(bukkitService);
// then
ArgumentCaptor<Location> locationCaptor = ArgumentCaptor.forClass(Location.class);
verify(player).teleport(locationCaptor.capture());
assertCorrectLocation(locationCaptor.getValue(), auth, world);
}
@Test
public void shouldTeleportWithLimboPlayerIfAuthYCoordIsNotSet() {
// given
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(true);
PlayerAuth auth = createAuthWithLocation();
auth.setQuitLocY(0.0);
auth.setWorld("authWorld");
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
World world = mock(World.class);
given(player.getWorld()).willReturn(world);
PlayerData limbo = mock(PlayerData.class);
Location location = mockLocation();
given(limbo.getLocation()).willReturn(location);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
runSyncDelayedTask(bukkitService);
// then
verify(player).teleport(location);
verify(bukkitService, never()).getWorld(anyString());
}
@Test
public void shouldTeleportWithLimboPlayerIfSaveQuitLocIsDisabled() {
// given
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(false);
PlayerAuth auth = createAuthWithLocation();
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
World world = mock(World.class);
given(player.getWorld()).willReturn(world);
PlayerData limbo = mock(PlayerData.class);
Location location = mockLocation();
given(limbo.getLocation()).willReturn(location);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
runSyncDelayedTask(bukkitService);
// then
verify(player).teleport(location);
}
@Test
public void shouldNotTeleportForNullLocationInLimboPlayer() {
// given
given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(false);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false);
PlayerAuth auth = PlayerAuth.builder().name("bobby").build();
Player player = mock(Player.class);
PlayerData limbo = mock(PlayerData.class);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
// then
verifyZeroInteractions(player);
verify(limbo, times(2)).getLocation();
}
private static void assertCorrectLocation(Location location, PlayerAuth auth, World world) {
assertThat(location.getX(), equalTo(auth.getQuitLocX()));
assertThat(location.getY(), equalTo(auth.getQuitLocY()));
assertThat(location.getZ(), equalTo(auth.getQuitLocZ()));
assertThat(location.getWorld(), equalTo(world));
}
// We check that the World in Location is set, this method creates a mock World in Location for us
private static Location mockLocation() {
Location location = mock(Location.class);
given(location.getWorld()).willReturn(mock(World.class));
return location;
}
private static PlayerAuth createAuthWithLocation() {
return PlayerAuth.builder()
.name("bobby")
.locX(123.45).locY(23.4).locZ(-4.567)
.build();
}
}
@@ -0,0 +1,342 @@
package fr.xephi.authme.service;
import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import com.google.common.base.Strings;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.geoip.GeoLiteAPI;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.service.ValidationService.ValidationResult;
import org.bukkit.command.CommandSender;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import java.util.Collections;
import static java.util.Arrays.asList;
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.verifyZeroInteractions;
/**
* Test for {@link ValidationService}.
*/
@RunWith(DelayedInjectionRunner.class)
public class ValidationServiceTest {
@InjectDelayed
private ValidationService validationService;
@Mock
private Settings settings;
@Mock
private DataSource dataSource;
@Mock
private PermissionsManager permissionsManager;
@Mock
private GeoLiteAPI geoLiteApi;
@BeforeInjecting
public void createService() {
given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
given(settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20);
given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
.willReturn(asList("unsafe", "other-unsafe"));
given(settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(3);
given(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)).willReturn(asList("name01", "npc"));
}
@Test
public void shouldRejectPasswordSameAsUsername() {
// given/when
ValidationResult error = validationService.validatePassword("bobby", "Bobby");
// then
assertErrorEquals(error, MessageKey.PASSWORD_IS_USERNAME_ERROR);
}
@Test
public void shouldRejectPasswordNotMatchingPattern() {
// given/when
// service mock returns pattern a-zA-Z -> numbers should not be accepted
ValidationResult error = validationService.validatePassword("invalid1234", "myPlayer");
// then
assertErrorEquals(error, MessageKey.PASSWORD_CHARACTERS_ERROR, "[a-zA-Z]+");
}
@Test
public void shouldRejectTooShortPassword() {
// given/when
ValidationResult error = validationService.validatePassword("ab", "tester");
// then
assertErrorEquals(error, MessageKey.INVALID_PASSWORD_LENGTH);
}
@Test
public void shouldRejectTooLongPassword() {
// given/when
ValidationResult error = validationService.validatePassword(Strings.repeat("a", 30), "player");
// then
assertErrorEquals(error, MessageKey.INVALID_PASSWORD_LENGTH);
}
@Test
public void shouldRejectUnsafePassword() {
// given/when
ValidationResult error = validationService.validatePassword("unsafe", "playertest");
// then
assertErrorEquals(error, MessageKey.PASSWORD_UNSAFE_ERROR);
}
@Test
public void shouldAcceptValidPassword() {
// given/when
ValidationResult error = validationService.validatePassword("safePass", "some_user");
// then
assertThat(error.hasError(), equalTo(false));
}
@Test
public void shouldAcceptEmailWithEmptyLists() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.validateEmail("test@example.org");
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldAcceptEmailWithWhitelist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
.willReturn(asList("domain.tld", "example.com"));
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.validateEmail("TesT@Example.com");
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailNotInWhitelist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
.willReturn(asList("domain.tld", "example.com"));
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.validateEmail("email@other-domain.abc");
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldAcceptEmailNotInBlacklist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
.willReturn(asList("Example.org", "a-test-name.tld"));
// when
boolean result = validationService.validateEmail("sample@valid-name.tld");
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailInBlacklist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
.willReturn(asList("Example.org", "a-test-name.tld"));
// when
boolean result = validationService.validateEmail("sample@a-Test-name.tld");
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldRejectInvalidEmail() {
// given/when/then
assertThat(validationService.validateEmail("invalidinput"), equalTo(false));
}
@Test
public void shouldRejectDefaultEmail() {
// given/when/then
assertThat(validationService.validateEmail("your@email.com"), equalTo(false));
}
@Test
public void shouldAllowRegistration() {
// given
CommandSender sender = mock(CommandSender.class);
String email = "my.address@example.org";
given(permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS))
.willReturn(false);
given(dataSource.countAuthsByEmail(email)).willReturn(2);
// when
boolean result = validationService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailWithTooManyAccounts() {
// given
CommandSender sender = mock(CommandSender.class);
String email = "mail@example.org";
given(permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS))
.willReturn(false);
given(dataSource.countAuthsByEmail(email)).willReturn(5);
// when
boolean result = validationService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldAllowBypassForPresentPermission() {
// given
CommandSender sender = mock(CommandSender.class);
String email = "mail-address@example.com";
given(permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS))
.willReturn(true);
given(dataSource.countAuthsByEmail(email)).willReturn(7);
// when
boolean result = validationService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRecognizeUnrestrictedNames() {
assertThat(validationService.isUnrestricted("npc"), equalTo(true));
assertThat(validationService.isUnrestricted("someplayer"), equalTo(false));
assertThat(validationService.isUnrestricted("NAME01"), equalTo(true));
// Check reloading
given(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)).willReturn(asList("new", "names"));
validationService.reload();
assertThat(validationService.isUnrestricted("npc"), equalTo(false));
assertThat(validationService.isUnrestricted("New"), equalTo(true));
}
@Test
public void shouldNotInvokeGeoLiteApiIfCountryListsAreEmpty() {
// given
given(settings.getProperty(ProtectionSettings.COUNTRIES_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(ProtectionSettings.COUNTRIES_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.isCountryAdmitted("addr");
// then
assertThat(result, equalTo(true));
verifyZeroInteractions(geoLiteApi);
}
@Test
public void shouldAcceptCountryInWhitelist() {
// given
given(settings.getProperty(ProtectionSettings.COUNTRIES_WHITELIST)).willReturn(asList("ch", "it"));
given(settings.getProperty(ProtectionSettings.COUNTRIES_BLACKLIST)).willReturn(Collections.<String>emptyList());
String ip = "127.0.0.1";
given(geoLiteApi.getCountryCode(ip)).willReturn("CH");
// when
boolean result = validationService.isCountryAdmitted(ip);
// then
assertThat(result, equalTo(true));
verify(geoLiteApi).getCountryCode(ip);
}
@Test
public void shouldRejectCountryMissingFromWhitelist() {
// given
given(settings.getProperty(ProtectionSettings.COUNTRIES_WHITELIST)).willReturn(asList("ch", "it"));
given(settings.getProperty(ProtectionSettings.COUNTRIES_BLACKLIST)).willReturn(Collections.<String>emptyList());
String ip = "123.45.67.89";
given(geoLiteApi.getCountryCode(ip)).willReturn("BR");
// when
boolean result = validationService.isCountryAdmitted(ip);
// then
assertThat(result, equalTo(false));
verify(geoLiteApi).getCountryCode(ip);
}
@Test
public void shouldAcceptCountryAbsentFromBlacklist() {
// given
given(settings.getProperty(ProtectionSettings.COUNTRIES_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(ProtectionSettings.COUNTRIES_BLACKLIST)).willReturn(asList("ch", "it"));
String ip = "127.0.0.1";
given(geoLiteApi.getCountryCode(ip)).willReturn("BR");
// when
boolean result = validationService.isCountryAdmitted(ip);
// then
assertThat(result, equalTo(true));
verify(geoLiteApi).getCountryCode(ip);
}
@Test
public void shouldRejectCountryInBlacklist() {
// given
given(settings.getProperty(ProtectionSettings.COUNTRIES_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(ProtectionSettings.COUNTRIES_BLACKLIST)).willReturn(asList("ch", "it"));
String ip = "123.45.67.89";
given(geoLiteApi.getCountryCode(ip)).willReturn("IT");
// when
boolean result = validationService.isCountryAdmitted(ip);
// then
assertThat(result, equalTo(false));
verify(geoLiteApi).getCountryCode(ip);
}
private static void assertErrorEquals(ValidationResult validationResult, MessageKey messageKey, String... args) {
assertThat(validationResult.hasError(), equalTo(true));
assertThat(validationResult.getMessageKey(), equalTo(messageKey));
assertThat(validationResult.getArgs(), equalTo(args));
}
}