Add missing tests for listeners

This commit is contained in:
ljacqu 2017-05-07 09:43:59 +02:00
parent 6ecb0ea75c
commit 1a48348824
4 changed files with 300 additions and 34 deletions

View File

@ -16,6 +16,7 @@ import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -42,10 +43,6 @@ import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent; import org.bukkit.event.player.PlayerShearEntityEvent;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_MOVEMENT_RADIUS; import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_MOVEMENT_RADIUS;
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT; import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT;
@ -107,15 +104,8 @@ public class PlayerListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
m.send(player, MessageKey.DENIED_CHAT); m.send(player, MessageKey.DENIED_CHAT);
} else if (settings.getProperty(RestrictionSettings.HIDE_CHAT)) { } else if (settings.getProperty(RestrictionSettings.HIDE_CHAT)) {
Set<Player> recipients = event.getRecipients(); event.getRecipients().removeIf(listenerService::shouldCancelEvent);
Iterator<Player> iter = recipients.iterator(); if (event.getRecipients().isEmpty()) {
while (iter.hasNext()) {
Player p = iter.next();
if (listenerService.shouldCancelEvent(p)) {
iter.remove();
}
}
if (recipients.isEmpty()) {
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -300,18 +290,17 @@ public class PlayerListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInventoryOpen(InventoryOpenEvent event) { public void onPlayerInventoryOpen(InventoryOpenEvent event) {
final Player player = (Player) event.getPlayer(); final HumanEntity player = event.getPlayer();
if (!listenerService.shouldCancelEvent(player)) { if (listenerService.shouldCancelEvent(player)) {
return; event.setCancelled(true);
/*
* @note little hack cause InventoryOpenEvent cannot be cancelled for
* real, cause no packet is sent to server by client for the main inv
*/
bukkitService.scheduleSyncDelayedTask(player::closeInventory, 1);
} }
event.setCancelled(true);
/*
* @note little hack cause InventoryOpenEvent cannot be cancelled for
* real, cause no packet is send to server by client for the main inv
*/
bukkitService.scheduleSyncDelayedTask(player::closeInventory, 1);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)

View File

@ -16,14 +16,14 @@ public final class ReflectionTestUtils {
} }
/** /**
* Set the field of a given object to a new value with reflection. * Sets the field of a given object to a new value with reflection.
* *
* @param clazz The class of the object * @param clazz the class declaring the field
* @param instance The instance to modify (pass null for static fields) * @param instance the instance to modify (pass null for static fields)
* @param fieldName The field name * @param fieldName the field name
* @param value The value to set the field to * @param value the value to set the field to
*/ */
public static <T> void setField(Class<T> clazz, T instance, String fieldName, Object value) { public static <T> void setField(Class<? super T> clazz, T instance, String fieldName, Object value) {
try { try {
Field field = getField(clazz, fieldName); Field field = getField(clazz, fieldName);
field.set(instance, value); field.set(instance, value);
@ -34,6 +34,18 @@ public final class ReflectionTestUtils {
} }
} }
/**
* Sets the field on the given instance to the new value.
*
* @param instance the instance to modify
* @param fieldName the field name
* @param value the value to set the field to
*/
@SuppressWarnings("unchecked")
public static void setField(Object instance, String fieldName, Object value) {
setField((Class) instance.getClass(), instance, fieldName, value);
}
private static <T> Field getField(Class<T> clazz, String fieldName) { private static <T> Field getField(Class<T> clazz, String fieldName) {
try { try {
Field field = clazz.getDeclaredField(fieldName); Field field = clazz.getDeclaredField(fieldName);
@ -62,13 +74,13 @@ public final class ReflectionTestUtils {
} }
/** /**
* Return the method on the given class with the supplied parameter types. * Returns the method on the given class with the supplied parameter types.
* *
* @param clazz The class to retrieve a method from * @param clazz the class to retrieve a method from
* @param methodName The name of the method * @param methodName the name of the method
* @param parameterTypes The parameter types the method to retrieve has * @param parameterTypes the parameter types the method to retrieve has
* *
* @return The method of the class, set to be accessible * @return the method of the class, set to be accessible
*/ */
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) { public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
try { try {

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.listener; package fr.xephi.authme.listener;
import fr.xephi.authme.ReflectionTestUtils;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
@ -19,6 +20,8 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -194,4 +197,23 @@ public class EntityListenerTest {
verify(listenerService).shouldCancelEvent(player); verify(listenerService).shouldCancelEvent(player);
verify(event).setCancelled(true); verify(event).setCancelled(true);
} }
@Test
public void shouldHandleOldShooterMethod() {
// given
ReflectionTestUtils.setField(listener, "shooterIsLivingEntity", true);
ReflectionTestUtils.setField(listener, "getShooter", null);
Projectile projectile = mock(Projectile.class);
Player shooter = mock(Player.class);
given(projectile.getShooter()).willReturn(shooter);
ProjectileLaunchEvent event = new ProjectileLaunchEvent(projectile);
given(listenerService.shouldCancelEvent(shooter)).willReturn(true);
// when
listener.onProjectileLaunch(event);
// then
verify(listenerService).shouldCancelEvent(shooter);
assertThat(event.isCancelled(), equalTo(true));
}
} }

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.listener; package fr.xephi.authme.listener;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
@ -7,17 +8,23 @@ import fr.xephi.authme.message.Messages;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.service.AntiBotService; import fr.xephi.authme.service.AntiBotService;
import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.JoinMessageService;
import fr.xephi.authme.service.TeleportationService; import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
@ -31,7 +38,9 @@ import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerShearEntityEvent; import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.inventory.InventoryView;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
@ -49,9 +58,11 @@ import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow;
@ -95,6 +106,8 @@ public class PlayerListenerTest {
private TeleportationService teleportationService; private TeleportationService teleportationService;
@Mock @Mock
private ValidationService validationService; private ValidationService validationService;
@Mock
private JoinMessageService joinMessageService;
/** /**
* #831: If a player is kicked because of "logged in from another location", the kick * #831: If a player is kicked because of "logged in from another location", the kick
@ -596,6 +609,236 @@ public class PlayerListenerTest {
verify(event).setResult(PlayerLoginEvent.Result.KICK_OTHER); verify(event).setResult(PlayerLoginEvent.Result.KICK_OTHER);
} }
@Test
public void shouldRemoveMessageOnQuit() {
// given
given(settings.getProperty(RegistrationSettings.REMOVE_LEAVE_MESSAGE)).willReturn(true);
given(antiBotService.wasPlayerKicked(anyString())).willReturn(false);
Player player = mockPlayerWithName("Billy");
PlayerQuitEvent event = new PlayerQuitEvent(player, "Player has quit the server");
// when
listener.onPlayerQuit(event);
// then
assertThat(event.getQuitMessage(), nullValue());
verify(antiBotService).wasPlayerKicked("Billy");
verify(management).performQuit(player);
}
@Test
public void shouldRemoveMessageForUnloggedUser() {
// given
given(settings.getProperty(RegistrationSettings.REMOVE_LEAVE_MESSAGE)).willReturn(false);
given(settings.getProperty(RegistrationSettings.REMOVE_UNLOGGED_LEAVE_MESSAGE)).willReturn(true);
String name = "Joel";
given(antiBotService.wasPlayerKicked(name)).willReturn(true);
Player player = mockPlayerWithName(name);
PlayerQuitEvent event = new PlayerQuitEvent(player, "Joel exits the party");
given(listenerService.shouldCancelEvent(event)).willReturn(true);
// when
listener.onPlayerQuit(event);
// then
assertThat(event.getQuitMessage(), nullValue());
verify(antiBotService).wasPlayerKicked(name);
verifyZeroInteractions(management);
}
@Test
public void shouldProcessPlayerAndKeepQuitMessage() {
// given
String name = "Louis";
Player player = mockPlayerWithName(name);
given(settings.getProperty(RegistrationSettings.REMOVE_LEAVE_MESSAGE)).willReturn(false);
given(settings.getProperty(RegistrationSettings.REMOVE_UNLOGGED_LEAVE_MESSAGE)).willReturn(false);
given(antiBotService.wasPlayerKicked(name)).willReturn(false);
String quitMessage = "The player has left the server.";
PlayerQuitEvent event = new PlayerQuitEvent(player, quitMessage);
// when
listener.onPlayerQuit(event);
// then
assertThat(event.getQuitMessage(), equalTo(quitMessage));
verify(antiBotService).wasPlayerKicked(name);
verify(management).performQuit(player);
}
@Test
public void shouldCancelInventoryClickEvent() {
// given
InventoryClickEvent event = mock(InventoryClickEvent.class);
HumanEntity player = mock(Player.class);
given(event.getWhoClicked()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(true);
// when
listener.onPlayerInventoryClick(event);
// then
verify(event).setCancelled(true);
}
@Test
public void shouldAllowInventoryClickEvent() {
// given
InventoryClickEvent event = mock(InventoryClickEvent.class);
HumanEntity player = mock(Player.class);
given(event.getWhoClicked()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(false);
// when
listener.onPlayerInventoryClick(event);
// then
verify(event, only()).getWhoClicked();
}
@Test
public void shouldAllowSignChangeEvent() {
// given
SignChangeEvent event = mock(SignChangeEvent.class);
Player player = mock(Player.class);
given(event.getPlayer()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(false);
// when
listener.onSignChange(event);
// then
verify(event, only()).getPlayer();
}
@Test
public void shouldCancelSignChangeEvent() {
// given
SignChangeEvent event = mock(SignChangeEvent.class);
Player player = mock(Player.class);
given(event.getPlayer()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(true);
// when
listener.onSignChange(event);
// then
verify(event).setCancelled(true);
}
@Test
public void shouldAllowInventoryOpen() {
// given
HumanEntity player = mock(Player.class);
InventoryView transaction = mock(InventoryView.class);
given(transaction.getPlayer()).willReturn(player);
InventoryOpenEvent event = new InventoryOpenEvent(transaction);
given(event.getPlayer()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(false);
// when
listener.onPlayerInventoryOpen(event);
// then
assertThat(event.isCancelled(), equalTo(false));
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldCancelInventoryOpen() {
// given
HumanEntity player = mock(Player.class);
InventoryView transaction = mock(InventoryView.class);
given(transaction.getPlayer()).willReturn(player);
InventoryOpenEvent event = new InventoryOpenEvent(transaction);
given(event.getPlayer()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(true);
// when
listener.onPlayerInventoryOpen(event);
// then
assertThat(event.isCancelled(), equalTo(true));
TestHelper.runSyncDelayedTaskWithDelay(bukkitService);
verify(player).closeInventory();
}
@Test
public void shouldNotModifyJoinMessage() {
// given
Player player = mock(Player.class);
String joinMsg = "The player joined";
PlayerJoinEvent event = new PlayerJoinEvent(player, joinMsg);
given(settings.getProperty(RegistrationSettings.REMOVE_JOIN_MESSAGE)).willReturn(false);
given(settings.getProperty(RegistrationSettings.CUSTOM_JOIN_MESSAGE)).willReturn("");
given(settings.getProperty(RegistrationSettings.DELAY_JOIN_MESSAGE)).willReturn(false);
// when
listener.onJoinMessage(event);
// then
assertThat(event.getJoinMessage(), equalTo(joinMsg));
verifyZeroInteractions(joinMessageService);
}
@Test
public void shouldRemoveJoinMessage() {
// given
Player player = mock(Player.class);
String joinMsg = "The player joined";
PlayerJoinEvent event = new PlayerJoinEvent(player, joinMsg);
given(settings.getProperty(RegistrationSettings.REMOVE_JOIN_MESSAGE)).willReturn(true);
// when
listener.onJoinMessage(event);
// then
assertThat(event.getJoinMessage(), nullValue());
verifyZeroInteractions(joinMessageService);
}
@Test
public void shouldUseCustomMessage() {
// given
Player player = mock(Player.class);
given(player.getName()).willReturn("doooew");
given(player.getDisplayName()).willReturn("Displ");
String joinMsg = "The player joined";
PlayerJoinEvent event = new PlayerJoinEvent(player, joinMsg);
given(settings.getProperty(RegistrationSettings.REMOVE_JOIN_MESSAGE)).willReturn(false);
given(settings.getProperty(RegistrationSettings.CUSTOM_JOIN_MESSAGE))
.willReturn("Hello {PLAYERNAME} (aka {DISPLAYNAME})");
given(settings.getProperty(RegistrationSettings.DELAY_JOIN_MESSAGE)).willReturn(false);
// when
listener.onJoinMessage(event);
// then
assertThat(event.getJoinMessage(), equalTo("Hello doooew (aka Displ)"));
verifyZeroInteractions(joinMessageService);
}
@Test
public void shouldDelayJoinMessage() {
// given
Player player = mock(Player.class);
given(player.getName()).willReturn("thename0");
given(player.getDisplayName()).willReturn("(not used)");
String joinMsg = "The player joined";
PlayerJoinEvent event = new PlayerJoinEvent(player, joinMsg);
given(settings.getProperty(RegistrationSettings.REMOVE_JOIN_MESSAGE)).willReturn(false);
given(settings.getProperty(RegistrationSettings.CUSTOM_JOIN_MESSAGE))
.willReturn("{PLAYERNAME} is joining us");
given(settings.getProperty(RegistrationSettings.DELAY_JOIN_MESSAGE)).willReturn(true);
// when
listener.onJoinMessage(event);
// then
assertThat(event.getJoinMessage(), nullValue());
verify(joinMessageService).putMessage("thename0", "thename0 is joining us");
}
private static Player mockPlayerWithName(String name) { private static Player mockPlayerWithName(String name) {
Player player = mock(Player.class); Player player = mock(Player.class);
given(player.getName()).willReturn(name); given(player.getName()).willReturn(name);