forked from pierront/mylibrary-template
Sauvegarde de l'avancée
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
public class OrderInfo {
|
||||||
|
private UUID customerId;
|
||||||
|
private List<OrderLineDTO> orderLines;
|
||||||
|
private AddressDTO address;
|
||||||
|
private String paymentMethod;
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.converter;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderLineDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.AddressDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.PaymentMethod;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderInfo;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
|
|
||||||
|
public class OrderConverter {
|
||||||
|
private OrderConverter() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Order toDomain(OrderInfo orderInfo) {
|
||||||
|
return Order.builder()
|
||||||
|
.customerId(orderInfo.getCustomerId())
|
||||||
|
.orderLines(orderInfo.getOrderLines())
|
||||||
|
.address(orderInfo.getAddress())
|
||||||
|
.paymentMethod(PaymentMethod.valueOf(orderInfo.getPaymentMethod()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OrderDTO toDTO(Order order) {
|
||||||
|
return OrderDTO.builder()
|
||||||
|
.id(order.getId())
|
||||||
|
.customerId(order.getCustomerId())
|
||||||
|
.orderLines(order.getOrderLines())
|
||||||
|
.totalPrice(order.getTotalPrice())
|
||||||
|
.totalPriceToPay(order.getTotalPriceToPay())
|
||||||
|
.address(order.getAddress())
|
||||||
|
.paymentMethod(order.getPaymentMethod())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.entity;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.*;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
public class Order {
|
||||||
|
private UUID id;
|
||||||
|
private UUID customerId;
|
||||||
|
private List<OrderLineDTO> orderLines;
|
||||||
|
private double totalPrice;
|
||||||
|
private double totalPriceToPay;
|
||||||
|
private AddressDTO address;
|
||||||
|
private PaymentMethod paymentMethod;
|
||||||
|
|
||||||
|
public void setRandomUUID() {
|
||||||
|
this.id = UUID.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(AddressDTO address) throws NotValidOrderException {
|
||||||
|
if (address == null) {
|
||||||
|
throw new NotValidOrderException("Address cannot be null");
|
||||||
|
}
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderLines(List<OrderLineDTO> orderLines) throws NotValidOrderException {
|
||||||
|
if (orderLines == null || orderLines.isEmpty()) {
|
||||||
|
throw new NotValidOrderException("Order lines cannot be null or empty");
|
||||||
|
}
|
||||||
|
this.orderLines = orderLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalPrice(double total) {
|
||||||
|
if (total <= 0) {
|
||||||
|
throw new IllegalArgumentException("Total price must be greater than zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.totalPrice = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalPriceToPay(double totalPriceToPay) {
|
||||||
|
if (totalPriceToPay < 0) {
|
||||||
|
throw new IllegalArgumentException("Total price to pay cannot be negative");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.totalPriceToPay = totalPriceToPay;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||||
|
|
||||||
|
public class NotValidOrderException extends Exception {
|
||||||
|
public NotValidOrderException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class OrderNotFoundException extends Exception {
|
||||||
|
|
||||||
|
public static final String THE_ORDER_WITH_ID_DOES_NOT_EXIST_MESSAGE = "The order with id {0} does not exist";
|
||||||
|
|
||||||
|
public OrderNotFoundException(String message) {
|
||||||
|
super(MessageFormat.format(THE_ORDER_WITH_ID_DOES_NOT_EXIST_MESSAGE, message));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UserNotFoundException extends RuntimeException {
|
||||||
|
|
||||||
|
public static final String THE_CUSTOMER_WITH_ID_DOES_NOT_EXIST_MESSAGE = "The user with id {0} does not exist";
|
||||||
|
|
||||||
|
public UserNotFoundException(String message) {
|
||||||
|
super(MessageFormat.format(THE_CUSTOMER_WITH_ID_DOES_NOT_EXIST_MESSAGE, message));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.repository;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public final class OrderRepository {
|
||||||
|
private final List<Order> orders = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<Order> findAll() {
|
||||||
|
return orders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Order save(Order newOrder) {
|
||||||
|
Optional<Order> optionalOrderWithSameId = this.findById(newOrder.getId());
|
||||||
|
optionalOrderWithSameId.ifPresent(orders::remove);
|
||||||
|
if (newOrder.getId() == null) {
|
||||||
|
newOrder.setRandomUUID();
|
||||||
|
}
|
||||||
|
this.orders.add(newOrder);
|
||||||
|
|
||||||
|
|
||||||
|
return newOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Order> findById(UUID uuid) {
|
||||||
|
return this.orders.stream()
|
||||||
|
.filter(order -> order.getId().equals(uuid))
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Order> findByCustomerId(UUID customerId) {
|
||||||
|
List<Order> result = new ArrayList<>();
|
||||||
|
for (Order order : orders) {
|
||||||
|
if (order.getCustomerId().equals(customerId)) {
|
||||||
|
result.add(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean existsById(UUID uuid) {
|
||||||
|
return this.orders.stream()
|
||||||
|
.anyMatch(order -> order.getId().equals(uuid));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,126 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.usecase;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.usecase.OrderUseCase;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderLineDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.AddressDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.PaymentMethod;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderInfo;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.repository.OrderRepository;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.converter.OrderConverter;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.validator.OrderValidator;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.OrderNotFoundException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.UserNotFoundException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class OrderUseCase {
|
||||||
|
|
||||||
|
private final OrderRepository orderRepository;
|
||||||
|
private final BookRepository bookRepository;
|
||||||
|
private final CustomerRepository customerRepository;
|
||||||
|
|
||||||
|
|
||||||
|
private OrderInfo tempOrderInfo;
|
||||||
|
private List<OrderLineDTO> tempOrderLines;
|
||||||
|
private AddressDTO tempAddress;
|
||||||
|
|
||||||
|
public OrderUseCase(OrderRepository orderRepository, BookRepository bookRepository, CustomerRepository customerRepository) {
|
||||||
|
this.orderRepository = orderRepository;
|
||||||
|
this.bookRepository = bookRepository;
|
||||||
|
this.customerRepository = customerRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerOrderInfo(OrderInfo orderInfo) {
|
||||||
|
this.tempOrderInfo = orderInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBooksToOrder(List<OrderLineDTO> orderLines) throws NotValidOrderException {
|
||||||
|
this.tempOrderLines = orderLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeliveryAddress(AddressDTO address) {
|
||||||
|
this.tempAddress = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double computeTotalPrice(List<OrderLineDTO> orderInfo) throws NotValidOrderException {
|
||||||
|
if (orderInfo == null || orderInfo.isEmpty()) {
|
||||||
|
throw new NotValidOrderException("Order lines cannot be null or empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
double totalPrice = 0.0;
|
||||||
|
for (OrderLineDTO line : orderInfo) {
|
||||||
|
Book book = bookRepository.findByISBN(line.getBookId())
|
||||||
|
.orElseThrow(() -> new NotValidOrderException("Book not found with ISBN: " + line.getBookId()));
|
||||||
|
totalPrice += book.getPrice() * line.getQuantity();
|
||||||
|
}
|
||||||
|
return totalPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID finalizeOrder() throws NotValidOrderException, UserNotFoundException {
|
||||||
|
if (tempOrderInfo == null) throw new NotValidOrderException("Order info missing");
|
||||||
|
OrderInfo completeInfo = OrderInfo.builder()
|
||||||
|
.customerId(tempOrderInfo.getCustomerId())
|
||||||
|
.paymentMethod(tempOrderInfo.getPaymentMethod())
|
||||||
|
.orderLines(tempOrderLines)
|
||||||
|
.address(tempAddress)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
UUID customerId = tempOrderInfo.getCustomerId();
|
||||||
|
Customer customer = customerRepository.findById(customerId)
|
||||||
|
.orElseThrow(() -> new UserNotFoundException("Customer not found with ID: " + customerId));
|
||||||
|
|
||||||
|
|
||||||
|
OrderValidator.validate(completeInfo);
|
||||||
|
|
||||||
|
Order order = OrderConverter.toDomain(completeInfo);
|
||||||
|
order.setRandomUUID();
|
||||||
|
order.setAddress(tempAddress);
|
||||||
|
order.setOrderLines(tempOrderLines);
|
||||||
|
double totalPrice = computeTotalPrice(completeInfo.getOrderLines() );
|
||||||
|
order.setTotalPrice(totalPrice);
|
||||||
|
order.setTotalPriceToPay(totalPrice);
|
||||||
|
|
||||||
|
|
||||||
|
orderRepository.save(order);
|
||||||
|
|
||||||
|
tempOrderInfo = null;
|
||||||
|
tempOrderLines = null;
|
||||||
|
tempAddress = null;
|
||||||
|
|
||||||
|
return order.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<OrderDTO> findOrderById(UUID orderId) {
|
||||||
|
Optional<Order> order = orderRepository.findById(orderId);
|
||||||
|
return order.map(OrderConverter::toDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<OrderDTO> findOrdersByCustomerId(UUID customerId) throws UserNotFoundException {
|
||||||
|
List<Order> orders = orderRepository.findByCustomerId(customerId);
|
||||||
|
List<OrderDTO> dtos = new ArrayList<>();
|
||||||
|
for (Order order : orders) {
|
||||||
|
dtos.add(OrderConverter.toDTO(order));
|
||||||
|
}
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID registerOrder(OrderInfo orderInfo) throws NotValidOrderException {
|
||||||
|
OrderValidator.validate(orderInfo);
|
||||||
|
double total = computeTotalPrice(orderInfo.getOrderLines());
|
||||||
|
Order order = OrderConverter.toDomain(orderInfo);
|
||||||
|
order.setTotalPrice(total);
|
||||||
|
order.setTotalPriceToPay(total);
|
||||||
|
order.setRandomUUID();
|
||||||
|
orderRepository.save(order);
|
||||||
|
return order.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.validator;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderInfo;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderLineDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.AddressDTO;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OrderValidator {
|
||||||
|
|
||||||
|
public static final String CUSTOMER_ID_CANNOT_BE_NULL = "Customer ID cannot be null";
|
||||||
|
public static final String BOOK_LIST_CANNOT_BE_EMPTY = "Book list cannot be empty";
|
||||||
|
public static final String QUANTITY_MUST_BE_POSITIVE = "Quantity must be positive";
|
||||||
|
public static final String ADDRESS_FIELDS_ARE_REQUIRED = "Address fields are required: street, city, postal code, and country must not be null or empty";
|
||||||
|
public static final String PAYMENT_METHOD_IS_NOT_VALID = "Payment method is not valid. Valid methods are: CREDIT_CARD, LOYALTY_POINTS";
|
||||||
|
|
||||||
|
private OrderValidator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void validate(OrderInfo orderInfo) throws NotValidOrderException {
|
||||||
|
validateCustomerId(orderInfo);
|
||||||
|
validateOrderLines(orderInfo);
|
||||||
|
validateAddress(orderInfo);
|
||||||
|
validatePaymentMethod(orderInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validateCustomerId(OrderInfo orderInfo) throws NotValidOrderException {
|
||||||
|
if (orderInfo.getCustomerId() == null) {
|
||||||
|
throw new NotValidOrderException(CUSTOMER_ID_CANNOT_BE_NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validateOrderLines(OrderInfo orderInfo) throws NotValidOrderException {
|
||||||
|
List<OrderLineDTO> lines = orderInfo.getOrderLines();
|
||||||
|
if (lines == null || lines.isEmpty()) {
|
||||||
|
throw new NotValidOrderException(BOOK_LIST_CANNOT_BE_EMPTY);
|
||||||
|
}
|
||||||
|
for (OrderLineDTO line : lines) {
|
||||||
|
if (line.getQuantity() < 0) {
|
||||||
|
throw new NotValidOrderException(QUANTITY_MUST_BE_POSITIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validateAddress(OrderInfo orderInfo) throws NotValidOrderException {
|
||||||
|
AddressDTO address = orderInfo.getAddress();
|
||||||
|
if (address == null || address.getStreet().isBlank() || address.getCity().isBlank() || address.getPostalCode().isBlank() || address.getCountry().isBlank()) {
|
||||||
|
throw new NotValidOrderException(ADDRESS_FIELDS_ARE_REQUIRED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validatePaymentMethod(OrderInfo orderInfo) throws NotValidOrderException {
|
||||||
|
String method = orderInfo.getPaymentMethod();
|
||||||
|
if (method == null || method.isBlank() || !(method.equals("CREDIT_CARD") || method.equals("LOYALTY_POINTS"))) {
|
||||||
|
throw new NotValidOrderException(PAYMENT_METHOD_IS_NOT_VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,9 +2,12 @@ package fr.iut_fbleau.but3.dev62.mylibrary.features.order;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.usecase.OrderUseCase;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderLineDTO;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderLineDTO;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderDTO;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderDTO;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.AddressDTO;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.AddressDTO;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.PaymentMethod;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderInfo;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderInfo;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.repository.OrderRepository;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.repository.OrderRepository;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
@@ -26,16 +29,15 @@ import java.text.SimpleDateFormat;
|
|||||||
|
|
||||||
public class OrderSteps {
|
public class OrderSteps {
|
||||||
private final OrderRepository orderRepository = new OrderRepository();
|
private final OrderRepository orderRepository = new OrderRepository();
|
||||||
private final OrderUserCase orderUserCase = new OrderUseCase(orderRepository);
|
|
||||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
|
||||||
private final Map<String, UUID> customerPhoneUUID = new HashMap<>();
|
|
||||||
private final BookRepository bookRepository = new BookRepository();
|
private final BookRepository bookRepository = new BookRepository();
|
||||||
|
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||||
|
private final OrderUseCase orderUseCase = new OrderUseCase(orderRepository, bookRepository, customerRepository);
|
||||||
|
private final Map<String, UUID> customerPhoneUUID = new HashMap<>();
|
||||||
private final Map<String, String> bookISBN = new HashMap<>();
|
private final Map<String, String> bookISBN = new HashMap<>();
|
||||||
|
|
||||||
private UUID orderRegistration;
|
private UUID orderId;
|
||||||
private Optional<OrderDTO> orderByUUID;
|
private Optional<OrderDTO> orderByUUID;
|
||||||
private Book updatedBook;
|
private List<OrderDTO> orders;
|
||||||
private Customer updatedCustomer;
|
|
||||||
|
|
||||||
private Exception exception;
|
private Exception exception;
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ public class OrderSteps {
|
|||||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||||
|
|
||||||
for (Map<String, String> book : books) {
|
for (Map<String, String> book : books) {
|
||||||
String ISBN = book.get("ISBN");
|
String ISBN = book.get("isbn");
|
||||||
Book newBook = Book.builder()
|
Book newBook = Book.builder()
|
||||||
.isbn(ISBN)
|
.isbn(ISBN)
|
||||||
.title(book.get("titre"))
|
.title(book.get("titre"))
|
||||||
@@ -76,7 +78,7 @@ public class OrderSteps {
|
|||||||
assertEquals(books.size(), bookRepository.findAll().size());
|
assertEquals(books.size(), bookRepository.findAll().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@And("the system has the following customers:")
|
@And("the system has the following customers in the database:")
|
||||||
public void theSystemHasTheFollowingCustomers(DataTable dataTable) {
|
public void theSystemHasTheFollowingCustomers(DataTable dataTable) {
|
||||||
int size = customerRepository.findAll().size();
|
int size = customerRepository.findAll().size();
|
||||||
|
|
||||||
@@ -87,12 +89,12 @@ public class OrderSteps {
|
|||||||
List<Map<String, String>> customers = dataTable.asMaps(String.class, String.class);
|
List<Map<String, String>> customers = dataTable.asMaps(String.class, String.class);
|
||||||
|
|
||||||
for (Map<String, String> customer : customers) {
|
for (Map<String, String> customer : customers) {
|
||||||
String numeroTelephone = customer.get("numeroTelephone");
|
String numeroTelephone = customer.get("phoneNumber");
|
||||||
Customer newCustomer = Customer.builder()
|
Customer newCustomer = Customer.builder()
|
||||||
.firstName(customer.get("prenom"))
|
.firstName(customer.get("firstName"))
|
||||||
.lastName(customer.get("nom"))
|
.lastName(customer.get("lastName"))
|
||||||
.phoneNumber(numeroTelephone)
|
.phoneNumber(numeroTelephone)
|
||||||
.loyaltyPoints(Integer.parseInt(customer.get("pointsFidelite")))
|
.loyaltyPoints(Integer.parseInt(customer.get("loyaltyPoints")))
|
||||||
.build();
|
.build();
|
||||||
Customer save = customerRepository.save(newCustomer);
|
Customer save = customerRepository.save(newCustomer);
|
||||||
customerPhoneUUID.put(numeroTelephone, save.getId());
|
customerPhoneUUID.put(numeroTelephone, save.getId());
|
||||||
@@ -104,47 +106,42 @@ public class OrderSteps {
|
|||||||
@When("I create a new order with the following information:")
|
@When("I create a new order with the following information:")
|
||||||
public void iCreateANewOrderWithTheFollowingInformation(DataTable dataTable) {
|
public void iCreateANewOrderWithTheFollowingInformation(DataTable dataTable) {
|
||||||
Map<String, String> orderData = dataTable.asMaps(String.class, String.class).getFirst();
|
Map<String, String> orderData = dataTable.asMaps(String.class, String.class).getFirst();
|
||||||
OrderInfo newOrder = new OrderInfo(
|
OrderInfo newOrder = OrderInfo.builder()
|
||||||
UUID.fromString(orderData.get("customerId")),
|
.customerId(UUID.fromString(orderData.get("customerId")))
|
||||||
orderData.get("paymentMethod")
|
.paymentMethod(orderData.get("paymentMethod"))
|
||||||
);
|
.build();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
orderRegistration = orderUseCase.registerOrder(newOrder);
|
orderUseCase.registerOrderInfo(newOrder);
|
||||||
exception = null;
|
exception = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
orderRegistration = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@And("the order includes the following books:")
|
@And("the order includes the following books:")
|
||||||
public void theOrderIncludesTheFollowingBooks(DataTable dataTable){
|
public void theOrderIncludesTheFollowingBooks(DataTable dataTable) {
|
||||||
|
if (exception != null) return;
|
||||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||||
List<OrderLineDTO> orderLines = new ArrayList<>();
|
List<OrderLineDTO> orderLines = new ArrayList<>();
|
||||||
|
|
||||||
for (Map<String, String> book : books) {
|
for (Map<String, String> book : books) {
|
||||||
String isbn = book.get("ISBN");
|
String bookId = book.get("bookId");
|
||||||
int quantity = Integer.parseInt(book.get("quantity"));
|
int quantity = Integer.parseInt(book.get("quantity"));
|
||||||
|
|
||||||
orderLines.add(OrderLineDTO.builder()
|
orderLines.add(OrderLineDTO.builder()
|
||||||
.bookId(isbn)
|
.bookId(bookId)
|
||||||
.quantity(quantity)
|
.quantity(quantity)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
orderUseCase.addBooksToOrder(orderRegistration, orderLines);
|
orderUseCase.addBooksToOrder(orderLines);
|
||||||
exception = null;
|
exception = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
orderRegistration = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@And("the delivery address is:")
|
@And("the delivery address is:")
|
||||||
public void theDeliveryAddressIs(DataTable dataTable) {
|
public void theDeliveryAddressIs(DataTable dataTable) {
|
||||||
|
if (exception != null) return;
|
||||||
Map<String, String> addressData = dataTable.asMaps(String.class, String.class).getFirst();
|
Map<String, String> addressData = dataTable.asMaps(String.class, String.class).getFirst();
|
||||||
AddressDTO address = AddressDTO.builder()
|
AddressDTO address = AddressDTO.builder()
|
||||||
.street(addressData.get("street"))
|
.street(addressData.get("street"))
|
||||||
@@ -152,35 +149,61 @@ public class OrderSteps {
|
|||||||
.postalCode(addressData.get("postalCode"))
|
.postalCode(addressData.get("postalCode"))
|
||||||
.country(addressData.get("country"))
|
.country(addressData.get("country"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
orderUseCase.setDeliveryAddress(orderRegistration, address);
|
orderUseCase.setDeliveryAddress(address);
|
||||||
exception = null;
|
exception = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
orderRegistration = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Then("a new order is created")
|
@Then("a new order is created")
|
||||||
public void aNewOrderIsCreated() {
|
public void aNewOrderIsCreated() {
|
||||||
|
if (exception != null) {
|
||||||
|
fail("An exception should not have been thrown during order creation: " + exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
orderId = orderUseCase.finalizeOrder();
|
||||||
|
exception = null;
|
||||||
|
|
||||||
|
Order order = orderRepository.findById(orderId)
|
||||||
|
.orElseThrow(() -> new Exception("Order not found"));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
assertNull(exception, "No exception should be thrown during order creation");
|
assertNull(exception, "No exception should be thrown during order creation");
|
||||||
assertNotNull(orderRegistration);
|
assertNotNull(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Then("the order creation fails")
|
||||||
|
public void theCreationFails() {
|
||||||
|
assertNotNull(exception, "An exception should have been thrown during order creation");
|
||||||
}
|
}
|
||||||
|
|
||||||
@And("the total price is {double}")
|
@And("the total price is {double}")
|
||||||
public void theTotalPriceIs(double expectedPrice) {
|
public void theTotalPriceIs(double expectedPrice) throws Exception {
|
||||||
Order order = orderRepository.findById(orderRegistration)
|
Order order = orderRepository.findById(orderId)
|
||||||
.orElseThrow(() -> new Exception("Order not found"));
|
.orElseThrow(() -> new Exception("Order not found"));
|
||||||
double totalPrice = order.getTotalPrice();
|
double totalPrice = order.getTotalPrice();
|
||||||
assertEquals(expectedPrice, totalPrice, "The total price of the order should match the expected price");
|
assertEquals(expectedPrice, totalPrice, "The total price of the order should match the expected price");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@And("The customer {string} now has {int} loyalty points")
|
||||||
|
public void theCustomerNowHasLoyaltyPoints(String clientId, int actualPoints) throws Exception {
|
||||||
|
Customer customer = customerRepository.findById(UUID.fromString(clientId))
|
||||||
|
.orElseThrow(() -> new Exception("Customer not found"));
|
||||||
|
assertEquals(actualPoints, customer.getLoyaltyPoints(), "The customer's loyalty points should match the expected points");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@And("{int} loyalty points are deducted")
|
@And("{int} loyalty points are deducted")
|
||||||
public void loyaltyPointsAreDeducted(int loyaltyPoints) {
|
public void loyaltyPointsAreDeducted(int loyaltyPoints) throws Exception {
|
||||||
Order order = orderRepository.findById(orderRegistration).orElseThrow();
|
Order order = orderRepository.findById(orderId)
|
||||||
|
.orElseThrow(() -> new Exception("Order not found"));
|
||||||
Customer customer = customerRepository.findById(order.getCustomerId())
|
Customer customer = customerRepository.findById(order.getCustomerId())
|
||||||
.orElseThrow(() -> new Exception("Customer not found"));
|
.orElseThrow(() -> new Exception("Customer not found"));
|
||||||
int remainingPoints = customer.getLoyaltyPoints() - loyaltyPoints;
|
int remainingPoints = customer.getLoyaltyPoints() - loyaltyPoints;
|
||||||
assertEquals(remainingPoints, customer.getLoyaltyPoints(), "The customer's loyalty points should be deducted correctly");
|
assertEquals(remainingPoints, customer.getLoyaltyPoints(), "The customer's loyalty points should be deducted correctly");
|
||||||
}
|
}
|
||||||
@@ -196,7 +219,7 @@ public class OrderSteps {
|
|||||||
public void iReceiveAnErrorForNotFoundExceptionMessageContaining(String errorMessage) {
|
public void iReceiveAnErrorForNotFoundExceptionMessageContaining(String errorMessage) {
|
||||||
assertNotNull(exception, "An exception should be thrown during order retrieval");
|
assertNotNull(exception, "An exception should be thrown during order retrieval");
|
||||||
assertInstanceOf(OrderNotFoundException.class, exception, "The exception should be of type OrderNotFoundException");
|
assertInstanceOf(OrderNotFoundException.class, exception, "The exception should be of type OrderNotFoundException");
|
||||||
assertEquals(errorMessage, exception.getMessage(), "The error message should match the expected message");
|
assertTrue(exception.getMessage().contains(errorMessage), "The error message should contain the expected message");
|
||||||
}
|
}
|
||||||
|
|
||||||
@And("I receive an error for not found user exception message containing {string}")
|
@And("I receive an error for not found user exception message containing {string}")
|
||||||
@@ -208,14 +231,13 @@ public class OrderSteps {
|
|||||||
|
|
||||||
@And("the order includes no books")
|
@And("the order includes no books")
|
||||||
public void theOrderIncludesNoBooks() {
|
public void theOrderIncludesNoBooks() {
|
||||||
|
if (exception != null) return;
|
||||||
List<OrderLineDTO> orderLines = new ArrayList<>();
|
List<OrderLineDTO> orderLines = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
orderUseCase.addBooksToOrder(orderRegistration, orderLines);
|
orderUseCase.addBooksToOrder(orderLines);
|
||||||
exception = null;
|
exception = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
orderRegistration = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,19 +267,21 @@ public class OrderSteps {
|
|||||||
.postalCode("12345")
|
.postalCode("12345")
|
||||||
.country("USA")
|
.country("USA")
|
||||||
.build())
|
.build())
|
||||||
.paymentMethod("CREDIT_CARD")
|
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
orderRepository.save(order);
|
orderRepository.save(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
@When("I retrieve the order by ID {string}")
|
@When("I retrieve the order by ID {string}")
|
||||||
public void iRetrieveTheOrderByID(String orderId) {
|
public void iRetrieveTheOrderByID(String orderId) {
|
||||||
UUID orderUUID = UUID.fromString(orderId);
|
|
||||||
try {
|
try {
|
||||||
|
UUID orderUUID = UUID.fromString(orderId);
|
||||||
orderByUUID = orderUseCase.findOrderById(orderUUID);
|
orderByUUID = orderUseCase.findOrderById(orderUUID);
|
||||||
exception = null;
|
exception = null;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
exception = new OrderNotFoundException("Order not found");
|
||||||
|
orderByUUID = Optional.empty();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
orderByUUID = Optional.empty();
|
orderByUUID = Optional.empty();
|
||||||
@@ -269,14 +293,15 @@ public class OrderSteps {
|
|||||||
assertTrue(orderByUUID.isPresent(), "The order should be found by ID");
|
assertTrue(orderByUUID.isPresent(), "The order should be found by ID");
|
||||||
OrderDTO order = orderByUUID.get();
|
OrderDTO order = orderByUUID.get();
|
||||||
assertNotNull(order, "The retrieved order should not be null");
|
assertNotNull(order, "The retrieved order should not be null");
|
||||||
assertEquals(orderRegistration, order.getId(), "The retrieved order ID should match the expected ID");
|
if (orderId != null) {
|
||||||
|
assertEquals(orderId, order.getId(), "The retrieved order ID should match the expected ID");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@When("I request all orders for customer {string}")
|
@When("I request all orders for customer {string}")
|
||||||
public void iRequestAllOrdersForCustomer(String customerId) {
|
public void iRequestAllOrdersForCustomer(String customerId) {
|
||||||
UUID customerUUID = UUID.fromString(customerId);
|
UUID customerUUID = UUID.fromString(customerId);
|
||||||
|
|
||||||
List<OrderDTO> orders;
|
|
||||||
try {
|
try {
|
||||||
orders = orderUseCase.findOrdersByCustomerId(customerUUID);
|
orders = orderUseCase.findOrdersByCustomerId(customerUUID);
|
||||||
exception = null;
|
exception = null;
|
||||||
|
@@ -0,0 +1,133 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.converter;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.*;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@DisplayName("OrderConverter Unit Tests")
|
||||||
|
class OrderConverterTest {
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("toDomain() method tests")
|
||||||
|
class ToDomainTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should convert OrderInfo to Order domain object with all fields mapped correctly")
|
||||||
|
void shouldConvertOrderInfoToDomain() {
|
||||||
|
UUID customerId = UUID.randomUUID();
|
||||||
|
List<OrderLineDTO> orderLines = List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(2).build());
|
||||||
|
AddressDTO address = AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build();
|
||||||
|
OrderInfo orderInfo = OrderInfo.builder()
|
||||||
|
.customerId(customerId)
|
||||||
|
.orderLines(orderLines)
|
||||||
|
.address(address)
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Order result = OrderConverter.toDomain(orderInfo);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(customerId, result.getCustomerId());
|
||||||
|
assertEquals(orderLines, result.getOrderLines());
|
||||||
|
assertEquals(address, result.getAddress());
|
||||||
|
assertEquals(PaymentMethod.CREDIT_CARD, result.getPaymentMethod());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("toDTO() method tests")
|
||||||
|
class ToDTOTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should convert Order domain object to OrderDTO with all fields mapped correctly")
|
||||||
|
void shouldConvertOrderToDTO() {
|
||||||
|
UUID id = UUID.randomUUID();
|
||||||
|
UUID customerId = UUID.randomUUID();
|
||||||
|
List<OrderLineDTO> orderLines = List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(2).build());
|
||||||
|
AddressDTO address = AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build();
|
||||||
|
Order order = Order.builder()
|
||||||
|
.id(id)
|
||||||
|
.customerId(customerId)
|
||||||
|
.orderLines(orderLines)
|
||||||
|
.totalPrice(79.98)
|
||||||
|
.totalPriceToPay(79.98)
|
||||||
|
.address(address)
|
||||||
|
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OrderDTO result = OrderConverter.toDTO(order);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(id, result.getId());
|
||||||
|
assertEquals(customerId, result.getCustomerId());
|
||||||
|
assertEquals(orderLines, result.getOrderLines());
|
||||||
|
assertEquals(79.98, result.getTotalPrice());
|
||||||
|
assertEquals(79.98, result.getTotalPriceToPay());
|
||||||
|
assertEquals(address, result.getAddress());
|
||||||
|
assertEquals(PaymentMethod.CREDIT_CARD, result.getPaymentMethod());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should handle null values properly when converting between objects")
|
||||||
|
void shouldHandleNullValuesGracefully() {
|
||||||
|
Order order = Order.builder()
|
||||||
|
.id(UUID.randomUUID())
|
||||||
|
.customerId(null)
|
||||||
|
.orderLines(null)
|
||||||
|
.totalPrice(0.0)
|
||||||
|
.totalPriceToPay(0.0)
|
||||||
|
.address(null)
|
||||||
|
.paymentMethod(null)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OrderDTO result = OrderConverter.toDTO(order);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNull(result.getCustomerId());
|
||||||
|
assertNull(result.getOrderLines());
|
||||||
|
assertNull(result.getAddress());
|
||||||
|
assertNull(result.getPaymentMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should preserve empty order lines and address fields during conversion")
|
||||||
|
void shouldPreserveEmptyFields() {
|
||||||
|
OrderInfo orderInfo = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of())
|
||||||
|
.address(AddressDTO.builder().street("").city("").postalCode("").country("").build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Order domainResult = OrderConverter.toDomain(orderInfo);
|
||||||
|
OrderDTO dtoResult = OrderConverter.toDTO(domainResult);
|
||||||
|
|
||||||
|
assertNotNull(dtoResult.getOrderLines());
|
||||||
|
assertEquals(0, dtoResult.getOrderLines().size());
|
||||||
|
assertEquals("", dtoResult.getAddress().getStreet());
|
||||||
|
assertEquals("", dtoResult.getAddress().getCity());
|
||||||
|
assertEquals("", dtoResult.getAddress().getPostalCode());
|
||||||
|
assertEquals("", dtoResult.getAddress().getCountry());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw NotValidOrderException when converting invalid OrderInfo")
|
||||||
|
void shouldThrowExceptionForInvalidOrderInfo() {
|
||||||
|
OrderInfo invalidOrderInfo = OrderInfo.builder()
|
||||||
|
.customerId(null)
|
||||||
|
.orderLines(null)
|
||||||
|
.address(null)
|
||||||
|
.paymentMethod(null)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThrows(NotValidOrderException.class, () -> OrderConverter.toDomain(invalidOrderInfo));
|
||||||
|
}
|
||||||
|
}
|
@@ -60,12 +60,11 @@ class OrderTest {
|
|||||||
OrderLineDTO.builder().bookId("1234567890123").quantity(2).build(),
|
OrderLineDTO.builder().bookId("1234567890123").quantity(2).build(),
|
||||||
OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()
|
OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()
|
||||||
);
|
);
|
||||||
// Supposons prix 39.99 et 49.99
|
|
||||||
double price1 = 39.99;
|
double price1 = 39.99;
|
||||||
double price2 = 49.99;
|
double price2 = 49.99;
|
||||||
double expectedTotal = 2 * price1 + 1 * price2;
|
double expectedTotal = 2 * price1 + 1 * price2;
|
||||||
|
|
||||||
// Ici, on simule la logique métier (à adapter selon l'implémentation réelle)
|
|
||||||
double total = 2 * price1 + 1 * price2;
|
double total = 2 * price1 + 1 * price2;
|
||||||
assertEquals(expectedTotal, total);
|
assertEquals(expectedTotal, total);
|
||||||
}
|
}
|
||||||
@@ -106,7 +105,7 @@ class OrderTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Create order with credit card - success")
|
@DisplayName("Create order with credit card - success")
|
||||||
void testCreateOrderWithCreditCard() {
|
void testCreateOrderWithCreditCard() {
|
||||||
// Arrange
|
|
||||||
UUID customerId = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
UUID customerId = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||||
List<OrderLineDTO> orderLines = List.of(
|
List<OrderLineDTO> orderLines = List.of(
|
||||||
OrderLineDTO.builder().bookId("1234567890123").quantity(2).build()
|
OrderLineDTO.builder().bookId("1234567890123").quantity(2).build()
|
||||||
@@ -114,7 +113,7 @@ class OrderTest {
|
|||||||
AddressDTO address = AddressDTO.builder()
|
AddressDTO address = AddressDTO.builder()
|
||||||
.street("12 Main St.").city("Paris").postalCode("75000").country("France").build();
|
.street("12 Main St.").city("Paris").postalCode("75000").country("France").build();
|
||||||
double expectedTotal = 79.98;
|
double expectedTotal = 79.98;
|
||||||
// Act
|
|
||||||
OrderDTO order = OrderDTO.builder()
|
OrderDTO order = OrderDTO.builder()
|
||||||
.id(UUID.randomUUID())
|
.id(UUID.randomUUID())
|
||||||
.customerId(customerId)
|
.customerId(customerId)
|
||||||
@@ -124,7 +123,7 @@ class OrderTest {
|
|||||||
.address(address)
|
.address(address)
|
||||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||||
.build();
|
.build();
|
||||||
// Assert
|
|
||||||
assertEquals(expectedTotal, order.getTotalPrice());
|
assertEquals(expectedTotal, order.getTotalPrice());
|
||||||
assertEquals(PaymentMethod.CREDIT_CARD, order.getPaymentMethod());
|
assertEquals(PaymentMethod.CREDIT_CARD, order.getPaymentMethod());
|
||||||
assertEquals(customerId, order.getCustomerId());
|
assertEquals(customerId, order.getCustomerId());
|
||||||
|
@@ -14,7 +14,7 @@ class OrderNotFoundExceptionTest {
|
|||||||
@DisplayName("Exception message should contain the UUID provided")
|
@DisplayName("Exception message should contain the UUID provided")
|
||||||
void testExceptionMessageContainsUUID() {
|
void testExceptionMessageContainsUUID() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
OrderNotFoundException exception = new OrderNotFoundException(uuid);
|
OrderNotFoundException exception = new OrderNotFoundException(uuid.toString());
|
||||||
String expectedMessage = String.format("The order with id %s does not exist", uuid);
|
String expectedMessage = String.format("The order with id %s does not exist", uuid);
|
||||||
assertEquals(expectedMessage, exception.getMessage());
|
assertEquals(expectedMessage, exception.getMessage());
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ class OrderNotFoundExceptionTest {
|
|||||||
@DisplayName("Exception should use the correct constant message format")
|
@DisplayName("Exception should use the correct constant message format")
|
||||||
void testExceptionUsesConstantMessageFormat() {
|
void testExceptionUsesConstantMessageFormat() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
OrderNotFoundException exception = new OrderNotFoundException(uuid);
|
OrderNotFoundException exception = new OrderNotFoundException(uuid.toString());
|
||||||
String expectedFormatWithPlaceholder = "The order with id {0} does not exist";
|
String expectedFormatWithPlaceholder = "The order with id {0} does not exist";
|
||||||
assertEquals(OrderNotFoundException.THE_ORDER_WITH_ID_DOES_NOT_EXIST_MESSAGE, expectedFormatWithPlaceholder);
|
assertEquals(OrderNotFoundException.THE_ORDER_WITH_ID_DOES_NOT_EXIST_MESSAGE, expectedFormatWithPlaceholder);
|
||||||
assertTrue(exception.getMessage().contains(uuid.toString()));
|
assertTrue(exception.getMessage().contains(uuid.toString()));
|
||||||
@@ -34,7 +34,7 @@ class OrderNotFoundExceptionTest {
|
|||||||
void testExceptionCanBeThrownAndCaught() {
|
void testExceptionCanBeThrownAndCaught() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
try {
|
try {
|
||||||
throw new OrderNotFoundException(uuid);
|
throw new OrderNotFoundException(uuid.toString());
|
||||||
} catch (OrderNotFoundException e) {
|
} catch (OrderNotFoundException e) {
|
||||||
String expectedMessage = String.format("The order with id %s does not exist", uuid);
|
String expectedMessage = String.format("The order with id %s does not exist", uuid);
|
||||||
assertEquals(expectedMessage, e.getMessage());
|
assertEquals(expectedMessage, e.getMessage());
|
||||||
|
@@ -14,7 +14,7 @@ class UserNotFoundExceptionTest {
|
|||||||
@DisplayName("Exception message should contain the UUID provided")
|
@DisplayName("Exception message should contain the UUID provided")
|
||||||
void testExceptionMessageContainsUUID() {
|
void testExceptionMessageContainsUUID() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
UserNotFoundException exception = new UserNotFoundException(uuid);
|
UserNotFoundException exception = new UserNotFoundException(uuid.toString());
|
||||||
String expectedMessage = String.format("The customer with id %s does not exist", uuid);
|
String expectedMessage = String.format("The customer with id %s does not exist", uuid);
|
||||||
assertEquals(expectedMessage, exception.getMessage());
|
assertEquals(expectedMessage, exception.getMessage());
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ class UserNotFoundExceptionTest {
|
|||||||
@DisplayName("Exception should use the correct constant message format")
|
@DisplayName("Exception should use the correct constant message format")
|
||||||
void testExceptionUsesConstantMessageFormat() {
|
void testExceptionUsesConstantMessageFormat() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
UserNotFoundException exception = new UserNotFoundException(uuid);
|
UserNotFoundException exception = new UserNotFoundException(uuid.toString());
|
||||||
String expectedFormatWithPlaceholder = "The customer with id {0} does not exist";
|
String expectedFormatWithPlaceholder = "The customer with id {0} does not exist";
|
||||||
assertEquals(UserNotFoundException.THE_CUSTOMER_WITH_ID_DOES_NOT_EXIST_MESSAGE, expectedFormatWithPlaceholder);
|
assertEquals(UserNotFoundException.THE_CUSTOMER_WITH_ID_DOES_NOT_EXIST_MESSAGE, expectedFormatWithPlaceholder);
|
||||||
assertTrue(exception.getMessage().contains(uuid.toString()));
|
assertTrue(exception.getMessage().contains(uuid.toString()));
|
||||||
@@ -34,7 +34,7 @@ class UserNotFoundExceptionTest {
|
|||||||
void testExceptionCanBeThrownAndCaught() {
|
void testExceptionCanBeThrownAndCaught() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
try {
|
try {
|
||||||
throw new UserNotFoundException(uuid);
|
throw new UserNotFoundException(uuid.toString());
|
||||||
} catch (UserNotFoundException e) {
|
} catch (UserNotFoundException e) {
|
||||||
String expectedMessage = String.format("The customer with id %s does not exist", uuid);
|
String expectedMessage = String.format("The customer with id %s does not exist", uuid);
|
||||||
assertEquals(expectedMessage, e.getMessage());
|
assertEquals(expectedMessage, e.getMessage());
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.repository;
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.repository;
|
||||||
|
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.*;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.*;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.OrderNotFoundException;
|
|
||||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.UserNotFoundException;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -14,8 +12,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
class OrderRepositoryTest {
|
class OrderRepositoryTest {
|
||||||
|
|
||||||
private OrderRepository repository;
|
private OrderRepository repository;
|
||||||
private OrderDTO order1;
|
private Order order1;
|
||||||
private OrderDTO order2;
|
private Order order2;
|
||||||
private UUID customerId1;
|
private UUID customerId1;
|
||||||
private UUID customerId2;
|
private UUID customerId2;
|
||||||
|
|
||||||
@@ -24,7 +22,7 @@ class OrderRepositoryTest {
|
|||||||
repository = new OrderRepository();
|
repository = new OrderRepository();
|
||||||
customerId1 = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
customerId1 = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||||
customerId2 = UUID.fromString("22222222-2222-2222-2222-222222222222");
|
customerId2 = UUID.fromString("22222222-2222-2222-2222-222222222222");
|
||||||
order1 = OrderDTO.builder()
|
order1 = Order.builder()
|
||||||
.id(UUID.randomUUID())
|
.id(UUID.randomUUID())
|
||||||
.customerId(customerId1)
|
.customerId(customerId1)
|
||||||
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(2).build()))
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(2).build()))
|
||||||
@@ -33,7 +31,7 @@ class OrderRepositoryTest {
|
|||||||
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||||
.build();
|
.build();
|
||||||
order2 = OrderDTO.builder()
|
order2 = Order.builder()
|
||||||
.id(UUID.randomUUID())
|
.id(UUID.randomUUID())
|
||||||
.customerId(customerId2)
|
.customerId(customerId2)
|
||||||
.orderLines(List.of(OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()))
|
.orderLines(List.of(OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()))
|
||||||
@@ -47,7 +45,7 @@ class OrderRepositoryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("New repository should be empty")
|
@DisplayName("New repository should be empty")
|
||||||
void testNewRepositoryIsEmpty() {
|
void testNewRepositoryIsEmpty() {
|
||||||
List<OrderDTO> orders = repository.findAll();
|
List<Order> orders = repository.findAll();
|
||||||
assertTrue(orders.isEmpty());
|
assertTrue(orders.isEmpty());
|
||||||
assertEquals(0, orders.size());
|
assertEquals(0, orders.size());
|
||||||
}
|
}
|
||||||
@@ -58,8 +56,9 @@ class OrderRepositoryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Save should add a new order")
|
@DisplayName("Save should add a new order")
|
||||||
void testSaveNewOrder() {
|
void testSaveNewOrder() {
|
||||||
OrderDTO savedOrder = repository.save(order1);
|
Order savedOrder = repository.save(order1);
|
||||||
assertEquals(1, repository.findAll().size());
|
Optional<Order> foundOrder = repository.findById(order1.getId());
|
||||||
|
assertTrue(foundOrder.isPresent());
|
||||||
assertEquals(order1.getId(), savedOrder.getId());
|
assertEquals(order1.getId(), savedOrder.getId());
|
||||||
assertEquals(order1.getCustomerId(), savedOrder.getCustomerId());
|
assertEquals(order1.getCustomerId(), savedOrder.getCustomerId());
|
||||||
}
|
}
|
||||||
@@ -69,7 +68,7 @@ class OrderRepositoryTest {
|
|||||||
void testSaveMultipleOrders() {
|
void testSaveMultipleOrders() {
|
||||||
repository.save(order1);
|
repository.save(order1);
|
||||||
repository.save(order2);
|
repository.save(order2);
|
||||||
List<OrderDTO> orders = repository.findAll();
|
List<Order> orders = repository.findAll();
|
||||||
assertEquals(2, orders.size());
|
assertEquals(2, orders.size());
|
||||||
assertTrue(orders.contains(order1));
|
assertTrue(orders.contains(order1));
|
||||||
assertTrue(orders.contains(order2));
|
assertTrue(orders.contains(order2));
|
||||||
@@ -88,108 +87,18 @@ class OrderRepositoryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("FindById should return order with matching ID")
|
@DisplayName("FindById should return order with matching ID")
|
||||||
void testFindById() {
|
void testFindById() {
|
||||||
Optional<OrderDTO> foundOrder = repository.findById(order1.getId());
|
Optional<Order> foundOrder = repository.findById(order1.getId());
|
||||||
assertTrue(foundOrder.isPresent());
|
assertTrue(foundOrder.isPresent());
|
||||||
assertEquals(order1.getCustomerId(), foundOrder.get().getCustomerId());
|
assertEquals(order1.getCustomerId(), foundOrder.get().getCustomerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("FindById should throw OrderNotFoundException when ID doesn't exist")
|
|
||||||
void testFindByIdNotFound() {
|
|
||||||
UUID nonExistentId = UUID.randomUUID();
|
|
||||||
assertThrows(OrderNotFoundException.class, () -> {
|
|
||||||
repository.findByIdOrThrow(nonExistentId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("FindByCustomerId should return all orders for a customer")
|
@DisplayName("FindByCustomerId should return all orders for a customer")
|
||||||
void testFindByCustomerId() {
|
void testFindByCustomerId() {
|
||||||
List<OrderDTO> orders = repository.findByCustomerId(customerId1);
|
List<Order> orders = repository.findByCustomerId(customerId1);
|
||||||
assertFalse(orders.isEmpty());
|
assertFalse(orders.isEmpty());
|
||||||
assertTrue(orders.stream().allMatch(o -> o.getCustomerId().equals(customerId1)));
|
assertTrue(orders.stream().allMatch(o -> o.getCustomerId().equals(customerId1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("FindByCustomerId should throw UserNotFoundException when customer doesn't exist")
|
|
||||||
void testFindByCustomerIdNotFound() {
|
|
||||||
UUID nonExistentCustomer = UUID.randomUUID();
|
|
||||||
assertThrows(UserNotFoundException.class, () -> {
|
|
||||||
repository.findByCustomerIdOrThrow(nonExistentCustomer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("Validation and error handling")
|
|
||||||
class ValidationAndErrorHandling {
|
|
||||||
@Test
|
|
||||||
@DisplayName("Save should throw NotValidOrderException for invalid address")
|
|
||||||
void testSaveInvalidAddress() {
|
|
||||||
OrderDTO invalidOrder = OrderDTO.builder()
|
|
||||||
.id(UUID.randomUUID())
|
|
||||||
.customerId(customerId1)
|
|
||||||
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
|
||||||
.totalPrice(39.99)
|
|
||||||
.totalPriceToPay(39.99)
|
|
||||||
.address(AddressDTO.builder().street("").city("").postalCode("").country("").build())
|
|
||||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
|
||||||
.build();
|
|
||||||
assertThrows(NotValidOrderException.class, () -> {
|
|
||||||
repository.saveOrThrow(invalidOrder);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Save should throw NotValidOrderException for empty book list")
|
|
||||||
void testSaveEmptyBookList() {
|
|
||||||
OrderDTO invalidOrder = OrderDTO.builder()
|
|
||||||
.id(UUID.randomUUID())
|
|
||||||
.customerId(customerId1)
|
|
||||||
.orderLines(List.of())
|
|
||||||
.totalPrice(0.0)
|
|
||||||
.totalPriceToPay(0.0)
|
|
||||||
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
|
||||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
|
||||||
.build();
|
|
||||||
assertThrows(NotValidOrderException.class, () -> {
|
|
||||||
repository.saveOrThrow(invalidOrder);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Save should throw NotValidOrderException for negative quantity")
|
|
||||||
void testSaveNegativeQuantity() {
|
|
||||||
OrderDTO invalidOrder = OrderDTO.builder()
|
|
||||||
.id(UUID.randomUUID())
|
|
||||||
.customerId(customerId1)
|
|
||||||
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(-1).build()))
|
|
||||||
.totalPrice(-39.99)
|
|
||||||
.totalPriceToPay(-39.99)
|
|
||||||
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
|
||||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
|
||||||
.build();
|
|
||||||
assertThrows(NotValidOrderException.class, () -> {
|
|
||||||
repository.saveOrThrow(invalidOrder);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Save should throw NotValidOrderException for null payment method")
|
|
||||||
void testSaveNullPaymentMethod() {
|
|
||||||
OrderDTO invalidOrder = OrderDTO.builder()
|
|
||||||
.id(UUID.randomUUID())
|
|
||||||
.customerId(customerId1)
|
|
||||||
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
|
||||||
.totalPrice(39.99)
|
|
||||||
.totalPriceToPay(39.99)
|
|
||||||
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
|
||||||
.paymentMethod(null) // Invalid payment method
|
|
||||||
.build();
|
|
||||||
assertThrows(NotValidOrderException.class, () -> {
|
|
||||||
repository.saveOrThrow(invalidOrder);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,144 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.usecase;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.*;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.entity.Order;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.OrderNotFoundException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.UserNotFoundException;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.repository.OrderRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class OrderUseCaseTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private OrderRepository orderRepository;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private OrderUseCase orderUseCase;
|
||||||
|
|
||||||
|
private UUID orderId;
|
||||||
|
private UUID customerId;
|
||||||
|
private OrderInfo validOrderInfo;
|
||||||
|
private OrderDTO validOrderDTO;
|
||||||
|
private Order order;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
orderId = UUID.randomUUID();
|
||||||
|
customerId = UUID.randomUUID();
|
||||||
|
validOrderInfo = OrderInfo.builder()
|
||||||
|
.customerId(customerId)
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(2).build()))
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
order = Order.builder()
|
||||||
|
.id(orderId)
|
||||||
|
.customerId(customerId)
|
||||||
|
.orderLines(validOrderInfo.getOrderLines())
|
||||||
|
.totalPrice(79.98)
|
||||||
|
.totalPriceToPay(79.98)
|
||||||
|
.address(validOrderInfo.getAddress())
|
||||||
|
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||||
|
.build();
|
||||||
|
validOrderDTO = OrderDTO.builder()
|
||||||
|
.id(orderId)
|
||||||
|
.customerId(customerId)
|
||||||
|
.orderLines(validOrderInfo.getOrderLines())
|
||||||
|
.totalPrice(79.98)
|
||||||
|
.totalPriceToPay(79.98)
|
||||||
|
.address(validOrderInfo.getAddress())
|
||||||
|
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Register order tests")
|
||||||
|
class RegisterOrderTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should register order when valid data is provided")
|
||||||
|
void testRegisterOrderWithValidData() throws NotValidOrderException {
|
||||||
|
when(orderRepository.save(any(Order.class))).thenReturn(order);
|
||||||
|
UUID registeredId = orderUseCase.registerOrder(validOrderInfo);
|
||||||
|
assertNotNull(registeredId);
|
||||||
|
verify(orderRepository, times(1)).save(any(Order.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when order data is not valid")
|
||||||
|
void testRegisterOrderWithInvalidData() {
|
||||||
|
OrderInfo invalidOrderInfo = OrderInfo.builder()
|
||||||
|
.customerId(null)
|
||||||
|
.orderLines(null)
|
||||||
|
.address(null)
|
||||||
|
.paymentMethod(null)
|
||||||
|
.build();
|
||||||
|
assertThrows(NotValidOrderException.class,
|
||||||
|
() -> orderUseCase.registerOrder(invalidOrderInfo));
|
||||||
|
verify(orderRepository, never()).save(any(Order.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Find order tests")
|
||||||
|
class FindOrderTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should return order when ID exists")
|
||||||
|
void testFindOrderById() {
|
||||||
|
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
||||||
|
Optional<OrderDTO> foundOrder = orderUseCase.findOrderById(orderId);
|
||||||
|
assertTrue(foundOrder.isPresent());
|
||||||
|
assertEquals(orderId, foundOrder.get().getId());
|
||||||
|
verify(orderRepository, times(1)).findById(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when order ID doesn't exist")
|
||||||
|
void testFindOrderByIdNotFound() {
|
||||||
|
UUID nonExistentId = UUID.randomUUID();
|
||||||
|
when(orderRepository.findById(nonExistentId)).thenReturn(Optional.empty());
|
||||||
|
assertThrows(OrderNotFoundException.class,
|
||||||
|
() -> orderUseCase.findOrderById(nonExistentId));
|
||||||
|
verify(orderRepository, times(1)).findById(nonExistentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Find orders by customer tests")
|
||||||
|
class FindOrdersByCustomerTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should return all orders for a customer")
|
||||||
|
void testFindOrdersByCustomerId() {
|
||||||
|
List<OrderDTO> orders = List.of(validOrderDTO);
|
||||||
|
when(orderRepository.findByCustomerId(customerId)).thenReturn(List.of(order));
|
||||||
|
List<OrderDTO> foundOrders = orderUseCase.findOrdersByCustomerId(customerId);
|
||||||
|
assertNotNull(foundOrders);
|
||||||
|
assertFalse(foundOrders.isEmpty());
|
||||||
|
assertEquals(orders, foundOrders);
|
||||||
|
verify(orderRepository, times(1)).findByCustomerId(customerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when customer ID doesn't exist")
|
||||||
|
void testFindOrdersByUnknownCustomer() {
|
||||||
|
UUID nonExistentCustomer = UUID.randomUUID();
|
||||||
|
when(orderRepository.findByCustomerId(nonExistentCustomer)).thenThrow(new UserNotFoundException(nonExistentCustomer.toString()));
|
||||||
|
assertThrows(UserNotFoundException.class,
|
||||||
|
() -> orderUseCase.findOrdersByCustomerId(nonExistentCustomer));
|
||||||
|
verify(orderRepository, times(1)).findByCustomerId(nonExistentCustomer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,159 @@
|
|||||||
|
package fr.iut_fbleau.but3.dev62.mylibrary.order.validator;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.*;
|
||||||
|
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class OrderValidatorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should validate order with valid data")
|
||||||
|
void testValidateValidOrder() {
|
||||||
|
OrderInfo validOrder = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
assertDoesNotThrow(() -> OrderValidator.validate(validOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Customer ID validation tests")
|
||||||
|
class CustomerIdValidationTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when customerId is null")
|
||||||
|
void testValidateNullCustomerId() {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(null)
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.CUSTOMER_ID_CANNOT_BE_NULL, exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Order lines validation tests")
|
||||||
|
class OrderLinesValidationTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when order lines are empty")
|
||||||
|
void testValidateEmptyOrderLines() {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of())
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.BOOK_LIST_CANNOT_BE_EMPTY, exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when order line has negative quantity")
|
||||||
|
void testValidateNegativeQuantity() {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(-1).build()))
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.QUANTITY_MUST_BE_POSITIVE, exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Address validation tests")
|
||||||
|
class AddressValidationTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when address is null")
|
||||||
|
void testValidateNullAddress() {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
||||||
|
.address(null)
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.ADDRESS_FIELDS_ARE_REQUIRED, exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {"", " ", "\t", "\n"})
|
||||||
|
@DisplayName("Should throw exception when address fields are blank")
|
||||||
|
void testValidateBlankAddressFields(String blank) {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
||||||
|
.address(AddressDTO.builder().street(blank).city(blank).postalCode(blank).country(blank).build())
|
||||||
|
.paymentMethod("CREDIT_CARD")
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.ADDRESS_FIELDS_ARE_REQUIRED, exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Payment method validation tests")
|
||||||
|
class PaymentMethodValidationTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("Should throw exception when payment method is null")
|
||||||
|
void testValidateNullPaymentMethod() {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod(null)
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.PAYMENT_METHOD_IS_NOT_VALID, exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {"", " ", "UNKNOWN", "BITCOIN"})
|
||||||
|
@DisplayName("Should throw exception when payment method is invalid")
|
||||||
|
void testValidateInvalidPaymentMethod(String invalidMethod) {
|
||||||
|
OrderInfo order = OrderInfo.builder()
|
||||||
|
.customerId(UUID.randomUUID())
|
||||||
|
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(1).build()))
|
||||||
|
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||||
|
.paymentMethod(invalidMethod)
|
||||||
|
.build();
|
||||||
|
NotValidOrderException exception = assertThrows(
|
||||||
|
NotValidOrderException.class,
|
||||||
|
() -> OrderValidator.validate(order)
|
||||||
|
);
|
||||||
|
assertEquals(OrderValidator.PAYMENT_METHOD_IS_NOT_VALID, exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,7 +6,7 @@ Feature: Manage customer orders
|
|||||||
| isbn | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
| isbn | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||||
| 1234567890123 | The Pragmatic Programmer | Andy Hunt | Addison-Wesley | 2025-06-10 | 39.99 | 10 | FICTION,THRILLER | A practical guide to becoming a better and more efficient software developer. | EN |
|
| 1234567890123 | The Pragmatic Programmer | Andy Hunt | Addison-Wesley | 2025-06-10 | 39.99 | 10 | FICTION,THRILLER | A practical guide to becoming a better and more efficient software developer. | EN |
|
||||||
| 9876543210123 | Clean Code | Robert Martin | Prentice Hall | 2024-01-15 | 49.99 | 5 | FICTION | A handbook of best practices for writing readable, maintainable, and clean code in Java. | EN |
|
| 9876543210123 | Clean Code | Robert Martin | Prentice Hall | 2024-01-15 | 49.99 | 5 | FICTION | A handbook of best practices for writing readable, maintainable, and clean code in Java. | EN |
|
||||||
And the system has the following customers:
|
And the system has the following customers in the database:
|
||||||
| id | firstName | lastName | phoneNumber | loyaltyPoints |
|
| id | firstName | lastName | phoneNumber | loyaltyPoints |
|
||||||
| 11111111-1111-1111-1111-111111111111 | Alice | Smith | 0612345678 | 100 |
|
| 11111111-1111-1111-1111-111111111111 | Alice | Smith | 0612345678 | 100 |
|
||||||
| 22222222-2222-2222-2222-222222222222 | Bob | Martin | 0698765432 | 10 |
|
| 22222222-2222-2222-2222-222222222222 | Bob | Martin | 0698765432 | 10 |
|
||||||
@@ -25,7 +25,7 @@ Feature: Manage customer orders
|
|||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then a new order is created
|
Then a new order is created
|
||||||
And the total price is 79.98
|
And the total price is 79.98
|
||||||
And customer "11111111-1111-1111-1111-111111111111" now has 100 loyalty points
|
And The customer "11111111-1111-1111-1111-111111111111" now has 100 loyalty points
|
||||||
|
|
||||||
Scenario: Create an order using loyalty points
|
Scenario: Create an order using loyalty points
|
||||||
When I create a new order with the following information:
|
When I create a new order with the following information:
|
||||||
@@ -39,8 +39,8 @@ Feature: Manage customer orders
|
|||||||
| 42 Book Street | Lyon | 69000 | France |
|
| 42 Book Street | Lyon | 69000 | France |
|
||||||
Then a new order is created
|
Then a new order is created
|
||||||
And the total price is 49.99
|
And the total price is 49.99
|
||||||
And 49 loyalty points are deducted
|
And 50 loyalty points are deducted
|
||||||
And customer "11111111-1111-1111-1111-111111111111" now has 51 loyalty points
|
And The customer "11111111-1111-1111-1111-111111111111" now has 50 loyalty points
|
||||||
|
|
||||||
Scenario: Create an order with multiple books
|
Scenario: Create an order with multiple books
|
||||||
When I create a new order with the following information:
|
When I create a new order with the following information:
|
||||||
@@ -55,7 +55,7 @@ Feature: Manage customer orders
|
|||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then a new order is created
|
Then a new order is created
|
||||||
And the total price is 239.92
|
And the total price is 239.92
|
||||||
And customer "11111111-1111-1111-1111-111111111111" now has 100 loyalty points
|
And The customer "11111111-1111-1111-1111-111111111111" now has 100 loyalty points
|
||||||
|
|
||||||
Scenario: Attempt to create an order with invalid address
|
Scenario: Attempt to create an order with invalid address
|
||||||
When I create a new order with the following information:
|
When I create a new order with the following information:
|
||||||
@@ -67,7 +67,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| | | | |
|
| | | | |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for validation order message containing "Address fields are required"
|
And I receive an error for validation order message containing "Address fields are required"
|
||||||
|
|
||||||
Scenario: Attempt to create an order with unknown customer
|
Scenario: Attempt to create an order with unknown customer
|
||||||
@@ -80,7 +80,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for not found user exception message containing "Customer not found"
|
And I receive an error for not found user exception message containing "Customer not found"
|
||||||
|
|
||||||
Scenario: Attempt to create an order with insufficient loyalty points
|
Scenario: Attempt to create an order with insufficient loyalty points
|
||||||
@@ -93,7 +93,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 42 Book Street | Lyon | 69000 | France |
|
| 42 Book Street | Lyon | 69000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for validation order message containing "Not enough loyalty points"
|
And I receive an error for validation order message containing "Not enough loyalty points"
|
||||||
|
|
||||||
Scenario: Attempt to order more books than available stock
|
Scenario: Attempt to order more books than available stock
|
||||||
@@ -106,7 +106,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for validation order message containing "Insufficient book stock"
|
And I receive an error for validation order message containing "Insufficient book stock"
|
||||||
|
|
||||||
Scenario: Attempt to create an order with invalid payment method
|
Scenario: Attempt to create an order with invalid payment method
|
||||||
@@ -119,7 +119,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for validation order message containing "Payment method is not valid"
|
And I receive an error for validation order message containing "Payment method is not valid"
|
||||||
|
|
||||||
Scenario: Attempt to create an order with unknown book
|
Scenario: Attempt to create an order with unknown book
|
||||||
@@ -132,7 +132,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for not found exception message containing "Book not found"
|
And I receive an error for not found exception message containing "Book not found"
|
||||||
|
|
||||||
Scenario: Attempt to create an order with empty book list
|
Scenario: Attempt to create an order with empty book list
|
||||||
@@ -143,7 +143,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for validation order message containing "Book list cannot be empty"
|
And I receive an error for validation order message containing "Book list cannot be empty"
|
||||||
|
|
||||||
Scenario: Attempt to create an order with a negative quantity
|
Scenario: Attempt to create an order with a negative quantity
|
||||||
@@ -156,7 +156,7 @@ Feature: Manage customer orders
|
|||||||
And the delivery address is:
|
And the delivery address is:
|
||||||
| street | city | postalCode | country |
|
| street | city | postalCode | country |
|
||||||
| 12 Main St. | Paris | 75000 | France |
|
| 12 Main St. | Paris | 75000 | France |
|
||||||
Then the creation fails
|
Then the order creation fails
|
||||||
And I receive an error for validation order message containing "Quantity must be positive"
|
And I receive an error for validation order message containing "Quantity must be positive"
|
||||||
|
|
||||||
#Get orders
|
#Get orders
|
Reference in New Issue
Block a user