Add template for assignment 1
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package dst.ass1.jpa;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Factory;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Matcher that finds items in string collections in a case-insensitive way.
|
||||
*/
|
||||
public class CaseInsensitiveStringCollectionMatcher extends TypeSafeDiagnosingMatcher<List<String>> {
|
||||
|
||||
private final String[] items;
|
||||
|
||||
public CaseInsensitiveStringCollectionMatcher(String... items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Factory
|
||||
public static CaseInsensitiveStringCollectionMatcher hasItems(String... items) {
|
||||
return new CaseInsensitiveStringCollectionMatcher(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(List<String> collection, Description description) {
|
||||
List<String> missing = new ArrayList<>();
|
||||
|
||||
for (String item : items) {
|
||||
if (collection.stream().noneMatch(i -> i.equalsIgnoreCase(item))) {
|
||||
missing.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (!missing.isEmpty()) {
|
||||
if (missing.size() == items.length) {
|
||||
description.appendValueList("was [", ", ", "]", collection);
|
||||
} else {
|
||||
description.appendValueList("missing [", ", ", "]", missing)
|
||||
.appendValueList(" in [", ", ", "]", collection);
|
||||
}
|
||||
}
|
||||
|
||||
return missing.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendValueList("collection containing ", " and ", "", items);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
package dst.ass1.jpa;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.jdbc.ReturningWork;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.metamodel.Type;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// DO NOT MODIFY THIS CLASS.
|
||||
|
||||
/**
|
||||
* Contains various methods for accessing the database underlying an EntityManager.
|
||||
* <p>
|
||||
* Note that the caller is responsible for dealing with possible exceptions as well as doing the connection handling. A
|
||||
* connection will not be closed even if a fatal error occurs. However, other SQL resources i.e.,
|
||||
* {@link Statement Statements} and {@link ResultSet ResultSets} created within the methods, which are not returned to
|
||||
* the caller, are closed before the method returns.
|
||||
*/
|
||||
public class DatabaseGateway {
|
||||
|
||||
private final EntityManager em;
|
||||
|
||||
public DatabaseGateway(EntityManager em) {
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all table-names for the given database/connection.
|
||||
*
|
||||
* @return List of table names
|
||||
*/
|
||||
public List<String> getTables() {
|
||||
return getSession().doReturningWork(new CollectionWork<>("show tables", rs -> rs.getString(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all column names in the given table.
|
||||
*
|
||||
* @param tableName the table
|
||||
* @return a list of column names
|
||||
*/
|
||||
public List<String> getColumns(String tableName) {
|
||||
return getColumnsDefinitions(tableName).stream().map(m -> m.get("COLUMN_NAME")).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getColumnsDefinitions(String tableName) {
|
||||
String sql = String.format("SELECT * FROM information_schema.columns "
|
||||
+ "WHERE table_name='%s'", tableName.toUpperCase());
|
||||
|
||||
return getSession().doReturningWork(new QueryWork<List<Map<String, String>>>(sql) {
|
||||
@Override
|
||||
protected List<Map<String, String>> execute(ResultSet rs) throws SQLException {
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
ResultSetMetaData meta = rs.getMetaData();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
String key = meta.getColumnName(i);
|
||||
String value = rs.getString(key);
|
||||
map.put(key, value);
|
||||
}
|
||||
list.add(map);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the java types of all managed entity types.
|
||||
*
|
||||
* @return a list of java types
|
||||
*/
|
||||
public List<Class<?>> getManagedJavaTypes() {
|
||||
return em.getMetamodel()
|
||||
.getManagedTypes().stream()
|
||||
.map(Type::getJavaType)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the named table can be accessed via the given EntityManager.
|
||||
*
|
||||
* @param tableName the name of the table to find
|
||||
* @return {@code true} if the database schema contains a table with the given name, {@code false} otherwise
|
||||
*/
|
||||
public boolean isTable(final String tableName) {
|
||||
return getSession().doReturningWork(new QueryWork<Boolean>("show tables") {
|
||||
@Override
|
||||
public Boolean execute(ResultSet rs) throws SQLException {
|
||||
while (rs.next()) {
|
||||
String tbl = rs.getString(1);
|
||||
if (tbl.equalsIgnoreCase(tableName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a certain database table contains a column with the given
|
||||
* name.
|
||||
*
|
||||
* @param tableName the name of the table to check
|
||||
* @param column the name of the column to find
|
||||
* @return {@code true} if the table contains the column, {@code false} otherwise
|
||||
*/
|
||||
public boolean isColumnInTable(String tableName, String column) {
|
||||
String sql = String.format(
|
||||
"SELECT * FROM information_schema.columns WHERE table_name='%s' and column_name='%s'",
|
||||
tableName.toUpperCase(), column.toUpperCase()
|
||||
);
|
||||
|
||||
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a table contains a column of the given type and length.
|
||||
*
|
||||
* @param tableName the table to look for
|
||||
* @param column the expected column name
|
||||
* @param type the expected column type
|
||||
* @param length the expected column length
|
||||
* @return true if the information schema has at least one such column
|
||||
*/
|
||||
public boolean isColumnInTableWithType(String tableName, String column, String type, String length) {
|
||||
String sql = String.format("SELECT * FROM information_schema.columns "
|
||||
+ "WHERE table_name='%s' and column_name='%s' and "
|
||||
+ "type_name='%s' and character_maximum_length='%s'",
|
||||
tableName.toUpperCase(), column.toUpperCase(), type.toUpperCase(), length);
|
||||
|
||||
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a certain table contains an index for the given column
|
||||
* name.
|
||||
*
|
||||
* @param tableName the name of the table to check
|
||||
* @param indexName the name of the column the index is created for
|
||||
* @param nonUnique {@code true} if the index is non unique, {@code false} otherwise
|
||||
* @return {@code true} if the index exists, {@code false} otherwise
|
||||
*/
|
||||
public boolean isIndex(String tableName, String indexName, boolean nonUnique) {
|
||||
|
||||
String sql = String.format(
|
||||
"SELECT * FROM information_schema.indexes WHERE table_name='%s' and column_name='%s' and non_unique='%s'",
|
||||
tableName.toUpperCase(), indexName.toUpperCase(), nonUnique ? "1" : "0"
|
||||
);
|
||||
|
||||
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
|
||||
}
|
||||
|
||||
public boolean isComposedIndex(String tableName, String columnName1, String columnName2) {
|
||||
String indexName1 = getIndexName(tableName, columnName1);
|
||||
String indexName2 = getIndexName(tableName, columnName2);
|
||||
|
||||
return Objects.nonNull(indexName1) && Objects.equals(indexName1, indexName2);
|
||||
}
|
||||
|
||||
private String getIndexName(String tableName, String columnName) {
|
||||
String sql = String.format(
|
||||
"SELECT index_name FROM information_schema.indexes WHERE table_name='%s' and column_name='%s'",
|
||||
tableName.toUpperCase(), columnName.toUpperCase()
|
||||
);
|
||||
|
||||
return getSession().doReturningWork(new QueryWork<String>(sql) {
|
||||
@Override
|
||||
protected String execute(ResultSet rs) throws SQLException {
|
||||
return (rs.next()) ? rs.getString(1) : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given column of a certain table can contain {@code NULL} values.
|
||||
*
|
||||
* @param tableName the name of the table to check
|
||||
* @param columnName the name of the column to check
|
||||
* @return {@code true} if the column is nullable, {@code false} otherwise
|
||||
*/
|
||||
public boolean isNullable(String tableName, String columnName) {
|
||||
String sql = String.format(
|
||||
"SELECT * FROM information_schema.columns " +
|
||||
"WHERE table_name='%s' and column_name='%s' and IS_NULLABLE=true",
|
||||
tableName.toUpperCase(), columnName.toUpperCase()
|
||||
);
|
||||
|
||||
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all data from all tables that can be accessed via the given EntityManager.
|
||||
*/
|
||||
public void truncateTables() {
|
||||
List<String> tables = getTables();
|
||||
tables.removeIf(t -> t.toLowerCase().startsWith("hibernate"));
|
||||
|
||||
getSession().doWork(connection -> {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
stmt.addBatch("SET FOREIGN_KEY_CHECKS=0");
|
||||
for (String table : tables) {
|
||||
stmt.addBatch("TRUNCATE TABLE " + table);
|
||||
}
|
||||
stmt.addBatch("SET FOREIGN_KEY_CHECKS=1");
|
||||
stmt.executeBatch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
return em.unwrap(Session.class);
|
||||
}
|
||||
|
||||
public interface StatementWork<T> extends ReturningWork<T> {
|
||||
|
||||
default T execute(Connection connection) throws SQLException {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
return execute(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
T execute(Statement stmt) throws SQLException;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CheckedFunction<T, R, E extends Exception> {
|
||||
R apply(T t) throws E;
|
||||
}
|
||||
|
||||
public static abstract class QueryWork<T> implements StatementWork<T> {
|
||||
private final String sql;
|
||||
|
||||
public QueryWork(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T execute(Statement stmt) throws SQLException {
|
||||
try (ResultSet rs = stmt.executeQuery(sql)) {
|
||||
return execute(rs);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T execute(ResultSet rs) throws SQLException;
|
||||
}
|
||||
|
||||
public static class HasAtLeastOneEntry extends QueryWork<Boolean> {
|
||||
|
||||
public HasAtLeastOneEntry(String sql) {
|
||||
super(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean execute(ResultSet rs) throws SQLException {
|
||||
return rs.next();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CollectionWork<T> extends QueryWork<List<T>> {
|
||||
|
||||
private final CheckedFunction<ResultSet, T, SQLException> extractor;
|
||||
|
||||
public CollectionWork(String sql, CheckedFunction<ResultSet, T, SQLException> extractor) {
|
||||
super(sql);
|
||||
this.extractor = extractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<T> execute(ResultSet rs) throws SQLException {
|
||||
List<T> list = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
list.add(extractor.apply(rs));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dst.ass1.jpa;
|
||||
|
||||
import dst.ass1.jpa.model.IModelFactory;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
// DO NOT MODIFY THIS CLASS.
|
||||
|
||||
/**
|
||||
* The ITestData interface is used by the {@link ORMService} to insert test data before each test run. You can pass
|
||||
* custom implementation of {@link ITestData} to the constructor of {@link ORMService} to create your own test fixture.
|
||||
*/
|
||||
public interface ITestData {
|
||||
/**
|
||||
* Creates test data using the model factory and inserts them into the entity manager.
|
||||
*
|
||||
* @param modelFactory the model factory
|
||||
* @param em the entity manager
|
||||
*/
|
||||
void insert(IModelFactory modelFactory, EntityManager em);
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package dst.ass1.jpa;
|
||||
|
||||
import dst.ass1.jpa.dao.IDAOFactory;
|
||||
import dst.ass1.jpa.dao.impl.DAOFactory;
|
||||
import dst.ass1.jpa.model.IModelFactory;
|
||||
import dst.ass1.jpa.model.impl.ModelFactory;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.rules.ExternalResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
// DO NOT MODIFY THIS CLASS.
|
||||
|
||||
/**
|
||||
* The ORMService class is used as a JUnit rule that, before each test run,
|
||||
* a) creates an entity manager factory from the persistence unit referenced in {@link Constants#JPA_PERSISTENCE_UNIT},
|
||||
* b) creates an entity manager using the factory,
|
||||
* c) creates dao and model factory instances, and
|
||||
* d) creates a database gateway for the entity manager.
|
||||
* <p>
|
||||
* It provides methods to access these services, and it closes the entity manager and corresponding factory after each
|
||||
* test run. If you pass an {@link ITestData} instance to the constructor, the {@link ORMService} will also insert test
|
||||
* data via a transaction before each run, and truncate tables after each run.
|
||||
*/
|
||||
public class ORMService extends ExternalResource {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ORMService.class);
|
||||
|
||||
private static EntityManagerFactory emf;
|
||||
private EntityManager em;
|
||||
|
||||
private DatabaseGateway databaseGateway;
|
||||
|
||||
private IModelFactory modelFactory;
|
||||
private IDAOFactory daoFactory;
|
||||
|
||||
private ITestData testData;
|
||||
private boolean insertTestData;
|
||||
private boolean truncateTables;
|
||||
|
||||
/**
|
||||
* Creates a new ORMService. By default, the ORMService rule only creates the database connection and other
|
||||
* ORM facilities. If you want to also insert a test fixture, use {@link #ORMService(ITestData)}.
|
||||
*/
|
||||
public ORMService() {
|
||||
this(null, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ORMService that also inserts the given {@link ITestData} before each run and truncates the tables
|
||||
* afterwards.
|
||||
*
|
||||
* @param testData the test data to insert
|
||||
*/
|
||||
public ORMService(ITestData testData) {
|
||||
this(testData, true, true);
|
||||
}
|
||||
|
||||
public ORMService(ITestData testData, boolean insertTestData, boolean truncateTables) {
|
||||
this.testData = testData;
|
||||
this.insertTestData = insertTestData;
|
||||
this.truncateTables = truncateTables;
|
||||
}
|
||||
|
||||
private static EntityManagerFactory createEntityManagerFactory() {
|
||||
return Persistence.createEntityManagerFactory(Constants.JPA_PERSISTENCE_UNIT);
|
||||
}
|
||||
|
||||
public EntityManager getEntityManager() {
|
||||
return em;
|
||||
}
|
||||
|
||||
public EntityManager createEntityManager() {
|
||||
return emf.createEntityManager();
|
||||
}
|
||||
|
||||
public IModelFactory getModelFactory() {
|
||||
return modelFactory;
|
||||
}
|
||||
|
||||
public IDAOFactory getDaoFactory() {
|
||||
return daoFactory;
|
||||
}
|
||||
|
||||
public DatabaseGateway getDatabaseGateway() {
|
||||
return databaseGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link #getEntityManager()}.
|
||||
*
|
||||
* @return an entity manager
|
||||
*/
|
||||
public EntityManager em() {
|
||||
return getEntityManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void before() throws Throwable {
|
||||
LOG.debug("Creating EntityManagerFactory");
|
||||
emf = createEntityManagerFactory();
|
||||
|
||||
LOG.debug("Creating EntityManager");
|
||||
em = emf.createEntityManager();
|
||||
databaseGateway = new DatabaseGateway(em);
|
||||
|
||||
LOG.debug("Initializing factories");
|
||||
// initialize factories
|
||||
modelFactory = new ModelFactory();
|
||||
daoFactory = new DAOFactory(em);
|
||||
|
||||
if (testData != null && insertTestData) {
|
||||
insertTestData(testData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void after() {
|
||||
if (truncateTables) {
|
||||
truncateTables();
|
||||
}
|
||||
|
||||
try {
|
||||
LOG.debug("Closing EntityManager");
|
||||
em.close();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error while closing entity manager", e);
|
||||
}
|
||||
|
||||
try {
|
||||
LOG.debug("Closing EntityManagerFactory");
|
||||
emf.close();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error while closing entity manager factory", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void insertTestData(ITestData data) {
|
||||
EntityTransaction tx = getEntityManager().getTransaction();
|
||||
|
||||
tx.begin();
|
||||
try {
|
||||
data.insert(getModelFactory(), getEntityManager());
|
||||
tx.commit();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
if (tx.isActive()) {
|
||||
tx.rollback();
|
||||
}
|
||||
} catch (Exception rollbackException) {
|
||||
LOG.error("Error while rolling back transaction after exception", rollbackException);
|
||||
} finally {
|
||||
throw new IllegalStateException("Couldn't insert fixture. Can't proceed with tests", e); // rethrow original exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void truncateTables() {
|
||||
try {
|
||||
LOG.debug("Truncating database tables");
|
||||
getDatabaseGateway().truncateTables();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error while trying to truncate tables after test", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package dst.ass1.jpa.examples;
|
||||
|
||||
import dst.ass1.jpa.ITestData;
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.dao.IVehicleDAO;
|
||||
import dst.ass1.jpa.model.IModelFactory;
|
||||
import dst.ass1.jpa.model.IVehicle;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* This examples shows how you can write your own tests with custom fixtures that are injected it into the
|
||||
* {@link ORMService} rule. Using rules instead of abstract tests is considered good practice as it follows the
|
||||
* principle of composition over inheritance.
|
||||
*/
|
||||
public class ExampleTestWithCustomTestData {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService(new MyTestData());
|
||||
|
||||
@Test
|
||||
public void vehicleDAO_findAll_returnsCorrectValues() throws Exception {
|
||||
IVehicleDAO vehicleDAO = orm.getDaoFactory().createVehicleDAO();
|
||||
|
||||
List<IVehicle> all = vehicleDAO.findAll();
|
||||
|
||||
assertThat(all.isEmpty(), is(false));
|
||||
assertThat(all.size(), is(2));
|
||||
|
||||
System.out.println(all);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicleDAO_findById_returnsCorrectValue() throws Exception {
|
||||
IVehicleDAO vehicleDAO = orm.getDaoFactory().createVehicleDAO();
|
||||
|
||||
IVehicle actual = vehicleDAO.findById(1L);
|
||||
|
||||
assertThat(actual.getColor(), is("red"));
|
||||
}
|
||||
|
||||
public static class MyTestData implements ITestData {
|
||||
|
||||
@Override
|
||||
public void insert(IModelFactory modelFactory, EntityManager em) {
|
||||
IVehicle vehicle1 = modelFactory.createVehicle();
|
||||
IVehicle vehicle2 = modelFactory.createVehicle();
|
||||
|
||||
vehicle1.setColor("red");
|
||||
vehicle1.setLicense("license1");
|
||||
vehicle1.setType("type_1");
|
||||
|
||||
vehicle2.setColor("blue");
|
||||
vehicle2.setLicense("license2");
|
||||
vehicle2.setType("type_2");
|
||||
|
||||
em.persist(vehicle1);
|
||||
em.persist(vehicle2);
|
||||
|
||||
em.flush(); // transaction is done through the ORMTestFixture
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package dst.ass1.jpa.examples;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.dao.IDAOFactory;
|
||||
import dst.ass1.jpa.dao.IVehicleDAO;
|
||||
import dst.ass1.jpa.model.IModelFactory;
|
||||
import dst.ass1.jpa.model.IVehicle;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* This test has no test fixture and dependencies between tests. This is possible by declaring {@link ORMService} as a
|
||||
* static class-level rule via {@link ClassRule}.
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class ExampleTestWithDependencies {
|
||||
|
||||
@ClassRule
|
||||
public static ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void t01_insert() throws Exception {
|
||||
EntityManager em = orm.getEntityManager();
|
||||
IModelFactory modelFactory = orm.getModelFactory();
|
||||
|
||||
IVehicle vehicle1 = modelFactory.createVehicle();
|
||||
IVehicle vehicle2 = modelFactory.createVehicle();
|
||||
|
||||
vehicle1.setColor("red");
|
||||
vehicle1.setLicense("license1");
|
||||
vehicle1.setType("type_1");
|
||||
|
||||
vehicle2.setColor("blue");
|
||||
vehicle2.setLicense("license2");
|
||||
vehicle2.setType("type_2");
|
||||
|
||||
em.persist(vehicle1);
|
||||
em.persist(vehicle2);
|
||||
|
||||
|
||||
em.getTransaction().begin();
|
||||
em.flush();
|
||||
em.getTransaction().commit();
|
||||
|
||||
assertThat(vehicle1.getId(), notNullValue());
|
||||
assertThat(vehicle2.getId(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void t02_query() throws Exception {
|
||||
IDAOFactory daoFactory = orm.getDaoFactory();
|
||||
IVehicleDAO vehicleDAO = daoFactory.createVehicleDAO();
|
||||
|
||||
List<IVehicle> all = vehicleDAO.findAll();
|
||||
|
||||
assertThat(all.isEmpty(), is(false));
|
||||
assertThat(all.size(), is(2));
|
||||
|
||||
System.out.println(all);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* This package contains a couple of examples of how you can use JUnit and our simple ORM test framework to create your
|
||||
* own tests.
|
||||
*/
|
||||
|
||||
package dst.ass1.jpa.examples;
|
||||
@@ -0,0 +1,103 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ITestData;
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.dao.*;
|
||||
import dst.ass1.jpa.model.*;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ErrorCollector;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import javax.persistence.EntityTransaction;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.object.IsCompatibleType.typeCompatibleWith;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests the basic setup of the model and dao factory (makes sure they don't return null), and also tests whether all
|
||||
* relevant entities have been mapped at all and test data can be inserted.
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class Ass1_1_1_00Test {
|
||||
|
||||
|
||||
@ClassRule
|
||||
public static ORMService orm = new ORMService();
|
||||
|
||||
@Rule
|
||||
public ErrorCollector err = new ErrorCollector();
|
||||
|
||||
@Test
|
||||
public void test01_modelFactoryReturnsThings() {
|
||||
IModelFactory modelFactory = orm.getModelFactory();
|
||||
|
||||
err.checkThat(modelFactory.createDriver(), isA(IDriver.class));
|
||||
err.checkThat(modelFactory.createEmployment(), isA(IEmployment.class));
|
||||
err.checkThat(modelFactory.createEmploymentKey(), isA(IEmploymentKey.class));
|
||||
err.checkThat(modelFactory.createLocation(), isA(ILocation.class));
|
||||
err.checkThat(modelFactory.createMatch(), isA(IMatch.class));
|
||||
err.checkThat(modelFactory.createMoney(), isA(IMoney.class));
|
||||
err.checkThat(modelFactory.createOrganization(), isA(IOrganization.class));
|
||||
err.checkThat(modelFactory.createRider(), isA(IRider.class));
|
||||
err.checkThat(modelFactory.createPreferences(), isA(IPreferences.class));
|
||||
err.checkThat(modelFactory.createTrip(), isA(ITrip.class));
|
||||
err.checkThat(modelFactory.createTripInfo(), isA(ITripInfo.class));
|
||||
err.checkThat(modelFactory.createVehicle(), isA(IVehicle.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02_daoFactoryReturnsThings() {
|
||||
IDAOFactory daoFactory = orm.getDaoFactory();
|
||||
|
||||
err.checkThat(daoFactory.createDriverDAO(), isA(IDriverDAO.class));
|
||||
err.checkThat(daoFactory.createEmploymentDAO(), isA(IEmploymentDAO.class));
|
||||
err.checkThat(daoFactory.createLocationDAO(), isA(ILocationDAO.class));
|
||||
err.checkThat(daoFactory.createMatchDAO(), isA(IMatchDAO.class));
|
||||
err.checkThat(daoFactory.createOrganizationDAO(), isA(IOrganizationDAO.class));
|
||||
err.checkThat(daoFactory.createRiderDAO(), isA(IRiderDAO.class));
|
||||
err.checkThat(daoFactory.createTripDAO(), isA(ITripDAO.class));
|
||||
err.checkThat(daoFactory.createTripInfoDAO(), isA(ITripInfoDAO.class));
|
||||
err.checkThat(daoFactory.createVehicleDAO(), isA(IVehicleDAO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03_entityTypesManagedCorrectly() throws Exception {
|
||||
List<Class<?>> types = orm.getDatabaseGateway().getManagedJavaTypes();
|
||||
|
||||
assertThat("No managed types found", types.isEmpty(), is(false));
|
||||
System.out.println("Managed types: " + types);
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IDriver.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IEmployment.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IEmploymentKey.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(ILocation.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IMoney.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IOrganization.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IRider.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IPreferences.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(ITrip.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(ITripInfo.class)));
|
||||
err.checkThat(types, hasItem(typeCompatibleWith(IVehicle.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04_canInsertTestFixture() throws Exception {
|
||||
ITestData testData = new TestData();
|
||||
|
||||
EntityTransaction tx = orm.em().getTransaction();
|
||||
tx.begin();
|
||||
try {
|
||||
testData.insert(orm.getModelFactory(), orm.em());
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Exception while inserting test fixture.", e);
|
||||
} finally {
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.DatabaseGateway;
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import org.junit.*;
|
||||
import org.junit.rules.ErrorCollector;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import static dst.ass1.jpa.CaseInsensitiveStringCollectionMatcher.hasItems;
|
||||
import static dst.ass1.jpa.util.Constants.*;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
|
||||
/**
|
||||
* Tests the basic object-relational mapping by examining the created database tables and constraints.
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class Ass1_1_1_01Test {
|
||||
|
||||
@ClassRule
|
||||
public static ORMService orm = new ORMService();
|
||||
|
||||
@Rule
|
||||
public ErrorCollector err = new ErrorCollector();
|
||||
|
||||
private DatabaseGateway db;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
db = orm.getDatabaseGateway();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printTables() throws Exception {
|
||||
// not a test, just some systout output that may help you to gain insight into the created database schema
|
||||
for (String table : db.getTables()) {
|
||||
System.out.printf("%-30s %s%n", table, db.getColumns(table));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicTablesJdbc() throws Exception {
|
||||
// checks that all basic tables exist
|
||||
err.checkThat(db.getTables(), hasItems(
|
||||
T_RIDER,
|
||||
T_TRIP,
|
||||
T_LOCATION,
|
||||
T_TRIP_INFO,
|
||||
T_DRIVER,
|
||||
T_EMPLOYMENT,
|
||||
T_ORGANIZATION,
|
||||
T_VEHICLE,
|
||||
T_MATCH,
|
||||
T_PREFERENCES
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation01Jdbc() throws Exception {
|
||||
// driver -> vehicle
|
||||
err.checkThat(db.getColumns(T_DRIVER), hasItems(I_VEHICLE));
|
||||
err.checkThat(db.isNullable(T_DRIVER, I_VEHICLE), is(false));
|
||||
|
||||
err.checkThat(db.getTables(), not(hasItems(J_DRIVER_VEHICLE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation02Jdbc() throws Exception {
|
||||
// rider <-> trip
|
||||
err.checkThat(db.getColumns(T_TRIP), hasItems(I_RIDER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation03Jdbc() throws Exception {
|
||||
// driver <- employment -> organization
|
||||
|
||||
err.checkThat(db.getColumns(T_EMPLOYMENT), hasItems(
|
||||
I_DRIVER,
|
||||
I_ORGANIZATION
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation04Jdbc() throws Exception {
|
||||
// trip <-> match -> vehicle
|
||||
// |
|
||||
// v
|
||||
// driver
|
||||
|
||||
err.checkThat(db.getColumns(T_MATCH), hasItems(
|
||||
I_DRIVER,
|
||||
I_TRIP,
|
||||
I_VEHICLE
|
||||
));
|
||||
err.checkThat(db.getColumns(T_DRIVER), not(hasItems(I_MATCH)));
|
||||
err.checkThat(db.getColumns(T_TRIP), not(hasItems(I_MATCH)));
|
||||
err.checkThat(db.getColumns(T_VEHICLE), not(hasItems(I_MATCH)));
|
||||
|
||||
err.checkThat(db.getColumns(T_MATCH), hasItems(I_TRIP));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation05Jdbc() throws Exception {
|
||||
// organization <-> organization
|
||||
|
||||
err.checkThat("join table should be explicitly renamed!", db.getTables(), not(hasItems(
|
||||
T_ORGANIZATION + "_" + T_ORGANIZATION
|
||||
)));
|
||||
err.checkThat(db.getTables(), hasItems(
|
||||
J_ORGANIZATION_PARTS
|
||||
));
|
||||
err.checkThat(db.getColumns(J_ORGANIZATION_PARTS), hasItems(
|
||||
I_ORGANIZATION_PARTS,
|
||||
I_ORGANIZATION_PART_OF
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation06Jdbc() throws Exception {
|
||||
// trip -> location (stops)
|
||||
err.checkThat(db.getTables(), hasItems(J_TRIP_LOCATION));
|
||||
err.checkThat(db.getColumns(J_TRIP_LOCATION), hasItems(I_TRIP));
|
||||
err.checkThat(db.getColumns(J_TRIP_LOCATION), hasItems(I_STOPS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation07Jdbc() throws Exception {
|
||||
// trip -> location (pickup)
|
||||
|
||||
err.checkThat(db.getColumns(T_TRIP), hasItems(I_PICKUP));
|
||||
err.checkThat(db.isIndex(T_TRIP, I_PICKUP, true), is(true));
|
||||
err.checkThat(db.isNullable(T_TRIP, I_PICKUP), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation08Jdbc() throws Exception {
|
||||
// trip -> location (destination)
|
||||
err.checkThat(db.getColumns(T_TRIP), hasItems(I_DESTINATION));
|
||||
err.checkThat(db.isIndex(T_TRIP, I_DESTINATION, true), is(true));
|
||||
err.checkThat(db.isNullable(T_TRIP, I_DESTINATION), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation09Jdbc() throws Exception {
|
||||
// trip <-> tripinfo
|
||||
|
||||
err.checkThat(db.getColumns(T_TRIP_INFO), hasItems(I_TRIP));
|
||||
err.checkThat(db.isNullable(T_TRIP_INFO, I_TRIP), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation10Jdbc() throws Exception {
|
||||
// organization -> vehicle
|
||||
|
||||
err.checkThat(db.getTables(), hasItems(J_ORGANIZATION_VEHICLE));
|
||||
err.checkThat(db.getColumns(J_ORGANIZATION_VEHICLE), hasItems(
|
||||
I_ORGANIZATION,
|
||||
I_VEHICLES
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelation11Jdbc() throws Exception {
|
||||
// rider -> preferences
|
||||
|
||||
err.checkThat(db.getColumns(T_RIDER), hasItems(I_PREFERENCES));
|
||||
err.checkThat(db.isNullable(T_RIDER, I_PREFERENCES), is(false));
|
||||
|
||||
err.checkThat(db.getColumns(T_PREFERENCES), not(hasItems(I_RIDER)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testColumnType01Jdbc() {
|
||||
err.checkThat(db.isColumnInTableWithType(T_RIDER, M_RIDER_PASSWORD, "VARBINARY", "20"), is(true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests the IVehicle license unique constraint.
|
||||
*/
|
||||
public class Ass1_1_1_02Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testConstraint() {
|
||||
new UniqueConstraintTester<>(() -> orm.getModelFactory().createVehicle(), e -> e.setLicense("uniquevalue"))
|
||||
.run(orm.getEntityManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintJdbc() {
|
||||
assertTrue(orm.getDatabaseGateway().isIndex(Constants.T_VEHICLE, Constants.M_VEHICLE_LICENSE, false));
|
||||
assertTrue(orm.getDatabaseGateway().isNullable(Constants.T_VEHICLE, Constants.M_VEHICLE_LICENSE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.IPreferences;
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.hibernate.PropertyValueException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.StringContains.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests the IRider tel not null constraint.
|
||||
*/
|
||||
public class Ass1_1_1_03Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testConstraint() {
|
||||
IRider e1 = orm.getModelFactory().createRider();
|
||||
e1.setEmail("email@example.com");
|
||||
e1.setTel(null);
|
||||
IPreferences preferences = orm.getModelFactory().createPreferences();
|
||||
e1.setPreferences(preferences);
|
||||
var e = assertThrows(PersistenceException.class, () -> {
|
||||
orm.em().getTransaction().begin();
|
||||
orm.em().persist(preferences);
|
||||
orm.em().persist(e1);
|
||||
orm.em().flush();
|
||||
});
|
||||
assertThat(e.getMessage(), containsString("not-null property"));
|
||||
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintJdbc() {
|
||||
assertFalse(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_TEL));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.IDriver;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.hibernate.PropertyValueException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
/**
|
||||
* Tests the IDriver tel not null constraint.
|
||||
*/
|
||||
public class Ass1_1_1_04Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testConstraint() {
|
||||
IDriver e1 = orm.getModelFactory().createDriver();
|
||||
e1.setTel(null);
|
||||
var e = assertThrows(PersistenceException.class, () -> {
|
||||
orm.em().getTransaction().begin();
|
||||
orm.em().persist(e1);
|
||||
orm.em().flush();
|
||||
});
|
||||
assertThat(e.getMessage(), containsString("not-null property"));
|
||||
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintJdbc() {
|
||||
assertFalse(orm.getDatabaseGateway().isNullable(Constants.T_DRIVER, Constants.M_DRIVER_TEL));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.IMoney;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.metamodel.ManagedType;
|
||||
import javax.persistence.metamodel.Type;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests if IMoney is implemented correctly.
|
||||
*/
|
||||
public class Ass1_1_1_05Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void moneyEntityCannotBePersisted() {
|
||||
IMoney money = orm.getModelFactory().createMoney();
|
||||
assertNotNull(money);
|
||||
|
||||
money.setValue(BigDecimal.TEN);
|
||||
money.setCurrency("EURO");
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
orm.getEntityManager().persist(money);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moneyIsEmbeddableType() {
|
||||
IMoney money = orm.getModelFactory().createMoney();
|
||||
assertNotNull(money);
|
||||
|
||||
ManagedType<?> type = orm.getEntityManager().getMetamodel().managedType(money.getClass());
|
||||
assertNotNull(type);
|
||||
assertThat(type.getPersistenceType(), is(Type.PersistenceType.EMBEDDABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moneyHasNoTable() throws Exception {
|
||||
assertFalse(orm.getDatabaseGateway().isTable("MONEY"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.IPreferences;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests that IPreferences is persisted correctly.
|
||||
*/
|
||||
public class Ass1_1_1_06Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testPreferencesMap() {
|
||||
IPreferences pref1 = orm.getModelFactory().createPreferences();
|
||||
|
||||
pref1.putData("key1", "value1");
|
||||
pref1.putData("key2", "value2");
|
||||
|
||||
EntityManager em = orm.getEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
em.persist(pref1);
|
||||
em.flush();
|
||||
em.getTransaction().commit();
|
||||
|
||||
EntityManager em2 = orm.createEntityManager();
|
||||
IPreferences md2 = em2.find(pref1.getClass(), pref1.getId());
|
||||
|
||||
Map<String, String> map = md2.getData();
|
||||
|
||||
assertThat(map.size(), is(2));
|
||||
assertThat(map.keySet(), hasItems("key1", "key2"));
|
||||
assertThat(map.get("key1"), is("value1"));
|
||||
assertThat(map.get("key2"), is("value2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreferencesMapJdbc() {
|
||||
assertTrue(orm.getDatabaseGateway().isTable(Constants.T_PREFERENCES));
|
||||
assertTrue(orm.getDatabaseGateway().isTable(Constants.J_PREFERENCES_DATA));
|
||||
assertTrue(orm.getDatabaseGateway().isColumnInTable(Constants.J_PREFERENCES_DATA, Constants.I_PREFERENCES));
|
||||
assertTrue(orm.getDatabaseGateway().isColumnInTable(Constants.J_PREFERENCES_DATA, Constants.M_PREFERENCES_DATA + "_KEY"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.model.IPreferences;
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import dst.ass1.jpa.model.ITrip;
|
||||
import org.hibernate.PropertyValueException;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests if the IRider and IPreferences relation is implemented correctly.
|
||||
*/
|
||||
public class Ass1_1_1_07Test extends Ass1_TestBase {
|
||||
|
||||
@Test
|
||||
public void testPreferencesAssociation() {
|
||||
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider1Id);
|
||||
assertNotNull(rider1);
|
||||
assertEquals(testData.preferences1Id, rider1.getPreferences().getId());
|
||||
|
||||
IRider rider2 = daoFactory.createRiderDAO().findById(testData.rider2Id);
|
||||
assertNotNull(rider2);
|
||||
assertEquals(testData.preferences2Id, rider2.getPreferences().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreferencesNonOptionalConstraint() {
|
||||
|
||||
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider1Id);
|
||||
assertNotNull(rider1);
|
||||
rider1.setPreferences(null);
|
||||
|
||||
var e = assertThrows(PersistenceException.class, () -> {
|
||||
em.getTransaction().begin();
|
||||
em.persist(rider1);
|
||||
em.flush();
|
||||
});
|
||||
assertThat(e.getMessage(), containsString("not-null property"));
|
||||
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreferencesUniqueConstraint() throws Exception {
|
||||
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider1Id);
|
||||
IPreferences preferences1 = rider1.getPreferences();
|
||||
|
||||
IRider rider5 = modelFactory.createRider();
|
||||
rider5.setEmail("email@example.com");
|
||||
rider5.setName("rider5");
|
||||
rider5.setTel("tel");
|
||||
rider5.setPreferences(preferences1);
|
||||
|
||||
em.getTransaction().begin();
|
||||
var missingException = "Persisting the same metadata object with a different course should result in a constraint violation";
|
||||
var e = assertThrows(missingException, PersistenceException.class, () -> {
|
||||
em.persist(rider5);
|
||||
em.flush();
|
||||
});
|
||||
assertThat(missingException, e.getCause(), is(instanceOf(ConstraintViolationException.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRiderPreferencesDeleteCascade() throws Exception {
|
||||
IRider rider = daoFactory.createRiderDAO().findById(testData.rider4Id);
|
||||
Long preferencesId = rider.getPreferences().getId();
|
||||
|
||||
em.getTransaction().begin();
|
||||
try {
|
||||
for (ITrip trip : rider.getTrips()) {
|
||||
trip.setRider(null);
|
||||
}
|
||||
em.remove(rider);
|
||||
em.flush();
|
||||
} catch (PersistenceException e) {
|
||||
throw new AssertionError("Removing a rider should not result in a PersistenceException", e);
|
||||
}
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.getTransaction().begin();
|
||||
IPreferences preferences = em.find(modelFactory.createPreferences().getClass(), preferencesId);
|
||||
assertNull("Expected preferences to be null after associated rider was deleted", preferences);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import dst.ass1.jpa.model.ITrip;
|
||||
import dst.ass1.jpa.model.TripState;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests the 1-N association between ITrip and IRider (its creator).
|
||||
*/
|
||||
public class Ass1_1_1_08Test extends Ass1_TestBase {
|
||||
|
||||
@Test
|
||||
public void testTripRiderAssociation() {
|
||||
|
||||
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider4Id);
|
||||
assertNotNull(rider1);
|
||||
assertNotNull(rider1.getTrips());
|
||||
|
||||
List<Long> tripIds = map(rider1.getTrips(), ITrip::getId);
|
||||
|
||||
assertEquals(1, tripIds.size());
|
||||
assertThat(tripIds, hasItem(testData.trip6Id));
|
||||
|
||||
ITrip trip1 = daoFactory.createTripDAO().findById(testData.trip6Id);
|
||||
ITrip trip2 = daoFactory.createTripDAO().findById(testData.trip1Id);
|
||||
|
||||
assertNotNull(trip1);
|
||||
assertNotNull(trip2);
|
||||
|
||||
assertEquals(testData.rider4Id, trip1.getRider().getId());
|
||||
assertEquals(testData.rider1Id, trip2.getRider().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTripStatus() {
|
||||
ITrip trip1 = daoFactory.createTripDAO().findById(testData.trip1Id);
|
||||
assertEquals(TripState.COMPLETED, trip1.getState());
|
||||
ITrip trip2 = daoFactory.createTripDAO().findById(testData.trip6Id);
|
||||
assertEquals(TripState.CREATED, trip2.getState());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IOrganizationDAO;
|
||||
import dst.ass1.jpa.dao.IVehicleDAO;
|
||||
import dst.ass1.jpa.dao.impl.DAOFactory;
|
||||
import dst.ass1.jpa.model.IOrganization;
|
||||
import dst.ass1.jpa.model.IVehicle;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests the association between IOrganization and IVehicle.
|
||||
*/
|
||||
public class Ass1_1_1_09Test extends Ass1_TestBase {
|
||||
|
||||
@Test
|
||||
public void testOrganizationVehicleAssociation() {
|
||||
EntityManager em = orm.createEntityManager();
|
||||
DAOFactory daoFactory = new DAOFactory(em);
|
||||
|
||||
IOrganizationDAO organizationDAO = daoFactory.createOrganizationDAO();
|
||||
IVehicleDAO vehicleDAO = daoFactory.createVehicleDAO();
|
||||
|
||||
List<IVehicle> vehicles = vehicleDAO.findAll();
|
||||
|
||||
assertNotNull(vehicles);
|
||||
assertEquals(4, vehicles.size());
|
||||
|
||||
IVehicle vehicle1 = vehicleDAO.findById(testData.vehicle1Id);
|
||||
IVehicle vehicle2 = vehicleDAO.findById(testData.vehicle2Id);
|
||||
IVehicle vehicle3 = vehicleDAO.findById(testData.vehicle3Id);
|
||||
IVehicle vehicle4 = vehicleDAO.findById(testData.vehicle4Id);
|
||||
|
||||
assertEquals(testData.vehicle1Id, vehicle1.getId());
|
||||
assertEquals(testData.vehicle2Id, vehicle2.getId());
|
||||
assertEquals(testData.vehicle3Id, vehicle3.getId());
|
||||
assertEquals(testData.vehicle4Id, vehicle4.getId());
|
||||
|
||||
List<IOrganization> organizations = organizationDAO.findAll();
|
||||
|
||||
assertNotNull(organizations);
|
||||
assertEquals(5, organizations.size());
|
||||
|
||||
IOrganization organization1 = organizationDAO.findById(testData.organization1Id);
|
||||
IOrganization organization2 = organizationDAO.findById(testData.organization2Id);
|
||||
IOrganization organization3 = organizationDAO.findById(testData.organization3Id);
|
||||
IOrganization organization4 = organizationDAO.findById(testData.organization4Id);
|
||||
IOrganization organization5 = organizationDAO.findById(testData.organization5Id);
|
||||
|
||||
assertEquals(testData.organization1Id, organization1.getId());
|
||||
assertNotNull(organization1.getVehicles());
|
||||
assertThat(organization1.getVehicles().size(), is(3));
|
||||
|
||||
List<Long> vehicleIds1 = map(organization1.getVehicles(), IVehicle::getId);
|
||||
assertThat(vehicleIds1, hasItems(testData.vehicle1Id, testData.vehicle2Id, testData.vehicle3Id));
|
||||
|
||||
assertEquals(testData.organization2Id, organization2.getId());
|
||||
assertNotNull(organization2.getVehicles());
|
||||
assertThat(organization2.getVehicles().size(), is(1));
|
||||
|
||||
List<Long> vehicleIds2 = map(organization2.getVehicles(), IVehicle::getId);
|
||||
assertThat(vehicleIds2, hasItems(testData.vehicle4Id));
|
||||
|
||||
assertEquals(testData.organization3Id, organization3.getId());
|
||||
assertNotNull(organization3.getVehicles());
|
||||
assertThat(organization3.getVehicles().size(), is(0));
|
||||
|
||||
assertEquals(testData.organization4Id, organization4.getId());
|
||||
assertNotNull(organization4.getVehicles());
|
||||
assertThat(organization4.getVehicles().size(), is(0));
|
||||
|
||||
assertEquals(testData.organization5Id, organization5.getId());
|
||||
assertNotNull(organization5.getVehicles());
|
||||
assertThat(organization5.getVehicles().size(), is(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IOrganizationDAO;
|
||||
import dst.ass1.jpa.dao.impl.DAOFactory;
|
||||
import dst.ass1.jpa.model.IOrganization;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.hibernate.Session;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
||||
import static org.hamcrest.core.IsCollectionContaining.hasItems;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests the self reference of IOrganization.
|
||||
*/
|
||||
public class Ass1_1_1_10Test extends Ass1_TestBase {
|
||||
|
||||
@Test
|
||||
public void testOrganizationSelfAssociation() {
|
||||
EntityManager em = orm.createEntityManager();
|
||||
IOrganizationDAO dao = new DAOFactory(em).createOrganizationDAO();
|
||||
|
||||
IOrganization organization1 = dao.findById(testData.organization1Id);
|
||||
IOrganization organization2 = dao.findById(testData.organization2Id);
|
||||
IOrganization organization3 = dao.findById(testData.organization3Id);
|
||||
IOrganization organization4 = dao.findById(testData.organization4Id);
|
||||
IOrganization organization5 = dao.findById(testData.organization5Id);
|
||||
|
||||
assertNotNull(organization1.getParts());
|
||||
assertNotNull(organization1.getPartOf());
|
||||
assertNotNull(organization2.getParts());
|
||||
assertNotNull(organization2.getPartOf());
|
||||
assertNotNull(organization3.getParts());
|
||||
assertNotNull(organization3.getPartOf());
|
||||
assertNotNull(organization4.getParts());
|
||||
assertNotNull(organization4.getPartOf());
|
||||
assertNotNull(organization5.getParts());
|
||||
assertNotNull(organization5.getPartOf());
|
||||
|
||||
List<Long> organization1Parts = map(organization1.getParts(), IOrganization::getId);
|
||||
List<Long> organization1PartOf = map(organization1.getPartOf(), IOrganization::getId);
|
||||
List<Long> organization2Parts = map(organization2.getParts(), IOrganization::getId);
|
||||
List<Long> organization2PartOf = map(organization2.getPartOf(), IOrganization::getId);
|
||||
List<Long> organization3Parts = map(organization3.getParts(), IOrganization::getId);
|
||||
List<Long> organization3PartOf = map(organization3.getPartOf(), IOrganization::getId);
|
||||
List<Long> organization4Parts = map(organization4.getParts(), IOrganization::getId);
|
||||
List<Long> organization4PartOf = map(organization4.getPartOf(), IOrganization::getId);
|
||||
List<Long> organization5Parts = map(organization5.getParts(), IOrganization::getId);
|
||||
List<Long> organization5PartOf = map(organization5.getPartOf(), IOrganization::getId);
|
||||
|
||||
|
||||
assertThat(organization1Parts, hasItems(testData.organization4Id, testData.organization5Id));
|
||||
assertThat(organization1PartOf, hasItem(testData.organization2Id));
|
||||
assertThat(organization2Parts, hasItem(testData.organization1Id));
|
||||
assertThat(organization2PartOf, hasItems(testData.organization4Id));
|
||||
assertThat(organization3Parts.size(), is(0));
|
||||
assertThat(organization3PartOf.size(), is(0));
|
||||
assertThat(organization4Parts, hasItems(testData.organization2Id));
|
||||
assertThat(organization4PartOf, hasItems(testData.organization1Id));
|
||||
assertThat(organization5Parts.size(), is(0));
|
||||
assertThat(organization5PartOf, hasItems(testData.organization1Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrganizationSelfAssociationJdbc() {
|
||||
String sql = "SELECT " + Constants.I_ORGANIZATION_PARTS + ", " + Constants.I_ORGANIZATION_PART_OF +
|
||||
" FROM " + Constants.J_ORGANIZATION_PARTS +
|
||||
" ORDER BY " + Constants.I_ORGANIZATION_PARTS + ", " + Constants.I_ORGANIZATION_PART_OF;
|
||||
|
||||
em.unwrap(Session.class).doWork(connection -> {
|
||||
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery(sql);
|
||||
assertTrue(rs.next());
|
||||
|
||||
assertEquals((long) testData.organization1Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
|
||||
assertEquals((long) testData.organization4Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
|
||||
|
||||
assertTrue(rs.next());
|
||||
|
||||
assertEquals((long) testData.organization1Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
|
||||
assertEquals((long) testData.organization5Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
|
||||
|
||||
assertTrue(rs.next());
|
||||
|
||||
assertEquals((long) testData.organization2Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
|
||||
assertEquals((long) testData.organization1Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
|
||||
|
||||
assertTrue(rs.next());
|
||||
|
||||
assertEquals((long) testData.organization4Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
|
||||
assertEquals((long) testData.organization2Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
|
||||
|
||||
rs.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.IPreferences;
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests the constraint for IRider bank data.
|
||||
*/
|
||||
public class Ass1_1_2_01Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testRiderAccountNoBankCodeConstraint() {
|
||||
IRider r1 = orm.getModelFactory().createRider();
|
||||
IRider r2 = orm.getModelFactory().createRider();
|
||||
IPreferences p1 = orm.getModelFactory().createPreferences();
|
||||
IPreferences p2 = orm.getModelFactory().createPreferences();
|
||||
orm.em().persist(p1);
|
||||
orm.em().persist(p2);
|
||||
|
||||
r1.setEmail("p1@example.com");
|
||||
r2.setEmail("p2@example.com");
|
||||
r1.setPreferences(p1);
|
||||
r2.setPreferences(p2);
|
||||
r1.setTel("tel1");
|
||||
r2.setTel("tel2");
|
||||
|
||||
new UniqueConstraintTester<>(r1, r2, e -> {
|
||||
e.setAccountNo("uniqueVal1");
|
||||
e.setBankCode("uniqueVal2");
|
||||
}).run(orm.getEntityManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRiderAccountNoBankCodeConstraintJdbc() {
|
||||
assertTrue(orm.getDatabaseGateway().isIndex(Constants.T_RIDER, Constants.M_RIDER_ACCOUNT, false));
|
||||
assertTrue(orm.getDatabaseGateway().isIndex(Constants.T_RIDER, Constants.M_RIDER_BANK_CODE, false));
|
||||
assertTrue(orm.getDatabaseGateway().isComposedIndex(Constants.T_RIDER, Constants.M_RIDER_ACCOUNT, Constants.M_RIDER_BANK_CODE));
|
||||
|
||||
assertTrue(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_ACCOUNT));
|
||||
assertTrue(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_BANK_CODE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.IPreferences;
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.hibernate.PropertyValueException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
/**
|
||||
* Tests the constraint for IRider email.
|
||||
*/
|
||||
public class Ass1_1_2_02Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testUniqueConstraint() {
|
||||
new UniqueConstraintTester<>(() -> {
|
||||
IRider rider = orm.getModelFactory().createRider();
|
||||
rider.setTel("tel");
|
||||
IPreferences preferences = orm.getModelFactory().createPreferences();
|
||||
orm.getEntityManager().persist(preferences);
|
||||
rider.setPreferences(preferences);
|
||||
return rider;
|
||||
}, e -> e.setEmail("unique@example.com"))
|
||||
.run(orm.getEntityManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotNullConstraint() {
|
||||
IRider e1 = orm.getModelFactory().createRider();
|
||||
e1.setEmail(null);
|
||||
e1.setTel("tel");
|
||||
IPreferences preferences = orm.getModelFactory().createPreferences();
|
||||
e1.setPreferences(preferences);
|
||||
var e = assertThrows(PersistenceException.class, () -> {
|
||||
orm.em().getTransaction().begin();
|
||||
orm.em().persist(preferences);
|
||||
orm.em().persist(e1);
|
||||
orm.em().flush();
|
||||
});
|
||||
assertThat(e.getMessage(), containsString("not-null property"));
|
||||
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRiderEmailNotNullConstraintJdbc() throws SQLException {
|
||||
assertFalse(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_EMAIL));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IRiderDAO;
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.Query;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class Ass1_2_1aTest extends Ass1_TestBase {
|
||||
|
||||
private IRiderDAO dao;
|
||||
private Class<? extends IRider> entityClass;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dao = daoFactory.createRiderDAO();
|
||||
entityClass = modelFactory.createRider().getClass();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedQuery_withEmailParameter_returnsNonEmptyResultSet() throws Exception {
|
||||
Query query = em.createNamedQuery(Constants.Q_RIDER_BY_EMAIL);
|
||||
|
||||
try {
|
||||
query.setParameter("email", TestData.RIDER_1_EMAIL);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AssertionError("Could not set parameter 'email' in named query " + Constants.Q_RIDER_BY_EMAIL, e);
|
||||
}
|
||||
|
||||
assertEquals("Expected exactly one result", 1, query.getResultList().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByEmail_returnsCorrectResult() throws Exception {
|
||||
Long riderId = testData.rider1Id;
|
||||
|
||||
IRider actual = dao.findByEmail(TestData.RIDER_1_EMAIL);
|
||||
IRider expected = em.find(entityClass, riderId);
|
||||
|
||||
assertEquals(riderId, actual.getId());
|
||||
assertSame(expected, actual); // note that they should actually be the same object due EntityManager caching!
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByEmail_withNonExistingEmail_returnsNull() throws Exception {
|
||||
assertNull(dao.findByEmail("non@existing.com"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IDriverDAO;
|
||||
import dst.ass1.jpa.model.IDriver;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
public class Ass1_2_1bTest extends Ass1_TestBase {
|
||||
|
||||
@Test
|
||||
public void namedQuery_returnsCorrectResult() throws Exception {
|
||||
TypedQuery<IDriver> singleResultQuery = em.createNamedQuery(Constants.Q_ACTIVE_IN_MULITIPLE_ORGANIZATIONS_DRIVERS, IDriver.class);
|
||||
singleResultQuery.setParameter("organizations", 2L);
|
||||
|
||||
List<IDriver> resultList = singleResultQuery.getResultList();
|
||||
assertThat("Expected a single result", resultList.size(), is(1));
|
||||
|
||||
IDriver result = resultList.get(0);
|
||||
assertThat(result.getName(), is(TestData.DRIVER_1_NAME));
|
||||
|
||||
TypedQuery<IDriver> twoResultsQuery = em.createNamedQuery(Constants.Q_ACTIVE_IN_MULITIPLE_ORGANIZATIONS_DRIVERS, IDriver.class);
|
||||
twoResultsQuery.setParameter("organizations", 1L);
|
||||
|
||||
List<IDriver> twoResults = twoResultsQuery.getResultList();
|
||||
assertThat("Expected two results", twoResults.size(), is(2));
|
||||
|
||||
List<String> names = map(twoResults, IDriver::getName);
|
||||
assertThat(names, hasItems(TestData.DRIVER_1_NAME, TestData.DRIVER_2_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void daoFind_returnsCorrectResult() throws Exception {
|
||||
IDriverDAO dao = daoFactory.createDriverDAO();
|
||||
Collection<IDriver> resultList;
|
||||
|
||||
resultList = dao.findActiveInMultipleOrganizationsDrivers(3L);
|
||||
assertThat("Expected an empty result for " + 3, resultList.isEmpty(), is(true));
|
||||
|
||||
resultList = dao.findActiveInMultipleOrganizationsDrivers(4L);
|
||||
assertThat("Expected an empty result for " + 4, resultList.isEmpty(), is(true));
|
||||
|
||||
resultList = dao.findActiveInMultipleOrganizationsDrivers(2L);
|
||||
assertThat("Expected a single results for " + 2, resultList.size(), is(1));
|
||||
IDriver result = resultList.iterator().next();
|
||||
assertThat(result.getName(), is(TestData.DRIVER_1_NAME));
|
||||
|
||||
resultList = dao.findActiveInMultipleOrganizationsDrivers(1L);
|
||||
assertThat("Expected two results for " + 1, resultList.size(), is(2));
|
||||
List<String> names = map(resultList, IDriver::getName);
|
||||
assertThat(names, hasItems(TestData.DRIVER_1_NAME, TestData.DRIVER_2_NAME));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IDriverDAO;
|
||||
import dst.ass1.jpa.dao.ILocationDAO;
|
||||
import dst.ass1.jpa.model.*;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import static dst.ass1.jpa.tests.TestData.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class Ass1_2_1cTest extends Ass1_TestBase {
|
||||
|
||||
|
||||
@Test
|
||||
public void namedQuery_returnsCorrectResult() {
|
||||
TypedQuery<Double> q = em.createNamedQuery(Constants.Q_SUM_DISTANCE_MOST_RECENT_TRIP, Double.class);
|
||||
|
||||
Double result = q.getSingleResult();
|
||||
assertNotNull(result);
|
||||
assertEquals(TRIP_2_DISTANCE + TRIP_4_DISTANCE, result, 0.0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedQuery_withAdditionalAssociation_returnsCorrectResult() throws Exception {
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
|
||||
ITrip trip = modelFactory.createTrip();
|
||||
ITripInfo tripInfo = modelFactory.createTripInfo();
|
||||
IMatch match = modelFactory.createMatch();
|
||||
IDriverDAO driverDAO = daoFactory.createDriverDAO();
|
||||
IDriver driver = driverDAO.findById(testData.driver2Id);
|
||||
IRider rider = daoFactory.createRiderDAO().findById(testData.rider1Id);
|
||||
ILocationDAO locationDAO = daoFactory.createLocationDAO();
|
||||
ILocation pickup = locationDAO.findById(testData.location1Id);
|
||||
ILocation destination = locationDAO.findById(testData.location2Id);
|
||||
IVehicle vehicle = daoFactory.createVehicleDAO().findById(testData.vehicle1Id);
|
||||
IMoney fare = modelFactory.createMoney();
|
||||
fare.setCurrency(CURRENCY_1);
|
||||
fare.setValue(BigDecimal.TEN);
|
||||
IMoney total = modelFactory.createMoney();
|
||||
total.setCurrency(CURRENCY_1);
|
||||
total.setValue(BigDecimal.TEN);
|
||||
|
||||
match.setDate(new Date());
|
||||
match.setFare(fare);
|
||||
match.setDriver(driver);
|
||||
match.setVehicle(vehicle);
|
||||
match.setTrip(trip);
|
||||
|
||||
trip.setCreated(new Date());
|
||||
trip.setUpdated(new Date());
|
||||
trip.setState(TripState.COMPLETED);
|
||||
trip.setPickup(pickup);
|
||||
trip.setDestination(destination);
|
||||
trip.setRider(rider);
|
||||
trip.setMatch(match);
|
||||
trip.setTripInfo(tripInfo);
|
||||
|
||||
double distance = 22.22;
|
||||
tripInfo.setDistance(distance);
|
||||
tripInfo.setCompleted(new Date());
|
||||
tripInfo.setTotal(total);
|
||||
tripInfo.setDriverRating(3);
|
||||
tripInfo.setRiderRating(4);
|
||||
tripInfo.setTrip(trip);
|
||||
|
||||
em.persist(trip);
|
||||
em.persist(match);
|
||||
em.persist(tripInfo);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
|
||||
TypedQuery<Double> q = em.createNamedQuery(Constants.Q_SUM_DISTANCE_MOST_RECENT_TRIP, Double.class);
|
||||
|
||||
Double resultList = q.getSingleResult();
|
||||
assertNotNull(resultList);
|
||||
assertEquals(TRIP_1_DISTANCE + TRIP_5_DISTANCE + distance, resultList, 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void daoFind_returnsCorrectResult() {
|
||||
double result = daoFactory.createRiderDAO().getTotalDistanceOfMostRecentRider();
|
||||
|
||||
assertEquals(TRIP_2_DISTANCE + TRIP_4_DISTANCE, result, 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IDAOFactory;
|
||||
import dst.ass1.jpa.dao.IDriverDAO;
|
||||
import dst.ass1.jpa.dao.ILocationDAO;
|
||||
import dst.ass1.jpa.dao.impl.DAOFactory;
|
||||
import dst.ass1.jpa.model.*;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static dst.ass1.jpa.tests.TestData.*;
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class Ass1_2_2Test extends Ass1_TestBase {
|
||||
|
||||
private ILocationDAO locationDAO;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// makes sure there's no cache from creating entities
|
||||
EntityManager em = orm.createEntityManager();
|
||||
IDAOFactory daoFactory = new DAOFactory(em);
|
||||
|
||||
locationDAO = daoFactory.createLocationDAO();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReachedLocationsExists() {
|
||||
em.createNamedQuery(Constants.Q_REACHED_LOCATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReachedLocationsQuery() {
|
||||
Collection<Long> ids = locationDAO.findReachedLocationIds();
|
||||
assertThat(ids.size(), is(5));
|
||||
assertThat(ids, hasItems(LOCATION_1_ID, LOCATION_2_ID, LOCATION_3_ID, LOCATION_4_ID, LOCATION_5_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReachedLocationsQuery_withAdditionalAssociations() {
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
final Long ADD_REACHED_1 = 12L;
|
||||
final Long ADD_REACHED_2 = 13L;
|
||||
ILocation location1 = modelFactory.createLocation();
|
||||
location1.setLocationId(11L);
|
||||
location1.setName("location11");
|
||||
ILocation location2 = modelFactory.createLocation();
|
||||
location2.setLocationId(ADD_REACHED_1);
|
||||
location2.setName("location12");
|
||||
ILocation location3 = modelFactory.createLocation();
|
||||
location3.setLocationId(ADD_REACHED_2);
|
||||
location3.setName("location13");
|
||||
ILocation location4 = modelFactory.createLocation();
|
||||
location4.setLocationId(14L);
|
||||
location4.setName("location14");
|
||||
|
||||
ITrip trip = modelFactory.createTrip();
|
||||
ITripInfo tripInfo = modelFactory.createTripInfo();
|
||||
IMatch match = modelFactory.createMatch();
|
||||
IDriverDAO driverDAO = daoFactory.createDriverDAO();
|
||||
IDriver driver = driverDAO.findById(testData.driver2Id);
|
||||
IRider rider = daoFactory.createRiderDAO().findById(testData.rider1Id);
|
||||
IVehicle vehicle = daoFactory.createVehicleDAO().findById(testData.vehicle1Id);
|
||||
IMoney fare = modelFactory.createMoney();
|
||||
fare.setCurrency(CURRENCY_1);
|
||||
fare.setValue(BigDecimal.TEN);
|
||||
IMoney total = modelFactory.createMoney();
|
||||
total.setCurrency(CURRENCY_1);
|
||||
total.setValue(BigDecimal.TEN);
|
||||
|
||||
match.setDate(new Date());
|
||||
match.setFare(fare);
|
||||
match.setDriver(driver);
|
||||
match.setVehicle(vehicle);
|
||||
match.setTrip(trip);
|
||||
|
||||
trip.setCreated(new Date());
|
||||
trip.setUpdated(new Date());
|
||||
trip.setState(TripState.COMPLETED);
|
||||
trip.setPickup(location1);
|
||||
trip.setDestination(location2);
|
||||
trip.setRider(rider);
|
||||
trip.setMatch(match);
|
||||
trip.setTripInfo(tripInfo);
|
||||
List<ILocation> stops = new LinkedList<>();
|
||||
stops.add(location3);
|
||||
trip.setStops(stops);
|
||||
|
||||
tripInfo.setDistance(22.22);
|
||||
tripInfo.setCompleted(createDate(2016, 2, 23, 2, 2));
|
||||
tripInfo.setTotal(total);
|
||||
tripInfo.setDriverRating(3);
|
||||
tripInfo.setRiderRating(4);
|
||||
tripInfo.setTrip(trip);
|
||||
|
||||
em.persist(location1);
|
||||
em.persist(location2);
|
||||
em.persist(location3);
|
||||
em.persist(location4);
|
||||
em.persist(trip);
|
||||
em.persist(match);
|
||||
em.persist(tripInfo);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
|
||||
Collection<Long> ids = locationDAO.findReachedLocationIds();
|
||||
|
||||
assertThat(ids, hasItems(LOCATION_1_ID, LOCATION_2_ID, LOCATION_3_ID, LOCATION_4_ID, LOCATION_5_ID, ADD_REACHED_1, ADD_REACHED_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReachedLocationsQuery_onEmptyDatabase() {
|
||||
db.truncateTables();
|
||||
Collection<Long> ids = locationDAO.findReachedLocationIds();
|
||||
assertTrue(ids.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IRiderDAO;
|
||||
import dst.ass1.jpa.model.IMoney;
|
||||
import dst.ass1.jpa.model.IRider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dst.ass1.jpa.tests.TestData.*;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class Ass1_2_3a_01Test extends Ass1_TestBase {
|
||||
|
||||
private IRiderDAO riderDAO;
|
||||
|
||||
static Map<Long, Map<String, IMoney>> convertMapKeys(Map<IRider, Map<String, IMoney>> result) {
|
||||
return result.entrySet().stream().collect(Collectors.toMap(
|
||||
kv -> kv.getKey().getId(),
|
||||
kv -> kv.getValue()
|
||||
));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
riderDAO = daoFactory.createRiderDAO();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecentspending() {
|
||||
final IMoney spendingCurrency1Rider1 = modelFactory.createMoney();
|
||||
spendingCurrency1Rider1.setValue(TRIP_INFO_1_MONEY_VALUE);
|
||||
spendingCurrency1Rider1.setCurrency(CURRENCY_1);
|
||||
|
||||
final IMoney spendingCurrency2Rider1 = modelFactory.createMoney();
|
||||
spendingCurrency2Rider1.setValue(TRIP_INFO_5_MONEY_VALUE);
|
||||
spendingCurrency2Rider1.setCurrency(CURRENCY_2);
|
||||
|
||||
final IMoney spendingCurrency1Rider2 = modelFactory.createMoney();
|
||||
spendingCurrency1Rider2.setValue(TRIP_INFO_4_MONEY_VALUE);
|
||||
spendingCurrency1Rider2.setCurrency(CURRENCY_1);
|
||||
|
||||
final IMoney spendingCurrency2Rider2 = modelFactory.createMoney();
|
||||
spendingCurrency2Rider2.setValue(TRIP_INFO_2_MONEY_VALUE);
|
||||
spendingCurrency2Rider2.setCurrency(CURRENCY_2);
|
||||
|
||||
final IMoney spendingCurrency3Rider3 = modelFactory.createMoney();
|
||||
spendingCurrency3Rider3.setValue(TRIP_INFO_3_MONEY_VALUE);
|
||||
spendingCurrency3Rider3.setCurrency(CURRENCY_3);
|
||||
|
||||
Map<IRider, Map<String, IMoney>> spending = riderDAO.getRecentSpending();
|
||||
|
||||
assertThat(spending.size(), is(3));
|
||||
|
||||
Map<Long, Map<String, IMoney>> mapped = convertMapKeys(spending);
|
||||
|
||||
assertTrue(mapped.containsKey(testData.rider1Id));
|
||||
assertTrue(mapped.containsKey(testData.rider2Id));
|
||||
assertTrue(mapped.containsKey(testData.rider3Id));
|
||||
|
||||
assertThat(mapped.get(testData.rider1Id).size(), is(2));
|
||||
assertThat(mapped.get(testData.rider2Id).size(), is(2));
|
||||
assertThat(mapped.get(testData.rider3Id).size(), is(1));
|
||||
|
||||
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_1));
|
||||
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_2));
|
||||
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_1));
|
||||
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_2));
|
||||
assertTrue(mapped.get(testData.rider3Id).containsKey(CURRENCY_3));
|
||||
|
||||
assertEquals(spendingCurrency1Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_1)));
|
||||
assertEquals(spendingCurrency2Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_2)));
|
||||
assertEquals(spendingCurrency1Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_1)));
|
||||
assertEquals(spendingCurrency2Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_2)));
|
||||
assertEquals(spendingCurrency3Rider3.getValue(), scaleDown(mapped.get(testData.rider3Id).get(CURRENCY_3)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecentSpending_onEmptyDatabase() {
|
||||
db.truncateTables();
|
||||
Map<IRider, Map<String, IMoney>> recentSpending = riderDAO.getRecentSpending();
|
||||
assertTrue(recentSpending.isEmpty());
|
||||
}
|
||||
|
||||
private BigDecimal scaleDown(IMoney money) {
|
||||
return money.getValue().setScale(0, RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.IRiderDAO;
|
||||
import dst.ass1.jpa.dao.ITripDAO;
|
||||
import dst.ass1.jpa.model.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityTransaction;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dst.ass1.jpa.tests.TestData.*;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class Ass1_2_3a_02Test extends Ass1_TestBase {
|
||||
|
||||
private static final BigDecimal TRIP_INFO_9_VALUE = new BigDecimal(55.0);
|
||||
private ITripDAO tripDAO;
|
||||
private IRiderDAO riderDAO;
|
||||
|
||||
static Map<Long, Map<String, IMoney>> convertMapKeys(Map<IRider, Map<String, IMoney>> result) {
|
||||
return result.entrySet().stream().collect(Collectors.toMap(
|
||||
kv -> kv.getKey().getId(),
|
||||
kv -> kv.getValue()
|
||||
));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpDatabase() throws Exception {
|
||||
tripDAO = daoFactory.createTripDAO();
|
||||
riderDAO = daoFactory.createRiderDAO();
|
||||
|
||||
IMoney total = modelFactory.createMoney();
|
||||
total.setValue(TRIP_INFO_9_VALUE);
|
||||
total.setCurrency(CURRENCY_2);
|
||||
|
||||
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
ITrip trip = tripDAO.findById(testData.trip9Id);
|
||||
trip.setState(TripState.COMPLETED);
|
||||
ITripInfo tripInfo = modelFactory.createTripInfo();
|
||||
tripInfo.setTrip(trip);
|
||||
tripInfo.setRiderRating(3);
|
||||
tripInfo.setDriverRating(3);
|
||||
tripInfo.setTotal(total);
|
||||
tripInfo.setCompleted(new Date());
|
||||
tripInfo.setDistance(2.2);
|
||||
trip.setTripInfo(tripInfo);
|
||||
em.persist(tripInfo);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecentspending() {
|
||||
final IMoney spendingCurrency1Rider1 = modelFactory.createMoney();
|
||||
spendingCurrency1Rider1.setValue(TRIP_INFO_1_MONEY_VALUE);
|
||||
spendingCurrency1Rider1.setCurrency(CURRENCY_1);
|
||||
|
||||
final IMoney spendingCurrency2Rider1 = modelFactory.createMoney();
|
||||
spendingCurrency2Rider1.setValue(TRIP_INFO_5_MONEY_VALUE.add(TRIP_INFO_9_VALUE));
|
||||
spendingCurrency2Rider1.setCurrency(CURRENCY_2);
|
||||
|
||||
final IMoney spendingCurrency1Rider2 = modelFactory.createMoney();
|
||||
spendingCurrency1Rider2.setValue(TRIP_INFO_4_MONEY_VALUE);
|
||||
spendingCurrency1Rider2.setCurrency(CURRENCY_1);
|
||||
|
||||
final IMoney spendingCurrency2Rider2 = modelFactory.createMoney();
|
||||
spendingCurrency2Rider2.setValue(TRIP_INFO_2_MONEY_VALUE);
|
||||
spendingCurrency2Rider2.setCurrency(CURRENCY_2);
|
||||
|
||||
final IMoney spendingCurrency3Rider3 = modelFactory.createMoney();
|
||||
spendingCurrency3Rider3.setValue(TRIP_INFO_3_MONEY_VALUE);
|
||||
spendingCurrency3Rider3.setCurrency(CURRENCY_3);
|
||||
|
||||
Map<IRider, Map<String, IMoney>> spending = riderDAO.getRecentSpending();
|
||||
|
||||
assertThat(spending.size(), is(3));
|
||||
|
||||
Map<Long, Map<String, IMoney>> mapped = convertMapKeys(spending);
|
||||
|
||||
assertTrue(mapped.containsKey(testData.rider1Id));
|
||||
assertTrue(mapped.containsKey(testData.rider2Id));
|
||||
assertTrue(mapped.containsKey(testData.rider3Id));
|
||||
|
||||
assertThat(mapped.get(testData.rider1Id).size(), is(2));
|
||||
assertThat(mapped.get(testData.rider2Id).size(), is(2));
|
||||
assertThat(mapped.get(testData.rider3Id).size(), is(1));
|
||||
|
||||
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_1));
|
||||
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_2));
|
||||
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_2));
|
||||
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_2));
|
||||
assertTrue(mapped.get(testData.rider3Id).containsKey(CURRENCY_3));
|
||||
|
||||
assertEquals(spendingCurrency1Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_1)));
|
||||
assertEquals(spendingCurrency2Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_2)));
|
||||
assertEquals(spendingCurrency1Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_1)));
|
||||
assertEquals(spendingCurrency2Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_2)));
|
||||
assertEquals(spendingCurrency3Rider3.getValue(), scaleDown(mapped.get(testData.rider3Id).get(CURRENCY_3)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecentSpending_onEmptyDatabase() {
|
||||
db.truncateTables();
|
||||
Map<IRider, Map<String, IMoney>> recentSpending = riderDAO.getRecentSpending();
|
||||
assertTrue(recentSpending.isEmpty());
|
||||
}
|
||||
|
||||
private BigDecimal scaleDown(IMoney money) {
|
||||
return money.getValue().setScale(0, RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.ITripDAO;
|
||||
import dst.ass1.jpa.model.ITrip;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.core.IsCollectionContaining.hasItems;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class Ass1_2_3b_01Test extends Ass1_TestBase {
|
||||
|
||||
private ITripDAO dao;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dao = daoFactory.createTripDAO();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledTripsBetweenStartAndFinish() {
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(null, null);
|
||||
Collection<Long> ids = map(trips, ITrip::getId);
|
||||
|
||||
assertThat(ids.size(), is(7));
|
||||
assertThat(ids, hasItems(testData.trip8Id, testData.trip11Id, testData.trip12Id, testData.trip13Id, testData.trip14Id, testData.trip15Id, testData.trip16Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledTripsCreatedBetweenStartAndFinish2() {
|
||||
Date start = createDate(2019, 1, 1, 1, 1);
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(start, null);
|
||||
Collection<Long> ids = map(trips, ITrip::getId);
|
||||
|
||||
assertThat(ids.size(), is(4));
|
||||
assertThat(ids, hasItems(testData.trip8Id, testData.trip13Id, testData.trip14Id, testData.trip15Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledTripsForStatusCreatedBetweenStartAndFinish3() {
|
||||
Date start = dao.findById(testData.trip15Id).getCreated();
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(start, null);
|
||||
Collection<Long> ids = map(trips, ITrip::getId);
|
||||
|
||||
assertThat(ids.size(), is(1));
|
||||
assertThat(ids, hasItems(testData.trip8Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledTripsForStatusCreatedBetweenStartAndFinish4() {
|
||||
Date end = dao.findById(testData.trip11Id).getCreated();
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(null, end);
|
||||
|
||||
assertThat(trips.size(), is(1));
|
||||
assertThat(map(trips, ITrip::getId), hasItems(testData.trip12Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish5() {
|
||||
Date start = dao.findById(testData.trip12Id).getCreated();
|
||||
Date end = dao.findById(testData.trip15Id).getCreated();
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(start, end);
|
||||
|
||||
assertThat(trips.size(), is(4));
|
||||
assertThat(map(trips, ITrip::getId), hasItems(testData.trip11Id, testData.trip13Id, testData.trip14Id, testData.trip16Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish6() {
|
||||
Date start = dao.findById(testData.trip8Id).getCreated();
|
||||
Collection<ITrip> cancelledTrips = dao.findCancelledTrips(start, null);
|
||||
|
||||
assertTrue(cancelledTrips.isEmpty());
|
||||
}
|
||||
|
||||
private Date createDate(int year, int month, int day, int hours, int minutes) {
|
||||
return new GregorianCalendar(year, month, day, hours, minutes).getTime();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.dao.ITripDAO;
|
||||
import dst.ass1.jpa.model.ITrip;
|
||||
import dst.ass1.jpa.model.TripState;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityTransaction;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.core.IsCollectionContaining.hasItems;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class Ass1_2_3b_02Test extends Ass1_TestBase {
|
||||
|
||||
private ITripDAO dao;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dao = daoFactory.createTripDAO();
|
||||
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
ITrip trip = dao.findById(testData.trip6Id);
|
||||
trip.setState(TripState.CANCELLED);
|
||||
em.persist(trip);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish() {
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(null, null);
|
||||
Collection<Long> ids = map(trips, ITrip::getId);
|
||||
|
||||
assertThat(ids.size(), is(8));
|
||||
assertThat(ids, hasItems(testData.trip6Id, testData.trip8Id, testData.trip11Id, testData.trip12Id, testData.trip13Id, testData.trip14Id, testData.trip15Id, testData.trip16Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish2() {
|
||||
Date start = createDate(2019, 1, 1, 1, 1);
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(start, null);
|
||||
Collection<Long> ids = map(trips, ITrip::getId);
|
||||
|
||||
assertThat(ids.size(), is(5));
|
||||
assertThat(ids, hasItems(testData.trip6Id, testData.trip8Id, testData.trip13Id, testData.trip14Id, testData.trip15Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish3() {
|
||||
Date start = dao.findById(testData.trip12Id).getCreated();
|
||||
Date end = dao.findById(testData.trip15Id).getCreated();
|
||||
Collection<ITrip> trips = dao.findCancelledTrips(start, end);
|
||||
|
||||
assertThat(trips.size(), is(5));
|
||||
assertThat(map(trips, ITrip::getId), hasItems(testData.trip6Id, testData.trip11Id, testData.trip13Id, testData.trip14Id, testData.trip16Id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish4() {
|
||||
Date start = dao.findById(testData.trip8Id).getCreated();
|
||||
Collection<ITrip> cancelledTrips = dao.findCancelledTrips(start, null);
|
||||
|
||||
assertTrue(cancelledTrips.isEmpty());
|
||||
}
|
||||
|
||||
private Date createDate(int year, int month, int day, int hours, int minutes) {
|
||||
return new GregorianCalendar(year, month, day, hours, minutes).getTime();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.model.ILocation;
|
||||
import dst.ass1.jpa.model.ITrip;
|
||||
import dst.ass1.jpa.model.TripState;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
public class Ass1_3_1Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void entityListener_prePersistSetsPropertiesCorrectly() throws InterruptedException {
|
||||
Date then = new Date();
|
||||
Thread.sleep(50);
|
||||
|
||||
EntityManager em = orm.getEntityManager();
|
||||
|
||||
ILocation pickup = orm.getModelFactory().createLocation();
|
||||
pickup.setName("name1");
|
||||
pickup.setLocationId(1L);
|
||||
|
||||
ILocation destination = orm.getModelFactory().createLocation();
|
||||
destination.setName("name2");
|
||||
destination.setLocationId(2L);
|
||||
|
||||
|
||||
ITrip trip = orm.getModelFactory().createTrip();
|
||||
trip.setState(TripState.CREATED);
|
||||
trip.setPickup(pickup);
|
||||
trip.setDestination(destination);
|
||||
|
||||
|
||||
EntityTransaction tx;
|
||||
// persist
|
||||
tx = em.getTransaction();
|
||||
tx.begin();
|
||||
em.persist(pickup);
|
||||
em.persist(destination);
|
||||
em.persist(trip);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
|
||||
assertNotNull(trip.getCreated());
|
||||
assertNotNull(trip.getUpdated());
|
||||
|
||||
assertThat(trip.getCreated(), greaterThan(then));
|
||||
assertThat(trip.getUpdated(), greaterThan(then));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void entityListener_preUpdateSetsPropertiesCorrectly() throws InterruptedException {
|
||||
EntityManager em = orm.getEntityManager();
|
||||
|
||||
ILocation pickup = orm.getModelFactory().createLocation();
|
||||
pickup.setName("name1");
|
||||
pickup.setLocationId(1L);
|
||||
|
||||
ILocation destination = orm.getModelFactory().createLocation();
|
||||
destination.setName("name2");
|
||||
destination.setLocationId(2L);
|
||||
|
||||
|
||||
ITrip trip = orm.getModelFactory().createTrip();
|
||||
trip.setCreated(new Date());
|
||||
trip.setUpdated(new Date());
|
||||
trip.setState(TripState.CREATED);
|
||||
trip.setPickup(pickup);
|
||||
trip.setDestination(destination);
|
||||
|
||||
EntityTransaction tx;
|
||||
// persist
|
||||
tx = em.getTransaction();
|
||||
tx.begin();
|
||||
em.persist(pickup);
|
||||
em.persist(destination);
|
||||
em.persist(trip);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
|
||||
Date then = new Date();
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
// update
|
||||
tx = em.getTransaction();
|
||||
tx.begin();
|
||||
trip.setState(TripState.QUEUED);
|
||||
em.persist(trip);
|
||||
em.flush();
|
||||
tx.commit();
|
||||
|
||||
assertNotNull(trip.getUpdated());
|
||||
assertThat(trip.getUpdated(), greaterThan(then));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.dao.IDAOFactory;
|
||||
import dst.ass1.jpa.listener.DefaultListener;
|
||||
import dst.ass1.jpa.model.IModelFactory;
|
||||
import dst.ass1.jpa.model.IVehicle;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class Ass1_3_2Test {
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService();
|
||||
|
||||
@Test
|
||||
public void testDefaultListener() {
|
||||
DefaultListener.clear();
|
||||
|
||||
IDAOFactory daoFactory = orm.getDaoFactory();
|
||||
IModelFactory modelFactory = orm.getModelFactory();
|
||||
EntityManager em = orm.getEntityManager();
|
||||
|
||||
em.getTransaction().begin();
|
||||
|
||||
// do some inserts
|
||||
IVehicle vehicle = modelFactory.createVehicle();
|
||||
vehicle.setLicense(TestData.VEHICLE_1_LICENSE);
|
||||
vehicle.setType(TestData.TYPE_1);
|
||||
vehicle.setColor(TestData.COLOR_1);
|
||||
em.persist(vehicle);
|
||||
em.flush();
|
||||
em.remove(vehicle);
|
||||
em.flush();
|
||||
|
||||
vehicle = modelFactory.createVehicle();
|
||||
vehicle.setLicense(TestData.VEHICLE_2_LICENSE);
|
||||
vehicle.setType(TestData.TYPE_2);
|
||||
vehicle.setColor(TestData.COLOR_2);
|
||||
em.persist(vehicle);
|
||||
|
||||
assertEquals(1, DefaultListener.getRemoveOperations());
|
||||
assertTrue(DefaultListener.getPersistOperations() > 0);
|
||||
assertEquals((double) DefaultListener.getOverallTimeToPersist() / DefaultListener.getPersistOperations(), DefaultListener.getAverageTimeToPersist(), 0.6);
|
||||
|
||||
List<IVehicle> vehicles = daoFactory.createVehicleDAO().findAll();
|
||||
assertNotNull(vehicles);
|
||||
assertFalse(vehicles.isEmpty());
|
||||
|
||||
int loadOperations = DefaultListener.getLoadOperations();
|
||||
em.refresh(vehicles.get(0));
|
||||
assertEquals(loadOperations + 1, DefaultListener.getLoadOperations());
|
||||
|
||||
vehicles = daoFactory.createVehicleDAO().findAll();
|
||||
assertNotNull(vehicles);
|
||||
assertFalse(vehicles.isEmpty());
|
||||
|
||||
vehicles.get(0).setLicense("updated");
|
||||
em.persist(vehicles.get(0));
|
||||
em.flush();
|
||||
|
||||
assertEquals(1, DefaultListener.getUpdateOperations());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.interceptor.SQLInterceptor;
|
||||
import dst.ass1.jpa.util.Constants;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.Query;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class Ass1_3_3Test extends Ass1_TestBase {
|
||||
|
||||
@Test
|
||||
public void sqlInterceptor_countsSelectsCorrectly() {
|
||||
em.getTransaction().begin();
|
||||
SQLInterceptor.resetCounter();
|
||||
assertEquals(0, SQLInterceptor.getSelectCount());
|
||||
|
||||
Query c = em.createQuery("select v from " + Constants.T_VEHICLE + " v");
|
||||
c.getResultList();
|
||||
|
||||
assertEquals(0, SQLInterceptor.getSelectCount());
|
||||
|
||||
c = em.createQuery("select distinct l from " + Constants.T_LOCATION + " l");
|
||||
c.getResultList();
|
||||
|
||||
assertEquals(1, SQLInterceptor.getSelectCount());
|
||||
|
||||
c = em.createQuery("select t from " + Constants.T_TRIP + " t");
|
||||
c.getResultList();
|
||||
assertEquals(2, SQLInterceptor.getSelectCount());
|
||||
|
||||
c = em.createQuery("select distinct t from " + Constants.T_TRIP + " t");
|
||||
c.getResultList();
|
||||
assertEquals(3, SQLInterceptor.getSelectCount());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses( {
|
||||
Ass1_1_1_00Test.class, Ass1_1_1_01Test.class, Ass1_1_1_02Test.class, Ass1_1_1_03Test.class, Ass1_1_1_04Test.class, Ass1_1_1_05Test.class, Ass1_1_1_06Test.class, Ass1_1_1_07Test.class, Ass1_1_1_08Test.class, Ass1_1_1_09Test.class, Ass1_1_1_10Test.class, Ass1_1_2_01Test.class, Ass1_1_2_02Test.class, Ass1_2_1aTest.class, Ass1_2_1bTest.class, Ass1_2_1cTest.class, Ass1_2_2Test.class, Ass1_2_3a_01Test.class, Ass1_2_3a_02Test.class, Ass1_2_3b_01Test.class, Ass1_2_3b_02Test.class, Ass1_3_1Test.class, Ass1_3_2Test.class, Ass1_3_3Test.class
|
||||
})
|
||||
public class Ass1_Suite {
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import dst.ass1.jpa.DatabaseGateway;
|
||||
import dst.ass1.jpa.ORMService;
|
||||
import dst.ass1.jpa.dao.IDAOFactory;
|
||||
import dst.ass1.jpa.model.IModelFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.ErrorCollector;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Ass1_TestBase {
|
||||
|
||||
protected final TestData testData = new TestData();
|
||||
|
||||
@Rule
|
||||
public ORMService orm = new ORMService(testData);
|
||||
|
||||
@Rule
|
||||
public ErrorCollector err = new ErrorCollector();
|
||||
|
||||
// commonly used classes unwrapped from ORMService
|
||||
protected EntityManager em;
|
||||
protected IModelFactory modelFactory;
|
||||
protected IDAOFactory daoFactory;
|
||||
protected DatabaseGateway db;
|
||||
|
||||
public static <T, R> List<R> map(Collection<T> collection, Function<T, R> fn) {
|
||||
return collection.stream().map(fn).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpBase() throws Exception {
|
||||
em = orm.getEntityManager();
|
||||
modelFactory = orm.getModelFactory();
|
||||
daoFactory = orm.getDaoFactory();
|
||||
db = orm.getDatabaseGateway();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
package dst.ass1.jpa.tests;
|
||||
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests a unique constraint by creating two instances of an entity, calling the same value setter on each entity,
|
||||
* and finally trying to persist them.
|
||||
*
|
||||
* @param <E> the entity type
|
||||
*/
|
||||
public class UniqueConstraintTester<E> {
|
||||
|
||||
private Consumer<E> valueSetter;
|
||||
private E e1;
|
||||
private E e2;
|
||||
|
||||
public UniqueConstraintTester(E e1, E e2, Consumer<E> valueSetter) {
|
||||
this.e1 = e1;
|
||||
this.e2 = e2;
|
||||
this.valueSetter = valueSetter;
|
||||
}
|
||||
|
||||
public UniqueConstraintTester(Supplier<E> entityFactory, Consumer<E> valueSetter) {
|
||||
this(entityFactory.get(), entityFactory.get(), valueSetter);
|
||||
}
|
||||
|
||||
public void run(EntityManager em) {
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
if (!tx.isActive()) {
|
||||
tx.begin();
|
||||
}
|
||||
|
||||
valueSetter.accept(e1);
|
||||
em.persist(e1);
|
||||
em.flush();
|
||||
|
||||
try {
|
||||
valueSetter.accept(e2);
|
||||
em.persist(e2);
|
||||
em.flush();
|
||||
fail("Missing unique constraint in " + e2.getClass());
|
||||
} catch (PersistenceException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (!(cause instanceof ConstraintViolationException)) {
|
||||
fail("Missing unique constraint in " + e2.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user