#53 Implemented SQLite product data persistence + tests
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
config.properties
|
config.properties
|
||||||
products-config.json
|
products-config.json
|
||||||
|
persistence.db
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
## Visual Studio Code #############################################################################
|
## Visual Studio Code #############################################################################
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@@ -76,6 +76,12 @@
|
|||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
<version>1.4.7</version>
|
<version>1.4.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xerial</groupId>
|
||||||
|
<artifactId>sqlite-jdbc</artifactId>
|
||||||
|
<version>3.42.0.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
package de.rwu.easydrop;
|
package de.rwu.easydrop;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.client.DataSourceFactory;
|
import de.rwu.easydrop.api.client.DataSourceFactory;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
|
import de.rwu.easydrop.data.connector.SQLiteConnector;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
import de.rwu.easydrop.service.retriever.CatalogueRetriever;
|
import de.rwu.easydrop.service.retriever.CatalogueRetriever;
|
||||||
import de.rwu.easydrop.service.retriever.ProductRetriever;
|
import de.rwu.easydrop.service.retriever.ProductRetriever;
|
||||||
|
import de.rwu.easydrop.service.writer.CatalogueWriter;
|
||||||
import de.rwu.easydrop.util.Config;
|
import de.rwu.easydrop.util.Config;
|
||||||
import de.rwu.easydrop.util.ProductsConfig;
|
import de.rwu.easydrop.util.ProductsConfig;
|
||||||
|
|
||||||
@@ -41,9 +47,14 @@ public final class Main {
|
|||||||
DataSourceFactory dataSourceFactory = new DataSourceFactory(config);
|
DataSourceFactory dataSourceFactory = new DataSourceFactory(config);
|
||||||
ProductRetriever retriever = new ProductRetriever(dataSourceFactory);
|
ProductRetriever retriever = new ProductRetriever(dataSourceFactory);
|
||||||
CatalogueRetriever catRetriever = new CatalogueRetriever(pConfig, retriever);
|
CatalogueRetriever catRetriever = new CatalogueRetriever(pConfig, retriever);
|
||||||
|
AbstractProductPersistence db = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
CatalogueWriter catWriter = new CatalogueWriter(db);
|
||||||
|
|
||||||
catRetriever.loadCatalogues();
|
catRetriever.loadCatalogues();
|
||||||
for (ProductCatalogue pCat : catRetriever.getProductCatalogues()) {
|
List<ProductCatalogue> pCats = catRetriever.getProductCatalogues();
|
||||||
|
catWriter.writeCatalogues(pCats);
|
||||||
|
|
||||||
|
for (ProductCatalogue pCat : pCats) {
|
||||||
String pCatStr = pCat.toString();
|
String pCatStr = pCat.toString();
|
||||||
LOGGER.info(pCatStr);
|
LOGGER.info(pCatStr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package de.rwu.easydrop.api.client;
|
|||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
|
import de.rwu.easydrop.exception.PersistenceException;
|
||||||
import de.rwu.easydrop.util.Config;
|
import de.rwu.easydrop.util.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,6 +17,17 @@ public class DataSourceFactory {
|
|||||||
* The data source config.
|
* The data source config.
|
||||||
*/
|
*/
|
||||||
private Config config;
|
private Config config;
|
||||||
|
/**
|
||||||
|
* Persistence interface.
|
||||||
|
*/
|
||||||
|
private AbstractProductPersistence persistence = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newPersistence the persistence to set
|
||||||
|
*/
|
||||||
|
public void setPersistence(final AbstractProductPersistence newPersistence) {
|
||||||
|
this.persistence = newPersistence;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newConfig the config to set
|
* @param newConfig the config to set
|
||||||
@@ -52,4 +65,17 @@ public class DataSourceFactory {
|
|||||||
String apiKey = config.getProperty("EBAY_API_KEY");
|
String apiKey = config.getProperty("EBAY_API_KEY");
|
||||||
return new EbayItemDataSource(apiUrl, apiKey);
|
return new EbayItemDataSource(apiUrl, apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a persistence data source.
|
||||||
|
*
|
||||||
|
* @return ProductPersistenceInterface
|
||||||
|
*/
|
||||||
|
public AbstractProductPersistence createProductPersistenceDataSource() {
|
||||||
|
if (persistence == null) {
|
||||||
|
throw new PersistenceException("Persistence is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return persistence;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.client.AbstractDataSource;
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows connecting to a persistent product data store.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
public abstract class AbstractProductPersistence extends AbstractDataSource {
|
||||||
|
/**
|
||||||
|
* Data origin.
|
||||||
|
*/
|
||||||
|
public static final String DATA_ORIGIN = "Persistence";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a ProductDTO to persistence.
|
||||||
|
*
|
||||||
|
* @param dto
|
||||||
|
*/
|
||||||
|
public abstract void saveProduct(ProductDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a ProductDTO from persistence.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract ProductDTO getProductDTOById(String productId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all data from persistence.
|
||||||
|
*/
|
||||||
|
public abstract void clearData();
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package de.rwu.easydrop.data.connector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows connecting to a SQLite Database.
|
|
||||||
*
|
|
||||||
* TODO implement
|
|
||||||
*/
|
|
||||||
public class DatabaseConnector {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.exception.PersistenceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows connecting to a SQLite Database.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
public final class SQLiteConnector extends AbstractProductPersistence {
|
||||||
|
/**
|
||||||
|
* Data origin.
|
||||||
|
*/
|
||||||
|
private static final String DATA_ORIGIN = "SQLite";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQLite Database.
|
||||||
|
*/
|
||||||
|
private SQLiteDataSource db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param src the db to set
|
||||||
|
*/
|
||||||
|
public void setDb(final SQLiteDataSource src) {
|
||||||
|
this.db = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to SQLite db file.
|
||||||
|
*/
|
||||||
|
private static final String PERSISTENCE_PATH = "jdbc:sqlite:persistence.db";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates instance.
|
||||||
|
*
|
||||||
|
* @param src SQLite Data Source
|
||||||
|
*/
|
||||||
|
public SQLiteConnector(final SQLiteDataSource src) {
|
||||||
|
db = src;
|
||||||
|
db.setUrl(PERSISTENCE_PATH);
|
||||||
|
initializeDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeDatabase() {
|
||||||
|
try {
|
||||||
|
// Create a new database connection
|
||||||
|
Connection connection = db.getConnection();
|
||||||
|
|
||||||
|
// Execute SQL statements to create tables
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS products ("
|
||||||
|
+ "dataOrigin TEXT, "
|
||||||
|
+ "productId TEXT, "
|
||||||
|
+ "currentPrice REAL, "
|
||||||
|
+ "merchant TEXT, "
|
||||||
|
+ "deliveryPrice REAL, "
|
||||||
|
+ "available INT, "
|
||||||
|
+ "lastupdate TEXT, "
|
||||||
|
+ "UNIQUE(productId, dataOrigin) ON CONFLICT REPLACE"
|
||||||
|
+ ")");
|
||||||
|
|
||||||
|
// Close the statement and connection
|
||||||
|
statement.close();
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while initializing SQLite DB", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a ProductDTO to persistence.
|
||||||
|
*
|
||||||
|
* @param dto
|
||||||
|
*/
|
||||||
|
public void saveProduct(final ProductDTO dto) {
|
||||||
|
String query = "INSERT INTO products ("
|
||||||
|
+ "dataOrigin, productId, currentPrice, merchant, "
|
||||||
|
+ "deliveryPrice, available, lastupdate"
|
||||||
|
+ ") VALUES ("
|
||||||
|
+ "?, ?, ?, ?, ?, ?, datetime('now', 'localtime')"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
statement.setString(++index, dto.getDataOrigin());
|
||||||
|
statement.setString(++index, dto.getProductId());
|
||||||
|
statement.setDouble(++index, dto.getCurrentPrice());
|
||||||
|
statement.setString(++index, dto.getMerchant());
|
||||||
|
statement.setDouble(++index, dto.getDeliveryPrice());
|
||||||
|
statement.setBoolean(++index, dto.isAvailable());
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while saving to SQLite", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProductDTO getProductDTOById(final String productId) {
|
||||||
|
String query = "SELECT * FROM products WHERE productId = ?";
|
||||||
|
ProductDTO dto = null;
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
|
||||||
|
statement.setString(1, productId);
|
||||||
|
|
||||||
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
|
if (resultSet.next()) {
|
||||||
|
dto = new ProductDTO(resultSet.getString("productId"),
|
||||||
|
resultSet.getString("dataOrigin"));
|
||||||
|
dto.setCurrentPrice(resultSet.getDouble("currentPrice"));
|
||||||
|
dto.setMerchant(resultSet.getString("merchant"));
|
||||||
|
dto.setDeliveryPrice(resultSet.getDouble("deliveryPrice"));
|
||||||
|
dto.setAvailable(resultSet.getBoolean("available"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while reading from SQLite", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all data from persistence.
|
||||||
|
*/
|
||||||
|
public void clearData() {
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
String query = "DELETE FROM products";
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while clearing the database", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDataOrigin() {
|
||||||
|
return DATA_ORIGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getApiKey() {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
this.getClass().getName() + " doesn't support getApiKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ProductDTO buildProductDTO(final ProductDTO product, final String json) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
this.getClass().getName() + " doesn't support buildProductDTO");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected URL createApiUrl(final String productIdentifier) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
this.getClass().getName() + " doesn't support createApiUrl");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Connectors for databases.
|
* Connectors for databases.
|
||||||
*
|
*
|
||||||
* TODO implement
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
package de.rwu.easydrop.data.connector;
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package de.rwu.easydrop.data.dao;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Product data access object.
|
|
||||||
*
|
|
||||||
* TODO implement
|
|
||||||
*/
|
|
||||||
public class ProductDAO {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* Data access objects for business objects created from persistence.
|
|
||||||
*
|
|
||||||
* TODO implement
|
|
||||||
*/
|
|
||||||
package de.rwu.easydrop.data.dao;
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Structure for business objects and persisting their info.
|
* Structure for business objects and persisting their info.
|
||||||
*
|
*
|
||||||
* TODO implement
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
package de.rwu.easydrop.data;
|
package de.rwu.easydrop.data;
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package de.rwu.easydrop.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception that signifies a problem with data persistence.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
public class PersistenceException extends RuntimeException {
|
||||||
|
/**
|
||||||
|
* Throws an exception that signifies the data of a Product are invalid.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public PersistenceException(final String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception that signifies the data of a Product are invalid.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* @param cause
|
||||||
|
*/
|
||||||
|
public PersistenceException(final String message, final Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
package de.rwu.easydrop.service.mapping;
|
package de.rwu.easydrop.service.mapping;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps between Product, ProductDAO and ProductDTO.
|
* Maps between Product, ProductDTO and ProductDTO.
|
||||||
*
|
*
|
||||||
* @since 0.2.0
|
* @since 0.2.0
|
||||||
*
|
*
|
||||||
* @see Product
|
* @see Product
|
||||||
* @see ProductDTO
|
* @see ProductDTO
|
||||||
* @see ProductDAO
|
* @see ProductDTO
|
||||||
*/
|
*/
|
||||||
public final class ProductMapper {
|
public final class ProductMapper {
|
||||||
|
|
||||||
@@ -41,4 +42,21 @@ public final class ProductMapper {
|
|||||||
|
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ProductDTO object from a corresponding Product.
|
||||||
|
*
|
||||||
|
* @param product Product
|
||||||
|
* @return ProductDTO
|
||||||
|
*/
|
||||||
|
public static ProductDTO mapProductToDTO(final Product product) {
|
||||||
|
ProductDTO dto = new ProductDTO(product.getProductId(), product.getDataOrigin());
|
||||||
|
|
||||||
|
dto.setAvailable(product.isAvailable());
|
||||||
|
dto.setCurrentPrice(product.getCurrentPrice());
|
||||||
|
dto.setDeliveryPrice(product.getDeliveryPrice());
|
||||||
|
dto.setMerchant(product.getMerchant());
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.exception.InvalidProductException;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
import de.rwu.easydrop.util.ProductsConfig;
|
import de.rwu.easydrop.util.ProductsConfig;
|
||||||
@@ -60,10 +61,12 @@ public class CatalogueRetriever {
|
|||||||
newProduct.setDataOrigin(product.getDataOrigin());
|
newProduct.setDataOrigin(product.getDataOrigin());
|
||||||
newProduct.setProductId(product.getProductId());
|
newProduct.setProductId(product.getProductId());
|
||||||
|
|
||||||
if (product.getDataOrigin().equals("Amazon")) {
|
if (newProduct.getDataOrigin().equals("Amazon")) {
|
||||||
newProduct = productRetriever.getProductFromAmazon(product.getProductId());
|
newProduct = productRetriever.getProductFromAmazon(product.getProductId());
|
||||||
} else if (product.getDataOrigin().equals("eBay")) {
|
} else if (newProduct.getDataOrigin().equals("eBay")) {
|
||||||
newProduct = productRetriever.getProductFromEbay(product.getProductId());
|
newProduct = productRetriever.getProductFromEbay(product.getProductId());
|
||||||
|
} else {
|
||||||
|
throw new InvalidProductException("Product data origin is invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
newProductCatalogue.addProduct(newProduct);
|
newProductCatalogue.addProduct(newProduct);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import de.rwu.easydrop.api.client.AmazonProductDataSource;
|
|||||||
import de.rwu.easydrop.api.client.DataSourceFactory;
|
import de.rwu.easydrop.api.client.DataSourceFactory;
|
||||||
import de.rwu.easydrop.api.client.EbayItemDataSource;
|
import de.rwu.easydrop.api.client.EbayItemDataSource;
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.service.mapping.ProductMapper;
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
import de.rwu.easydrop.service.validation.ProductValidator;
|
import de.rwu.easydrop.service.validation.ProductValidator;
|
||||||
@@ -64,4 +65,20 @@ public class ProductRetriever {
|
|||||||
|
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a product from persistence.
|
||||||
|
*
|
||||||
|
* @param productId
|
||||||
|
* @return Product from persistence
|
||||||
|
*/
|
||||||
|
public Product getProductFromPersistence(final String productId) {
|
||||||
|
AbstractProductPersistence src = dataSourceFactory.createProductPersistenceDataSource();
|
||||||
|
|
||||||
|
ProductDTO dto = src.getProductDTOById(productId);
|
||||||
|
Product product = ProductMapper.mapProductFromDTO(dto);
|
||||||
|
ProductValidator.validate(product);
|
||||||
|
|
||||||
|
return product;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
|
import de.rwu.easydrop.service.validation.ProductValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes data for all products of multiple catalogues to persistence.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
public final class CatalogueWriter {
|
||||||
|
/**
|
||||||
|
* Holds a persistence reference.
|
||||||
|
*/
|
||||||
|
private AbstractProductPersistence persistence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instance.
|
||||||
|
*
|
||||||
|
* @param newPersistence
|
||||||
|
*/
|
||||||
|
public CatalogueWriter(final AbstractProductPersistence newPersistence) {
|
||||||
|
persistence = newPersistence;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes all products of specified catalogues to persistence.
|
||||||
|
*
|
||||||
|
* @param catalogues
|
||||||
|
*/
|
||||||
|
public void writeCatalogues(final List<ProductCatalogue> catalogues) {
|
||||||
|
for (ProductCatalogue pCat : catalogues) {
|
||||||
|
for (Product product : pCat.getProducts()) {
|
||||||
|
ProductValidator.validate(product);
|
||||||
|
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
||||||
|
|
||||||
|
persistence.saveProduct(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
|
import de.rwu.easydrop.service.validation.ProductValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for writing product info to persistence.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
public class ProductWriter {
|
||||||
|
/**
|
||||||
|
* Persistence.
|
||||||
|
*/
|
||||||
|
private AbstractProductPersistence persistence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newPersistence the persistence to set
|
||||||
|
*/
|
||||||
|
public void setPersistence(final AbstractProductPersistence newPersistence) {
|
||||||
|
this.persistence = newPersistence;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates and saves product to persistence.
|
||||||
|
*
|
||||||
|
* @param product
|
||||||
|
*/
|
||||||
|
public void writeProductToPersistence(final Product product) {
|
||||||
|
ProductValidator.validate(product);
|
||||||
|
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
||||||
|
|
||||||
|
persistence.saveProduct(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Writes Objects to a data store.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
package de.rwu.easydrop.service.writer;
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package de.rwu.easydrop.api.client;
|
package de.rwu.easydrop.api.client;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
@@ -9,7 +11,10 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.data.connector.SQLiteConnector;
|
||||||
|
import de.rwu.easydrop.exception.PersistenceException;
|
||||||
import de.rwu.easydrop.util.Config;
|
import de.rwu.easydrop.util.Config;
|
||||||
|
|
||||||
class DataSourceFactoryTest {
|
class DataSourceFactoryTest {
|
||||||
@@ -45,4 +50,20 @@ class DataSourceFactoryTest {
|
|||||||
// Assert
|
// Assert
|
||||||
assertEquals("ebay-api-key", dataSource.getApiKey());
|
assertEquals("ebay-api-key", dataSource.getApiKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createProductPersistenceDataSource_NullPersistence() {
|
||||||
|
PersistenceException exception = assertThrows(PersistenceException.class, () -> {
|
||||||
|
dataSourceFactory.createProductPersistenceDataSource();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals("Persistence is not set", exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createProductPersistenceDataSource_WorkingPersistence() {
|
||||||
|
dataSourceFactory.setPersistence(new SQLiteConnector(new SQLiteDataSource()));
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> dataSourceFactory.createProductPersistenceDataSource());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,195 @@
|
|||||||
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.exception.PersistenceException;
|
||||||
|
|
||||||
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
|
class SQLiteConnectorTest {
|
||||||
|
private static final String TEST_PRODUCT_ID = "12345";
|
||||||
|
private SQLiteConnector sqliteConnector;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private SQLiteDataSource mockDataSource;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void setup() {
|
||||||
|
sqliteConnector = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void clearDatabase() {
|
||||||
|
MockitoAnnotations.openMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void saveProduct_ValidProduct_SuccessfullySaved() {
|
||||||
|
// Arrange
|
||||||
|
sqliteConnector.clearData();
|
||||||
|
ProductDTO ProductDTO = new ProductDTO(TEST_PRODUCT_ID, "Amazon");
|
||||||
|
ProductDTO.setDataOrigin("Amazon");
|
||||||
|
ProductDTO.setProductId(TEST_PRODUCT_ID);
|
||||||
|
ProductDTO.setCurrentPrice(9.99);
|
||||||
|
ProductDTO.setMerchant("Sample Merchant");
|
||||||
|
ProductDTO.setDeliveryPrice(2.50);
|
||||||
|
ProductDTO.setAvailable(true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
assertDoesNotThrow(() -> sqliteConnector.saveProduct(ProductDTO));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ProductDTO savedProductDTO = sqliteConnector.getProductDTOById(TEST_PRODUCT_ID);
|
||||||
|
assertNotNull(savedProductDTO);
|
||||||
|
assertEquals("Amazon", savedProductDTO.getDataOrigin());
|
||||||
|
assertEquals(TEST_PRODUCT_ID, savedProductDTO.getProductId());
|
||||||
|
assertEquals(9.99, savedProductDTO.getCurrentPrice());
|
||||||
|
assertEquals("Sample Merchant", savedProductDTO.getMerchant());
|
||||||
|
assertEquals(2.50, savedProductDTO.getDeliveryPrice());
|
||||||
|
assertTrue(savedProductDTO.isAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getProductDTOById_ProductExists_ReturnsProductDTO() {
|
||||||
|
// Arrange
|
||||||
|
sqliteConnector.clearData();
|
||||||
|
insertSampleProduct();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ProductDTO ProductDTO = sqliteConnector.getProductDTOById(TEST_PRODUCT_ID);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNotNull(ProductDTO);
|
||||||
|
assertEquals("Amazon", ProductDTO.getDataOrigin());
|
||||||
|
assertEquals(TEST_PRODUCT_ID, ProductDTO.getProductId());
|
||||||
|
assertEquals(9.99, ProductDTO.getCurrentPrice());
|
||||||
|
assertEquals("Sample Merchant", ProductDTO.getMerchant());
|
||||||
|
assertEquals(2.50, ProductDTO.getDeliveryPrice());
|
||||||
|
assertTrue(ProductDTO.isAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void constructor_ThrowsPersistenceException_OnSQLException() {
|
||||||
|
try {
|
||||||
|
doThrow(SQLException.class).when(mockDataSource).getConnection();
|
||||||
|
|
||||||
|
PersistenceException exception = assertThrows(PersistenceException.class, () -> {
|
||||||
|
new SQLiteConnector(mockDataSource);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals("Something went wrong while initializing SQLite DB", exception.getMessage());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
fail("No SQLException should be thrown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getProductDTOById_ProductDoesNotExist_ReturnsNull() {
|
||||||
|
// Act
|
||||||
|
ProductDTO ProductDTO = sqliteConnector.getProductDTOById("FAKE_ID");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNull(ProductDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void saveProduct_ThrowsPersistenceException_OnSQLException() throws SQLException {
|
||||||
|
// Arrange
|
||||||
|
ProductDTO ProductDTO = new ProductDTO(TEST_PRODUCT_ID, "Amazon");
|
||||||
|
sqliteConnector.setDb(mockDataSource);
|
||||||
|
doThrow(SQLException.class).when(mockDataSource).getConnection();
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(PersistenceException.class, () -> sqliteConnector.saveProduct(ProductDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getProductDTOById_ThrowsPersistenceException_OnSQLException() throws SQLException {
|
||||||
|
// Arrange
|
||||||
|
String productId = "12345";
|
||||||
|
sqliteConnector.setDb(mockDataSource);
|
||||||
|
doThrow(SQLException.class).when(mockDataSource).getConnection();
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(PersistenceException.class, () -> sqliteConnector.getProductDTOById(productId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void clearData_ThrowsPersistenceException_OnSQLException() throws SQLException {
|
||||||
|
// Arrange
|
||||||
|
sqliteConnector.setDb(mockDataSource);
|
||||||
|
doThrow(SQLException.class).when(mockDataSource).getConnection();
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(PersistenceException.class, () -> sqliteConnector.clearData());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertSampleProduct() {
|
||||||
|
ProductDTO ProductDTO = new ProductDTO(TEST_PRODUCT_ID, "Amazon");
|
||||||
|
ProductDTO.setCurrentPrice(9.99);
|
||||||
|
ProductDTO.setMerchant("Sample Merchant");
|
||||||
|
ProductDTO.setDeliveryPrice(2.50);
|
||||||
|
ProductDTO.setAvailable(true);
|
||||||
|
sqliteConnector.saveProduct(ProductDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getDataOrigin_ReturnsCorrectDataOrigin() {
|
||||||
|
// Arrange
|
||||||
|
SQLiteConnector connector = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
String dataOrigin = connector.getDataOrigin();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals("SQLite", dataOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getApiKey_UnsupportedOperationExceptionThrown() {
|
||||||
|
// Arrange
|
||||||
|
SQLiteConnector connector = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(UnsupportedOperationException.class, connector::getApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void buildProductDTO_UnsupportedOperationExceptionThrown() {
|
||||||
|
// Arrange
|
||||||
|
SQLiteConnector connector = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
ProductDTO product = new ProductDTO("ASIN123", "Amazon");
|
||||||
|
String json = "{\"productId\":\"ASIN123\",\"dataOrigin\":\"Amazon\"}";
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(UnsupportedOperationException.class, () -> connector.buildProductDTO(product, json));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createApiUrl_UnsupportedOperationExceptionThrown() {
|
||||||
|
// Arrange
|
||||||
|
SQLiteConnector connector = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
String productIdentifier = "ASIN123";
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(UnsupportedOperationException.class, () -> connector.createApiUrl(productIdentifier));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package de.rwu.easydrop.exception;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class PersistenceExceptionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPersistenceExceptionWithMessage() {
|
||||||
|
String errorMessage = "Error occurred during data persistence.";
|
||||||
|
PersistenceException exception = new PersistenceException(errorMessage);
|
||||||
|
|
||||||
|
assertEquals(errorMessage, exception.getMessage());
|
||||||
|
assertNull(exception.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPersistenceExceptionWithMessageAndCause() {
|
||||||
|
String errorMessage = "Error occurred during data persistence.";
|
||||||
|
Throwable cause = new IllegalArgumentException("Invalid argument.");
|
||||||
|
PersistenceException exception = new PersistenceException(errorMessage, cause);
|
||||||
|
|
||||||
|
assertEquals(errorMessage, exception.getMessage());
|
||||||
|
assertEquals(cause, exception.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import java.lang.reflect.Modifier;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
class ProductMapperTest {
|
class ProductMapperTest {
|
||||||
@@ -53,4 +54,27 @@ class ProductMapperTest {
|
|||||||
dto.setMerchant("Example Merchant");
|
dto.setMerchant("Example Merchant");
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mapProductToDTO() {
|
||||||
|
// Arrange
|
||||||
|
Product product = new Product();
|
||||||
|
product.setProductId("12345");
|
||||||
|
product.setDataOrigin("Amazon");
|
||||||
|
product.setAvailable(true);
|
||||||
|
product.setCurrentPrice(9.99);
|
||||||
|
product.setDeliveryPrice(2.50);
|
||||||
|
product.setMerchant("Seller1");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals("12345", dto.getProductId());
|
||||||
|
assertEquals("Amazon", dto.getDataOrigin());
|
||||||
|
assertTrue(dto.isAvailable());
|
||||||
|
assertEquals(9.99, dto.getCurrentPrice());
|
||||||
|
assertEquals(2.50, dto.getDeliveryPrice());
|
||||||
|
assertEquals("Seller1", dto.getMerchant());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package de.rwu.easydrop.service.retriever;
|
package de.rwu.easydrop.service.retriever;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -13,6 +14,7 @@ import javax.naming.ConfigurationException;
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.exception.InvalidProductException;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
import de.rwu.easydrop.util.ProductsConfig;
|
import de.rwu.easydrop.util.ProductsConfig;
|
||||||
@@ -40,11 +42,11 @@ class CatalogueRetrieverTest {
|
|||||||
product1.setDataOrigin("Amazon");
|
product1.setDataOrigin("Amazon");
|
||||||
product1.setProductId("ASIN1");
|
product1.setProductId("ASIN1");
|
||||||
productCatalogue.addProduct(product1);
|
productCatalogue.addProduct(product1);
|
||||||
|
|
||||||
Product product2 = new Product();
|
Product product2 = new Product();
|
||||||
product2.setDataOrigin("eBay");
|
product2.setDataOrigin("eBay");
|
||||||
product2.setProductId("ProductID2");
|
product2.setProductId("ProductID2");
|
||||||
productCatalogue.addProduct(product2);
|
productCatalogue.addProduct(product2);
|
||||||
|
|
||||||
productCatalogues.add(productCatalogue);
|
productCatalogues.add(productCatalogue);
|
||||||
|
|
||||||
// Mock the methods
|
// Mock the methods
|
||||||
@@ -72,4 +74,30 @@ class CatalogueRetrieverTest {
|
|||||||
verify(productRetriever).getProductFromAmazon("ASIN1");
|
verify(productRetriever).getProductFromAmazon("ASIN1");
|
||||||
verify(productRetriever).getProductFromEbay("ProductID2");
|
verify(productRetriever).getProductFromEbay("ProductID2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadCatalogues_ValidConfig_CataloguesLoaded_InvalidProduct() throws ConfigurationException {
|
||||||
|
// Arrange
|
||||||
|
List<ProductCatalogue> productCatalogues = new ArrayList<>();
|
||||||
|
|
||||||
|
// Create a sample product catalogue
|
||||||
|
ProductCatalogue productCatalogue = new ProductCatalogue("Catalogue 1", "Sample catalogue");
|
||||||
|
|
||||||
|
Product product = new Product();
|
||||||
|
product.setDataOrigin("");
|
||||||
|
product.setProductId("ProductID1");
|
||||||
|
productCatalogue.addProduct(product);
|
||||||
|
productCatalogues.add(productCatalogue);
|
||||||
|
|
||||||
|
// Mock the methods
|
||||||
|
when(productsConfig.getProductCatalogues()).thenReturn(productCatalogues);
|
||||||
|
when(productRetriever.getProductFromAmazon("ProductID1")).thenReturn(product);
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
InvalidProductException exception = assertThrows(InvalidProductException.class, () -> {
|
||||||
|
catalogueRetriever.loadCatalogues();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals("Product data origin is invalid", exception.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import de.rwu.easydrop.api.client.AmazonProductDataSource;
|
|||||||
import de.rwu.easydrop.api.client.DataSourceFactory;
|
import de.rwu.easydrop.api.client.DataSourceFactory;
|
||||||
import de.rwu.easydrop.api.client.EbayItemDataSource;
|
import de.rwu.easydrop.api.client.EbayItemDataSource;
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.util.Config;
|
import de.rwu.easydrop.util.Config;
|
||||||
|
|
||||||
@@ -33,6 +34,8 @@ class ProductRetrieverTest {
|
|||||||
private ProductDTO productDTO;
|
private ProductDTO productDTO;
|
||||||
@Mock
|
@Mock
|
||||||
private Product product;
|
private Product product;
|
||||||
|
@Mock
|
||||||
|
private AbstractProductPersistence persistence;
|
||||||
|
|
||||||
private ProductRetriever productRetriever;
|
private ProductRetriever productRetriever;
|
||||||
|
|
||||||
@@ -84,4 +87,25 @@ class ProductRetrieverTest {
|
|||||||
assertEquals(9.99, result.getCurrentPrice());
|
assertEquals(9.99, result.getCurrentPrice());
|
||||||
verify(ebayDataSource, times(1)).getProductDTOById(productQuery);
|
verify(ebayDataSource, times(1)).getProductDTOById(productQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getProductFromPersistence_ValidProductId_ReturnsProduct() {
|
||||||
|
// Arrange
|
||||||
|
String productId = "123";
|
||||||
|
when(dataSourceFactory.createProductPersistenceDataSource()).thenReturn(persistence);
|
||||||
|
when(persistence.getProductDTOById(productId)).thenReturn(productDTO);
|
||||||
|
when(productDTO.getProductId()).thenReturn(productId);
|
||||||
|
when(productDTO.getCurrentPrice()).thenReturn(9.99);
|
||||||
|
when(productDTO.getDataOrigin()).thenReturn("Amazon");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Product result = productRetriever.getProductFromPersistence(productId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(productId, result.getProductId());
|
||||||
|
assertEquals(9.99, result.getCurrentPrice());
|
||||||
|
|
||||||
|
// Verify the interactions
|
||||||
|
verify(persistence, times(1)).getProductDTOById(productId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
|
|
||||||
|
class CatalogueWriterTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AbstractProductPersistence persistenceMock;
|
||||||
|
|
||||||
|
private CatalogueWriter catalogueWriter;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
MockitoAnnotations.openMocks(this);
|
||||||
|
catalogueWriter = new CatalogueWriter(persistenceMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeCatalogues_ValidCatalogues_ProductsWrittenToPersistence() {
|
||||||
|
// Arrange
|
||||||
|
List<ProductCatalogue> catalogues = createSampleCatalogues();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
catalogueWriter.writeCatalogues(catalogues);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(persistenceMock, times(4)).saveProduct(any(ProductDTO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProductCatalogue> createSampleCatalogues() {
|
||||||
|
List<ProductCatalogue> catalogues = new ArrayList<>();
|
||||||
|
|
||||||
|
ProductCatalogue catalogue1 = new ProductCatalogue("Catalogue 1", "Sample catalogue 1");
|
||||||
|
catalogue1.addProduct(createSampleProduct("Amazon", "ID 1"));
|
||||||
|
catalogue1.addProduct(createSampleProduct("eBay", "ID 2"));
|
||||||
|
|
||||||
|
ProductCatalogue catalogue2 = new ProductCatalogue("Catalogue 2", "Sample catalogue 2");
|
||||||
|
catalogue2.addProduct(createSampleProduct("Amazon", "ID 3"));
|
||||||
|
catalogue2.addProduct(createSampleProduct("eBay", "ID 4"));
|
||||||
|
|
||||||
|
catalogues.add(catalogue1);
|
||||||
|
catalogues.add(catalogue2);
|
||||||
|
|
||||||
|
return catalogues;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Product createSampleProduct(String dataOrigin, String productId) {
|
||||||
|
Product product = new Product();
|
||||||
|
product.setDataOrigin(dataOrigin);
|
||||||
|
product.setProductId(productId);
|
||||||
|
product.setCurrentPrice(9999.99);
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
|
class ProductWriterTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AbstractProductPersistence persistence;
|
||||||
|
|
||||||
|
private ProductWriter productWriter;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setup() {
|
||||||
|
MockitoAnnotations.openMocks(this);
|
||||||
|
productWriter = new ProductWriter();
|
||||||
|
productWriter.setPersistence(persistence);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeProductToPersistence_ValidProduct_CallsSaveProduct() {
|
||||||
|
// Arrange
|
||||||
|
Product product = new Product();
|
||||||
|
product.setProductId("12345");
|
||||||
|
product.setDataOrigin("Amazon");
|
||||||
|
product.setCurrentPrice(9.99);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
productWriter.writeProductToPersistence(product);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Mockito.verify(persistence).saveProduct(any(ProductDTO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeProductToPersistence_InvalidProduct_ThrowsException() {
|
||||||
|
// Arrange
|
||||||
|
Product product = new Product();
|
||||||
|
product.setProductId("");
|
||||||
|
product.setDataOrigin("Amazon");
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(Exception.class, () -> productWriter.writeProductToPersistence(product));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
package de.rwu.easydrop.util;
|
package de.rwu.easydrop.util;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
|
|
||||||
class ProductsConfigIntegrationTest {
|
class ProductsConfigIntegrationTest {
|
||||||
private ProductsConfig config;
|
private ProductsConfig config;
|
||||||
private final static String TESTDATA_PATH = "src/test/resources/test.products-config.json";
|
private final static String TESTDATA_PATH = "src/test/resources/test.products-config.json";
|
||||||
@@ -65,4 +70,20 @@ class ProductsConfigIntegrationTest {
|
|||||||
|
|
||||||
assertEquals("Products config is empty or malformed", exception.getMessage());
|
assertEquals("Products config is empty or malformed", exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testReset() {
|
||||||
|
try {
|
||||||
|
config.setConfigLocation(TESTDATA_PATH);
|
||||||
|
config.loadConfig();
|
||||||
|
} catch (ConfigurationException e) {
|
||||||
|
fail("ConfigurationException should not be thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(config.getProductCatalogues());
|
||||||
|
config.reset();
|
||||||
|
List<ProductCatalogue> pCats = config.getProductCatalogues();
|
||||||
|
|
||||||
|
assertEquals(0, pCats.size(), "Catalogues list should be empty");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user