Added Product mapping and validation

This commit is contained in:
Marvin Scham
2023-06-06 02:12:35 +02:00
parent af8993cb0f
commit 7f57955400
6 changed files with 247 additions and 6 deletions

View File

@@ -1,14 +1,44 @@
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.
*
* TODO implement
* @since 0.2.0
*
* @see Product
* @see ProductDTO
* @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;
}
}

View File

@@ -1,6 +1,6 @@
/**
* Maps different formats of corresponding objects.
*
* TODO implement
* @since 0.2.0
*/
package de.rwu.easydrop.service.mapping;

View File

@@ -1,10 +1,56 @@
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.
*
* @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);
}
}

View File

@@ -1,6 +1,6 @@
/**
* Supports validation processes.
*
* TODO implement
* @since 0.2.0
*/
package de.rwu.easydrop.service.validation;

View File

@@ -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;
}
}

View File

@@ -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;
}
}