Added Product mapping and validation
This commit is contained in:
@@ -1,14 +1,44 @@
|
|||||||
package de.rwu.easydrop.service.mapping;
|
package de.rwu.easydrop.service.mapping;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps between Product, ProductDAO and ProductDTO.
|
* Maps between Product, ProductDAO and ProductDTO.
|
||||||
*
|
*
|
||||||
* TODO implement
|
* @since 0.2.0
|
||||||
*
|
*
|
||||||
* @see Product
|
* @see Product
|
||||||
* @see ProductDTO
|
* @see ProductDTO
|
||||||
* @see ProductDAO
|
* @see ProductDAO
|
||||||
*/
|
*/
|
||||||
public class ProductMapper {
|
public final class ProductMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor to prevent unwanted instantiation.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
*/
|
||||||
|
private ProductMapper() throws UnsupportedOperationException {
|
||||||
|
throw new UnsupportedOperationException("This is a mapping class, don't instantiate it.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Product object from a corresponding DTO.
|
||||||
|
*
|
||||||
|
* @param dto Product Data Transfer Object
|
||||||
|
* @return Product
|
||||||
|
*/
|
||||||
|
public static Product mapProductFromDTO(final ProductDTO dto) {
|
||||||
|
Product product = new Product();
|
||||||
|
|
||||||
|
product.setAvailable(dto.isAvailable());
|
||||||
|
product.setCurrentPrice(dto.getCurrentPrice());
|
||||||
|
product.setDataOrigin(dto.getDataOrigin());
|
||||||
|
product.setDeliveryPrice(dto.getDeliveryPrice());
|
||||||
|
product.setMerchant(dto.getMerchant());
|
||||||
|
product.setProductId(dto.getProductId());
|
||||||
|
|
||||||
|
return product;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Maps different formats of corresponding objects.
|
* Maps different formats of corresponding objects.
|
||||||
*
|
*
|
||||||
* TODO implement
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
package de.rwu.easydrop.service.mapping;
|
package de.rwu.easydrop.service.mapping;
|
||||||
|
|||||||
@@ -1,10 +1,56 @@
|
|||||||
package de.rwu.easydrop.service.validation;
|
package de.rwu.easydrop.service.validation;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.exception.InvalidProductException;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirms validity of Product data.
|
* Confirms validity of Product data.
|
||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
public class ProductValidator {
|
public final class ProductValidator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor to prevent unwanted instantiation.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
*/
|
||||||
|
private ProductValidator() throws UnsupportedOperationException {
|
||||||
|
throw new UnsupportedOperationException("This is a validator class, don't instantiate it.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure a Product does not contain invalid information.
|
||||||
|
*
|
||||||
|
* @param product the Product
|
||||||
|
*/
|
||||||
|
public static void validate(final Product product) {
|
||||||
|
if (product.getCurrentPrice() == 0.00) {
|
||||||
|
throw new InvalidProductException("Current price cannot be 0.00");
|
||||||
|
}
|
||||||
|
if (!isInValidDataOrigins(product.getDataOrigin())) {
|
||||||
|
throw new InvalidProductException("Unknown data source");
|
||||||
|
}
|
||||||
|
if (product.getProductId().equals("")) {
|
||||||
|
throw new InvalidProductException("Product ID cannot be empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a dataOrigin is within the set of valid ones.
|
||||||
|
*
|
||||||
|
* @param dataOrigin like "Amazon"
|
||||||
|
* @return true if valid
|
||||||
|
*/
|
||||||
|
public static boolean isInValidDataOrigins(final String dataOrigin) {
|
||||||
|
Set<String> validOrigins = new HashSet<>();
|
||||||
|
|
||||||
|
validOrigins.add("Amazon");
|
||||||
|
validOrigins.add("eBay");
|
||||||
|
|
||||||
|
return validOrigins.contains(dataOrigin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Supports validation processes.
|
* Supports validation processes.
|
||||||
*
|
*
|
||||||
* TODO implement
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
package de.rwu.easydrop.service.validation;
|
package de.rwu.easydrop.service.validation;
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package de.rwu.easydrop.service.mapping;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
|
class ProductMapperTest {
|
||||||
|
@Test
|
||||||
|
void testConstructorIsPrivate()
|
||||||
|
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||||
|
// Check for private constructor
|
||||||
|
Constructor<ProductMapper> constructor = ProductMapper.class.getDeclaredConstructor();
|
||||||
|
assertTrue(Modifier.isPrivate(constructor.getModifiers()));
|
||||||
|
|
||||||
|
// Make sure exception is thrown when instantiating
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
assertThrows(InvocationTargetException.class, () -> {
|
||||||
|
constructor.newInstance();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mapProductFromDTO_ReturnsProductWithMappedFields() {
|
||||||
|
// Arrange
|
||||||
|
ProductDTO dto = createProductDTO();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Product product = ProductMapper.mapProductFromDTO(dto);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(dto.isAvailable(), product.isAvailable());
|
||||||
|
assertEquals(dto.getCurrentPrice(), product.getCurrentPrice());
|
||||||
|
assertEquals(dto.getDataOrigin(), product.getDataOrigin());
|
||||||
|
assertEquals(dto.getDeliveryPrice(), product.getDeliveryPrice());
|
||||||
|
assertEquals(dto.getMerchant(), product.getMerchant());
|
||||||
|
assertEquals(dto.getProductId(), product.getProductId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProductDTO createProductDTO() {
|
||||||
|
ProductDTO dto = new ProductDTO("12345", "Amazon");
|
||||||
|
dto.setAvailable(true);
|
||||||
|
dto.setCurrentPrice(9.99);
|
||||||
|
dto.setDeliveryPrice(2.50);
|
||||||
|
dto.setMerchant("Example Merchant");
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package de.rwu.easydrop.service.validation;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.exception.InvalidProductException;
|
||||||
|
import de.rwu.easydrop.model.Product;
|
||||||
|
|
||||||
|
class ProductValidatorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorIsPrivate()
|
||||||
|
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||||
|
// Check for private constructor
|
||||||
|
Constructor<ProductValidator> constructor = ProductValidator.class.getDeclaredConstructor();
|
||||||
|
assertTrue(Modifier.isPrivate(constructor.getModifiers()));
|
||||||
|
|
||||||
|
// Make sure exception is thrown when instantiating
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
assertThrows(InvocationTargetException.class, () -> {
|
||||||
|
constructor.newInstance();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_ValidProduct_NoExceptionThrown() {
|
||||||
|
// Arrange
|
||||||
|
Product product = new Product();
|
||||||
|
product.setCurrentPrice(9.99);
|
||||||
|
product.setDataOrigin("Amazon");
|
||||||
|
product.setProductId("12345");
|
||||||
|
|
||||||
|
// Act and Assert
|
||||||
|
assertDoesNotThrow(() -> ProductValidator.validate(product));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isInValidDataOrigins_ValidDataOrigin_ReturnsTrue() {
|
||||||
|
// Arrange
|
||||||
|
String dataOrigin = "Amazon";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
boolean result = ProductValidator.isInValidDataOrigins(dataOrigin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isInValidDataOrigins_InvalidDataOrigin_ReturnsFalse() {
|
||||||
|
// Arrange
|
||||||
|
String dataOrigin = "UnknownOrigin";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
boolean result = ProductValidator.isInValidDataOrigins(dataOrigin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("invalidProductProvider")
|
||||||
|
void validate_InvalidProduct_ThrowsInvalidProductException(Product product) {
|
||||||
|
// Act and Assert
|
||||||
|
assertThrows(InvalidProductException.class, () -> ProductValidator.validate(product));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Product> invalidProductProvider() {
|
||||||
|
return Stream.of(
|
||||||
|
createProductWithZeroPrice(),
|
||||||
|
createProductWithUnknownDataOrigin(),
|
||||||
|
createProductWithEmptyProductId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Product createProductWithZeroPrice() {
|
||||||
|
Product product = new Product();
|
||||||
|
product.setCurrentPrice(0.00);
|
||||||
|
product.setDataOrigin("Amazon");
|
||||||
|
product.setProductId("12345");
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Product createProductWithUnknownDataOrigin() {
|
||||||
|
Product product = new Product();
|
||||||
|
product.setCurrentPrice(9.99);
|
||||||
|
product.setDataOrigin("UnknownOrigin");
|
||||||
|
product.setProductId("12345");
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Product createProductWithEmptyProductId() {
|
||||||
|
Product product = new Product();
|
||||||
|
product.setCurrentPrice(9.99);
|
||||||
|
product.setDataOrigin("Amazon");
|
||||||
|
product.setProductId("");
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user