@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension;
|
||||
import fr.xephi.authme.initialization.HasCleanup;
|
||||
import fr.xephi.authme.process.register.executors.RegistrationMethod;
|
||||
import fr.xephi.authme.security.crypts.Whirlpool;
|
||||
@@ -55,6 +56,7 @@ public class ClassesConsistencyTest {
|
||||
/** Classes excluded from the field visibility test. */
|
||||
private static final Set<Class<?>> CLASSES_EXCLUDED_FROM_VISIBILITY_TEST = ImmutableSet.of(
|
||||
Whirlpool.class, // not our implementation, so we don't touch it
|
||||
MySqlExtension.class, // has immutable protected fields used by all children
|
||||
Columns.class // uses non-static String constants, which is safe
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
@@ -18,6 +20,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -206,4 +209,14 @@ public final class TestHelper {
|
||||
given(player.getAddress()).willReturn(inetSocketAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the Settings mock to return the property's default value for any given property.
|
||||
*
|
||||
* @param settings the settings mock
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void returnDefaultsForAllProperties(Settings settings) {
|
||||
given(settings.getProperty(any(Property.class)))
|
||||
.willAnswer(invocation -> ((Property<?>) invocation.getArgument(0)).getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -19,7 +12,6 @@ import org.junit.runners.Parameterized;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
@@ -37,7 +29,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
@@ -46,124 +37,57 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Test class which runs through a datasource implementation and verifies that all
|
||||
* Test class which runs through objects interacting with a database and verifies that all
|
||||
* instances of {@link AutoCloseable} that are created in the calls are closed again.
|
||||
* <p>
|
||||
* Instead of an actual connection to a datasource, we pass a mock Connection object
|
||||
* which is set to create additional mocks on demand for Statement and ResultSet objects.
|
||||
* This test ensures that all such objects that are created will be closed again by
|
||||
* keeping a list of mocks ({@link #closeables}) and then verifying that all have been
|
||||
* closed {@link #verifyHaveMocksBeenClosed()}.
|
||||
* closed ({@link #verifyHaveMocksBeenClosed()}).
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public abstract class AbstractResourceClosingTest {
|
||||
|
||||
/** List of DataSource method names not to test. */
|
||||
private static final Set<String> IGNORED_METHODS = ImmutableSet.of("reload", "close", "getType");
|
||||
|
||||
/** Collection of values to use to call methods with the parameters they expect. */
|
||||
private static final Map<Class<?>, Object> PARAM_VALUES = getDefaultParameters();
|
||||
|
||||
/**
|
||||
* Custom list of hash algorithms to use to test a method. By default we define {@link HashAlgorithm#XFBCRYPT} as
|
||||
* algorithms we use as a lot of methods execute additional statements in {@link MySQL}. If other algorithms
|
||||
* have custom behaviors, they can be supplied in this map so it will be tested as well.
|
||||
*/
|
||||
private static final Map<String, HashAlgorithm[]> CUSTOM_ALGORITHMS = getCustomAlgorithmList();
|
||||
|
||||
/** Mock of a settings instance. */
|
||||
private static Settings settings;
|
||||
|
||||
/** The datasource to test. */
|
||||
private DataSource dataSource;
|
||||
|
||||
/** The DataSource method to test. */
|
||||
private Method method;
|
||||
|
||||
/** Keeps track of the closeables which are created during the tested call. */
|
||||
private List<AutoCloseable> closeables = new ArrayList<>();
|
||||
|
||||
private boolean hasCreatedConnection = false;
|
||||
|
||||
/**
|
||||
* Constructor for the test instance verifying the given method with the given hash algorithm.
|
||||
* Constructor for the test instance verifying the given method.
|
||||
*
|
||||
* @param method The DataSource method to test
|
||||
* @param name The name of the method
|
||||
* @param algorithm The hash algorithm to use
|
||||
*/
|
||||
public AbstractResourceClosingTest(Method method, String name, HashAlgorithm algorithm) {
|
||||
public AbstractResourceClosingTest(Method method, String name) {
|
||||
// Note ljacqu 20160227: The name parameter is necessary as we pass it from the @Parameters method;
|
||||
// we use the method name in the annotation to name the test sensibly
|
||||
this.method = method;
|
||||
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(algorithm);
|
||||
}
|
||||
|
||||
/** Initialize the settings mock and makes it return the default of any given property by default. */
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@BeforeClass
|
||||
public static void initializeSettings() throws IOException, ClassNotFoundException {
|
||||
settings = mock(Settings.class);
|
||||
given(settings.getProperty(any(Property.class))).willAnswer(new Answer() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
return ((Property<?>) invocation.getArguments()[0]).getDefaultValue();
|
||||
}
|
||||
});
|
||||
public static void initializeLogger() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
/** Initialize the dataSource implementation to test based on a mock connection. */
|
||||
@Before
|
||||
public void setUpMockConnection() throws Exception {
|
||||
Connection connection = initConnection();
|
||||
dataSource = createDataSource(settings, connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual test -- executes the method given through the constructor and then verifies that all
|
||||
* AutoCloseable mocks it constructed have been closed.
|
||||
*/
|
||||
@Test
|
||||
public void shouldCloseResources() throws IllegalAccessException, InvocationTargetException {
|
||||
method.invoke(dataSource, buildParamListForMethod(method));
|
||||
method.invoke(getObjectUnderTest(), buildParamListForMethod(method));
|
||||
verifyHaveMocksBeenClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization method -- provides the parameters to run the test with by scanning all DataSource
|
||||
* methods. By default, we run one test per method with the default hash algorithm, XFBCRYPT.
|
||||
* If the map of custom algorithms has an entry for the method name, we add an entry for each algorithm
|
||||
* supplied by the map.
|
||||
*
|
||||
* @return Test parameters
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{1}({2})")
|
||||
public static Collection<Object[]> data() {
|
||||
List<Method> methods = getDataSourceMethods();
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
// Use XFBCRYPT if nothing else specified as there is a lot of specific behavior to this hash algorithm in MySQL
|
||||
final HashAlgorithm[] defaultAlgorithm = new HashAlgorithm[]{HashAlgorithm.XFBCRYPT};
|
||||
for (Method method : methods) {
|
||||
HashAlgorithm[] algorithms = MoreObjects.firstNonNull(CUSTOM_ALGORITHMS.get(method.getName()), defaultAlgorithm);
|
||||
for (HashAlgorithm algorithm : algorithms) {
|
||||
data.add(new Object[]{method, method.getName(), algorithm});
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Create a DataSource instance with the given mock settings and mock connection. */
|
||||
protected abstract DataSource createDataSource(Settings settings, Connection connection) throws Exception;
|
||||
|
||||
/* Get all methods of the DataSource interface, minus the ones in the ignored list. */
|
||||
private static List<Method> getDataSourceMethods() {
|
||||
List<Method> publicMethods = new ArrayList<>();
|
||||
for (Method method : DataSource.class.getDeclaredMethods()) {
|
||||
if (!IGNORED_METHODS.contains(method.getName())) {
|
||||
publicMethods.add(method);
|
||||
}
|
||||
}
|
||||
return publicMethods;
|
||||
}
|
||||
protected abstract Object getObjectUnderTest();
|
||||
|
||||
/**
|
||||
* Verify that all AutoCloseables that have been created during the method execution have been closed.
|
||||
@@ -187,7 +111,7 @@ public abstract class AbstractResourceClosingTest {
|
||||
* @param method The method to create a valid parameter list for
|
||||
* @return Parameter list to invoke the given method with
|
||||
*/
|
||||
private static Object[] buildParamListForMethod(Method method) {
|
||||
private Object[] buildParamListForMethod(Method method) {
|
||||
List<Object> params = new ArrayList<>();
|
||||
int index = 0;
|
||||
for (Class<?> paramType : method.getParameterTypes()) {
|
||||
@@ -195,7 +119,7 @@ public abstract class AbstractResourceClosingTest {
|
||||
// but that is a sensible assumption and makes our life much easier later on when juggling with Type
|
||||
Object param = Collection.class.isAssignableFrom(paramType)
|
||||
? getTypedCollection(method.getGenericParameterTypes()[index])
|
||||
: PARAM_VALUES.get(paramType);
|
||||
: getMethodParameter(paramType);
|
||||
Preconditions.checkNotNull(param, "No param type for " + paramType);
|
||||
params.add(param);
|
||||
++index;
|
||||
@@ -203,6 +127,15 @@ public abstract class AbstractResourceClosingTest {
|
||||
return params.toArray();
|
||||
}
|
||||
|
||||
private Object getMethodParameter(Class<?> paramType) {
|
||||
if (paramType.equals(Connection.class)) {
|
||||
Preconditions.checkArgument(!hasCreatedConnection, "A Connection object was already created in this test run");
|
||||
hasCreatedConnection = true;
|
||||
return initConnection();
|
||||
}
|
||||
return PARAM_VALUES.get(paramType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collection of the required type with some test elements that correspond to the
|
||||
* collection's generic type.
|
||||
@@ -247,29 +180,15 @@ public abstract class AbstractResourceClosingTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the custom list of hash algorithms to test a method with to execute code specific to
|
||||
* one hash algorithm. By default, XFBCRYPT is used. Only MySQL has code specific to algorithms
|
||||
* but for technical reasons the custom list will be used for all tested classes.
|
||||
*
|
||||
* @return List of custom algorithms by method
|
||||
*/
|
||||
private static Map<String, HashAlgorithm[]> getCustomAlgorithmList() {
|
||||
// We use XFBCRYPT as default encryption method so we don't have to list many of the special cases for it
|
||||
return ImmutableMap.<String, HashAlgorithm[]>builder()
|
||||
.put("saveAuth", new HashAlgorithm[]{HashAlgorithm.PHPBB, HashAlgorithm.WORDPRESS})
|
||||
.build();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// Mock initialization
|
||||
// ---------------------
|
||||
/**
|
||||
* Initialize the connection mock which produces additional AutoCloseable mocks and records them.
|
||||
* Initializes the connection mock which produces additional AutoCloseable mocks and records them.
|
||||
*
|
||||
* @return Connection mock
|
||||
*/
|
||||
private Connection initConnection() {
|
||||
protected Connection initConnection() {
|
||||
Connection connection = mock(Connection.class);
|
||||
try {
|
||||
given(connection.prepareStatement(anyString())).willAnswer(preparedStatementAnswer());
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Resource-closing test for SQL data sources.
|
||||
*/
|
||||
public abstract class AbstractSqlDataSourceResourceClosingTest extends AbstractResourceClosingTest {
|
||||
|
||||
/** List of DataSource method names not to test. */
|
||||
private static final Set<String> IGNORED_METHODS = ImmutableSet.of("reload", "getType");
|
||||
|
||||
private static Settings settings;
|
||||
|
||||
AbstractSqlDataSourceResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeSettings() {
|
||||
settings = mock(Settings.class);
|
||||
TestHelper.returnDefaultsForAllProperties(settings);
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
protected DataSource getObjectUnderTest() {
|
||||
try {
|
||||
return createDataSource(settings, initConnection());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a DataSource instance with the given mock settings and mock connection. */
|
||||
protected abstract DataSource createDataSource(Settings settings, Connection connection) throws Exception;
|
||||
|
||||
/**
|
||||
* Initialization method -- provides the parameters to run the test with by scanning all DataSource methods.
|
||||
*
|
||||
* @return Test parameters
|
||||
*/
|
||||
@Parameterized.Parameters(name = "{1}")
|
||||
public static Collection<Object[]> data() {
|
||||
List<Method> methods = getDataSourceMethods();
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
for (Method method : methods) {
|
||||
data.add(new Object[]{method, method.getName()});
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Get all methods of the DataSource interface, minus the ones in the ignored list. */
|
||||
private static List<Method> getDataSourceMethods() {
|
||||
List<Method> publicMethods = new ArrayList<>();
|
||||
for (Method method : DataSource.class.getDeclaredMethods()) {
|
||||
if (!IGNORED_METHODS.contains(method.getName())) {
|
||||
publicMethods.add(method);
|
||||
}
|
||||
}
|
||||
return publicMethods;
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@ import ch.jalu.configme.properties.Property;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension;
|
||||
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -30,6 +30,8 @@ public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
|
||||
/** Mock of a settings instance. */
|
||||
private static Settings settings;
|
||||
/** Mock of extensions factory. */
|
||||
private static MySqlExtensionsFactory extensionsFactory;
|
||||
/** SQL statement to execute before running a test. */
|
||||
private static String sqlInitialize;
|
||||
/** Connection to the H2 test database. */
|
||||
@@ -38,19 +40,15 @@ public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
/**
|
||||
* Set up the settings mock to return specific values for database settings and load {@link #sqlInitialize}.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@BeforeClass
|
||||
public static void initializeSettings() throws IOException, ClassNotFoundException {
|
||||
// Check that we have an H2 driver
|
||||
Class.forName("org.h2.jdbcx.JdbcDataSource");
|
||||
|
||||
settings = mock(Settings.class);
|
||||
when(settings.getProperty(any(Property.class))).thenAnswer(new Answer() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return ((Property) invocation.getArguments()[0]).getDefaultValue();
|
||||
}
|
||||
});
|
||||
TestHelper.returnDefaultsForAllProperties(settings);
|
||||
extensionsFactory = mock(MySqlExtensionsFactory.class);
|
||||
when(extensionsFactory.buildExtension(any(Columns.class))).thenReturn(mock(MySqlExtension.class));
|
||||
set(DatabaseSettings.MYSQL_DATABASE, "h2_test");
|
||||
set(DatabaseSettings.MYSQL_TABLE, "authme");
|
||||
TestHelper.setRealLogger();
|
||||
@@ -85,7 +83,7 @@ public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
@Override
|
||||
protected DataSource getDataSource(String saltColumn) {
|
||||
when(settings.getProperty(DatabaseSettings.MYSQL_COL_SALT)).thenReturn(saltColumn);
|
||||
return new MySQL(settings, hikariSource);
|
||||
return new MySQL(settings, hikariSource, extensionsFactory);
|
||||
}
|
||||
|
||||
private static <T> void set(Property<T> property, T value) {
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtension;
|
||||
import fr.xephi.authme.datasource.mysqlextensions.MySqlExtensionsFactory;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link MySQL}.
|
||||
*/
|
||||
public class MySqlResourceClosingTest extends AbstractResourceClosingTest {
|
||||
public class MySqlResourceClosingTest extends AbstractSqlDataSourceResourceClosingTest {
|
||||
|
||||
public MySqlResourceClosingTest(Method method, String name, HashAlgorithm algorithm) {
|
||||
super(method, name, algorithm);
|
||||
public MySqlResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSource createDataSource(Settings settings, Connection connection) throws Exception {
|
||||
HikariDataSource hikariDataSource = mock(HikariDataSource.class);
|
||||
given(hikariDataSource.getConnection()).willReturn(connection);
|
||||
return new MySQL(settings, hikariDataSource);
|
||||
MySqlExtensionsFactory extensionsFactory = mock(MySqlExtensionsFactory.class);
|
||||
given(extensionsFactory.buildExtension(any(Columns.class))).willReturn(mock(MySqlExtension.class));
|
||||
return new MySQL(settings, hikariDataSource, extensionsFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -22,7 +20,6 @@ import java.sql.Statement;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -41,19 +38,13 @@ public class SQLiteIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
/**
|
||||
* Set up the settings mock to return specific values for database settings and load {@link #sqlInitialize}.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@BeforeClass
|
||||
public static void initializeSettings() throws IOException, ClassNotFoundException {
|
||||
// Check that we have an implementation for SQLite
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
|
||||
settings = mock(Settings.class);
|
||||
when(settings.getProperty(any(Property.class))).thenAnswer(new Answer() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return ((Property) invocation.getArguments()[0]).getDefaultValue();
|
||||
}
|
||||
});
|
||||
TestHelper.returnDefaultsForAllProperties(settings);
|
||||
set(DatabaseSettings.MYSQL_DATABASE, "sqlite-test");
|
||||
set(DatabaseSettings.MYSQL_TABLE, "authme");
|
||||
TestHelper.setRealLogger();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -9,10 +8,10 @@ import java.sql.Connection;
|
||||
/**
|
||||
* Resource closing test for {@link SQLite}.
|
||||
*/
|
||||
public class SQLiteResourceClosingTest extends AbstractResourceClosingTest {
|
||||
public class SQLiteResourceClosingTest extends AbstractSqlDataSourceResourceClosingTest {
|
||||
|
||||
public SQLiteResourceClosingTest(Method method, String name, HashAlgorithm algorithm) {
|
||||
super(method, name, algorithm);
|
||||
public SQLiteResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package fr.xephi.authme.datasource.mysqlextensions;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.datasource.AbstractResourceClosingTest;
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Checks that SQL resources are closed properly in {@link MySqlExtension} implementations.
|
||||
*/
|
||||
public abstract class AbstractMySqlExtensionResourceClosingTest extends AbstractResourceClosingTest {
|
||||
|
||||
private static Settings settings;
|
||||
private static Columns columns;
|
||||
|
||||
public AbstractMySqlExtensionResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void initSettings() {
|
||||
settings = mock(Settings.class);
|
||||
TestHelper.returnDefaultsForAllProperties(settings);
|
||||
columns = new Columns(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySqlExtension getObjectUnderTest() {
|
||||
return createExtension(settings, columns);
|
||||
}
|
||||
|
||||
protected abstract MySqlExtension createExtension(Settings settings, Columns columns);
|
||||
|
||||
@Parameterized.Parameters(name = "{1}")
|
||||
public static List<Object[]> createParameters() {
|
||||
return Arrays.stream(MySqlExtension.class.getDeclaredMethods())
|
||||
.filter(m -> Modifier.isPublic(m.getModifiers()))
|
||||
.map(m -> new Object[]{m, m.getName()})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package fr.xephi.authme.datasource.mysqlextensions;
|
||||
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link Ipb4Extension}.
|
||||
*/
|
||||
public class Ipb4ExtensionResourceClosingTest extends AbstractMySqlExtensionResourceClosingTest {
|
||||
|
||||
public Ipb4ExtensionResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySqlExtension createExtension(Settings settings, Columns columns) {
|
||||
return new Ipb4Extension(settings, columns);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fr.xephi.authme.datasource.mysqlextensions;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
/**
|
||||
* Test for {@link NoOpExtension}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NoOpExtensionTest {
|
||||
|
||||
private NoOpExtension extension;
|
||||
|
||||
@Before
|
||||
public void createExtension() {
|
||||
Settings settings = mock(Settings.class);
|
||||
TestHelper.returnDefaultsForAllProperties(settings);
|
||||
Columns columns = new Columns(settings);
|
||||
extension = new NoOpExtension(settings, columns);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotHaveAnyInteractionsWithConnection() throws SQLException {
|
||||
// given
|
||||
Connection connection = mock(Connection.class);
|
||||
PlayerAuth auth = mock(PlayerAuth.class);
|
||||
int id = 3;
|
||||
String name = "Bobby";
|
||||
HashedPassword password = new HashedPassword("test", "toast");
|
||||
|
||||
|
||||
// when
|
||||
extension.extendAuth(auth, id, connection);
|
||||
extension.changePassword(name, password, connection);
|
||||
extension.removeAuth(name, connection);
|
||||
extension.saveAuth(auth, connection);
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(connection, auth);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package fr.xephi.authme.datasource.mysqlextensions;
|
||||
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link PhpBbExtension}.
|
||||
*/
|
||||
public class PhpBbExtensionResourceClosingTest extends AbstractMySqlExtensionResourceClosingTest {
|
||||
|
||||
public PhpBbExtensionResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySqlExtension createExtension(Settings settings, Columns columns) {
|
||||
return new PhpBbExtension(settings, columns);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package fr.xephi.authme.datasource.mysqlextensions;
|
||||
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link WordpressExtension}.
|
||||
*/
|
||||
public class WordpressExtensionResourceClosingTest extends AbstractMySqlExtensionResourceClosingTest {
|
||||
|
||||
public WordpressExtensionResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySqlExtension createExtension(Settings settings, Columns columns) {
|
||||
return new WordpressExtension(settings, columns);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package fr.xephi.authme.datasource.mysqlextensions;
|
||||
|
||||
import fr.xephi.authme.datasource.Columns;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Resource closing test for {@link XfBcryptExtension}.
|
||||
*/
|
||||
public class XfBcryptExtensionResourceClosingTest extends AbstractMySqlExtensionResourceClosingTest {
|
||||
|
||||
public XfBcryptExtensionResourceClosingTest(Method method, String name) {
|
||||
super(method, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySqlExtension createExtension(Settings settings, Columns columns) {
|
||||
return new XfBcryptExtension(settings, columns);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user